1 /* 2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. 3 * All rights reserved 4 * www.brocade.com 5 * 6 * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License (GPL) Version 2 as 10 * published by the Free Software Foundation 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 */ 17 18 /** 19 * bfa_attr.c Linux driver configuration interface module. 20 */ 21 22 #include <linux/slab.h> 23 #include "bfad_drv.h" 24 #include "bfad_im.h" 25 #include "bfad_trcmod.h" 26 #include "bfad_attr.h" 27 28 /** 29 * FC_transport_template FC transport template 30 */ 31 32 /** 33 * FC transport template entry, get SCSI target port ID. 34 */ 35 void 36 bfad_im_get_starget_port_id(struct scsi_target *starget) 37 { 38 struct Scsi_Host *shost; 39 struct bfad_im_port_s *im_port; 40 struct bfad_s *bfad; 41 struct bfad_itnim_s *itnim = NULL; 42 u32 fc_id = -1; 43 unsigned long flags; 44 45 shost = bfad_os_starget_to_shost(starget); 46 im_port = (struct bfad_im_port_s *) shost->hostdata[0]; 47 bfad = im_port->bfad; 48 spin_lock_irqsave(&bfad->bfad_lock, flags); 49 50 itnim = bfad_os_get_itnim(im_port, starget->id); 51 if (itnim) 52 fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim); 53 54 fc_starget_port_id(starget) = fc_id; 55 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 56 } 57 58 /** 59 * FC transport template entry, get SCSI target nwwn. 60 */ 61 void 62 bfad_im_get_starget_node_name(struct scsi_target *starget) 63 { 64 struct Scsi_Host *shost; 65 struct bfad_im_port_s *im_port; 66 struct bfad_s *bfad; 67 struct bfad_itnim_s *itnim = NULL; 68 u64 node_name = 0; 69 unsigned long flags; 70 71 shost = bfad_os_starget_to_shost(starget); 72 im_port = (struct bfad_im_port_s *) shost->hostdata[0]; 73 bfad = im_port->bfad; 74 spin_lock_irqsave(&bfad->bfad_lock, flags); 75 76 itnim = bfad_os_get_itnim(im_port, starget->id); 77 if (itnim) 78 node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim); 79 80 fc_starget_node_name(starget) = bfa_os_htonll(node_name); 81 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 82 } 83 84 /** 85 * FC transport template entry, get SCSI target pwwn. 86 */ 87 void 88 bfad_im_get_starget_port_name(struct scsi_target *starget) 89 { 90 struct Scsi_Host *shost; 91 struct bfad_im_port_s *im_port; 92 struct bfad_s *bfad; 93 struct bfad_itnim_s *itnim = NULL; 94 u64 port_name = 0; 95 unsigned long flags; 96 97 shost = bfad_os_starget_to_shost(starget); 98 im_port = (struct bfad_im_port_s *) shost->hostdata[0]; 99 bfad = im_port->bfad; 100 spin_lock_irqsave(&bfad->bfad_lock, flags); 101 102 itnim = bfad_os_get_itnim(im_port, starget->id); 103 if (itnim) 104 port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim); 105 106 fc_starget_port_name(starget) = bfa_os_htonll(port_name); 107 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 108 } 109 110 /** 111 * FC transport template entry, get SCSI host port ID. 112 */ 113 void 114 bfad_im_get_host_port_id(struct Scsi_Host *shost) 115 { 116 struct bfad_im_port_s *im_port = 117 (struct bfad_im_port_s *) shost->hostdata[0]; 118 struct bfad_port_s *port = im_port->port; 119 120 fc_host_port_id(shost) = 121 bfa_os_hton3b(bfa_fcs_port_get_fcid(port->fcs_port)); 122 } 123 124 125 126 127 128 struct Scsi_Host * 129 bfad_os_starget_to_shost(struct scsi_target *starget) 130 { 131 return dev_to_shost(starget->dev.parent); 132 } 133 134 /** 135 * FC transport template entry, get SCSI host port type. 136 */ 137 static void 138 bfad_im_get_host_port_type(struct Scsi_Host *shost) 139 { 140 struct bfad_im_port_s *im_port = 141 (struct bfad_im_port_s *) shost->hostdata[0]; 142 struct bfad_s *bfad = im_port->bfad; 143 struct bfa_pport_attr_s attr; 144 145 bfa_fcport_get_attr(&bfad->bfa, &attr); 146 147 switch (attr.port_type) { 148 case BFA_PPORT_TYPE_NPORT: 149 fc_host_port_type(shost) = FC_PORTTYPE_NPORT; 150 break; 151 case BFA_PPORT_TYPE_NLPORT: 152 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; 153 break; 154 case BFA_PPORT_TYPE_P2P: 155 fc_host_port_type(shost) = FC_PORTTYPE_PTP; 156 break; 157 case BFA_PPORT_TYPE_LPORT: 158 fc_host_port_type(shost) = FC_PORTTYPE_LPORT; 159 break; 160 default: 161 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; 162 break; 163 } 164 } 165 166 /** 167 * FC transport template entry, get SCSI host port state. 168 */ 169 static void 170 bfad_im_get_host_port_state(struct Scsi_Host *shost) 171 { 172 struct bfad_im_port_s *im_port = 173 (struct bfad_im_port_s *) shost->hostdata[0]; 174 struct bfad_s *bfad = im_port->bfad; 175 struct bfa_pport_attr_s attr; 176 177 bfa_fcport_get_attr(&bfad->bfa, &attr); 178 179 switch (attr.port_state) { 180 case BFA_PPORT_ST_LINKDOWN: 181 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; 182 break; 183 case BFA_PPORT_ST_LINKUP: 184 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; 185 break; 186 case BFA_PPORT_ST_UNINIT: 187 case BFA_PPORT_ST_ENABLING_QWAIT: 188 case BFA_PPORT_ST_ENABLING: 189 case BFA_PPORT_ST_DISABLING_QWAIT: 190 case BFA_PPORT_ST_DISABLING: 191 case BFA_PPORT_ST_DISABLED: 192 case BFA_PPORT_ST_STOPPED: 193 case BFA_PPORT_ST_IOCDOWN: 194 default: 195 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; 196 break; 197 } 198 } 199 200 /** 201 * FC transport template entry, get SCSI host active fc4s. 202 */ 203 static void 204 bfad_im_get_host_active_fc4s(struct Scsi_Host *shost) 205 { 206 struct bfad_im_port_s *im_port = 207 (struct bfad_im_port_s *) shost->hostdata[0]; 208 struct bfad_port_s *port = im_port->port; 209 210 memset(fc_host_active_fc4s(shost), 0, 211 sizeof(fc_host_active_fc4s(shost))); 212 213 if (port->supported_fc4s & 214 (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM)) 215 fc_host_active_fc4s(shost)[2] = 1; 216 217 if (port->supported_fc4s & BFA_PORT_ROLE_FCP_IPFC) 218 fc_host_active_fc4s(shost)[3] = 0x20; 219 220 fc_host_active_fc4s(shost)[7] = 1; 221 } 222 223 /** 224 * FC transport template entry, get SCSI host link speed. 225 */ 226 static void 227 bfad_im_get_host_speed(struct Scsi_Host *shost) 228 { 229 struct bfad_im_port_s *im_port = 230 (struct bfad_im_port_s *) shost->hostdata[0]; 231 struct bfad_s *bfad = im_port->bfad; 232 struct bfa_pport_attr_s attr; 233 unsigned long flags; 234 235 spin_lock_irqsave(shost->host_lock, flags); 236 bfa_fcport_get_attr(&bfad->bfa, &attr); 237 switch (attr.speed) { 238 case BFA_PPORT_SPEED_8GBPS: 239 fc_host_speed(shost) = FC_PORTSPEED_8GBIT; 240 break; 241 case BFA_PPORT_SPEED_4GBPS: 242 fc_host_speed(shost) = FC_PORTSPEED_4GBIT; 243 break; 244 case BFA_PPORT_SPEED_2GBPS: 245 fc_host_speed(shost) = FC_PORTSPEED_2GBIT; 246 break; 247 case BFA_PPORT_SPEED_1GBPS: 248 fc_host_speed(shost) = FC_PORTSPEED_1GBIT; 249 break; 250 default: 251 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; 252 break; 253 } 254 spin_unlock_irqrestore(shost->host_lock, flags); 255 } 256 257 /** 258 * FC transport template entry, get SCSI host port type. 259 */ 260 static void 261 bfad_im_get_host_fabric_name(struct Scsi_Host *shost) 262 { 263 struct bfad_im_port_s *im_port = 264 (struct bfad_im_port_s *) shost->hostdata[0]; 265 struct bfad_port_s *port = im_port->port; 266 wwn_t fabric_nwwn = 0; 267 268 fabric_nwwn = bfa_fcs_port_get_fabric_name(port->fcs_port); 269 270 fc_host_fabric_name(shost) = bfa_os_htonll(fabric_nwwn); 271 272 } 273 274 /** 275 * FC transport template entry, get BFAD statistics. 276 */ 277 static struct fc_host_statistics * 278 bfad_im_get_stats(struct Scsi_Host *shost) 279 { 280 struct bfad_im_port_s *im_port = 281 (struct bfad_im_port_s *) shost->hostdata[0]; 282 struct bfad_s *bfad = im_port->bfad; 283 struct bfad_hal_comp fcomp; 284 struct fc_host_statistics *hstats; 285 bfa_status_t rc; 286 unsigned long flags; 287 288 hstats = &bfad->link_stats; 289 init_completion(&fcomp.comp); 290 spin_lock_irqsave(&bfad->bfad_lock, flags); 291 memset(hstats, 0, sizeof(struct fc_host_statistics)); 292 rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa), 293 (union bfa_pport_stats_u *) hstats, 294 bfad_hcb_comp, &fcomp); 295 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 296 if (rc != BFA_STATUS_OK) 297 return NULL; 298 299 wait_for_completion(&fcomp.comp); 300 301 return hstats; 302 } 303 304 /** 305 * FC transport template entry, reset BFAD statistics. 306 */ 307 static void 308 bfad_im_reset_stats(struct Scsi_Host *shost) 309 { 310 struct bfad_im_port_s *im_port = 311 (struct bfad_im_port_s *) shost->hostdata[0]; 312 struct bfad_s *bfad = im_port->bfad; 313 struct bfad_hal_comp fcomp; 314 unsigned long flags; 315 bfa_status_t rc; 316 317 init_completion(&fcomp.comp); 318 spin_lock_irqsave(&bfad->bfad_lock, flags); 319 rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp, 320 &fcomp); 321 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 322 323 if (rc != BFA_STATUS_OK) 324 return; 325 326 wait_for_completion(&fcomp.comp); 327 328 return; 329 } 330 331 /** 332 * FC transport template entry, get rport loss timeout. 333 */ 334 static void 335 bfad_im_get_rport_loss_tmo(struct fc_rport *rport) 336 { 337 struct bfad_itnim_data_s *itnim_data = rport->dd_data; 338 struct bfad_itnim_s *itnim = itnim_data->itnim; 339 struct bfad_s *bfad = itnim->im->bfad; 340 unsigned long flags; 341 342 spin_lock_irqsave(&bfad->bfad_lock, flags); 343 rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); 344 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 345 } 346 347 /** 348 * FC transport template entry, set rport loss timeout. 349 */ 350 static void 351 bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) 352 { 353 struct bfad_itnim_data_s *itnim_data = rport->dd_data; 354 struct bfad_itnim_s *itnim = itnim_data->itnim; 355 struct bfad_s *bfad = itnim->im->bfad; 356 unsigned long flags; 357 358 if (timeout > 0) { 359 spin_lock_irqsave(&bfad->bfad_lock, flags); 360 bfa_fcpim_path_tov_set(&bfad->bfa, timeout); 361 rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); 362 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 363 } 364 365 } 366 367 struct fc_function_template bfad_im_fc_function_template = { 368 369 /* Target dynamic attributes */ 370 .get_starget_port_id = bfad_im_get_starget_port_id, 371 .show_starget_port_id = 1, 372 .get_starget_node_name = bfad_im_get_starget_node_name, 373 .show_starget_node_name = 1, 374 .get_starget_port_name = bfad_im_get_starget_port_name, 375 .show_starget_port_name = 1, 376 377 /* Host dynamic attribute */ 378 .get_host_port_id = bfad_im_get_host_port_id, 379 .show_host_port_id = 1, 380 381 /* Host fixed attributes */ 382 .show_host_node_name = 1, 383 .show_host_port_name = 1, 384 .show_host_supported_classes = 1, 385 .show_host_supported_fc4s = 1, 386 .show_host_supported_speeds = 1, 387 .show_host_maxframe_size = 1, 388 389 /* More host dynamic attributes */ 390 .show_host_port_type = 1, 391 .get_host_port_type = bfad_im_get_host_port_type, 392 .show_host_port_state = 1, 393 .get_host_port_state = bfad_im_get_host_port_state, 394 .show_host_active_fc4s = 1, 395 .get_host_active_fc4s = bfad_im_get_host_active_fc4s, 396 .show_host_speed = 1, 397 .get_host_speed = bfad_im_get_host_speed, 398 .show_host_fabric_name = 1, 399 .get_host_fabric_name = bfad_im_get_host_fabric_name, 400 401 .show_host_symbolic_name = 1, 402 403 /* Statistics */ 404 .get_fc_host_stats = bfad_im_get_stats, 405 .reset_fc_host_stats = bfad_im_reset_stats, 406 407 /* Allocation length for host specific data */ 408 .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *), 409 410 /* Remote port fixed attributes */ 411 .show_rport_maxframe_size = 1, 412 .show_rport_supported_classes = 1, 413 .show_rport_dev_loss_tmo = 1, 414 .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, 415 .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, 416 }; 417 418 /** 419 * Scsi_Host_attrs SCSI host attributes 420 */ 421 static ssize_t 422 bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr, 423 char *buf) 424 { 425 struct Scsi_Host *shost = class_to_shost(dev); 426 struct bfad_im_port_s *im_port = 427 (struct bfad_im_port_s *) shost->hostdata[0]; 428 struct bfad_s *bfad = im_port->bfad; 429 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; 430 431 bfa_get_adapter_serial_num(&bfad->bfa, serial_num); 432 return snprintf(buf, PAGE_SIZE, "%s\n", serial_num); 433 } 434 435 static ssize_t 436 bfad_im_model_show(struct device *dev, struct device_attribute *attr, 437 char *buf) 438 { 439 struct Scsi_Host *shost = class_to_shost(dev); 440 struct bfad_im_port_s *im_port = 441 (struct bfad_im_port_s *) shost->hostdata[0]; 442 struct bfad_s *bfad = im_port->bfad; 443 char model[BFA_ADAPTER_MODEL_NAME_LEN]; 444 445 bfa_get_adapter_model(&bfad->bfa, model); 446 return snprintf(buf, PAGE_SIZE, "%s\n", model); 447 } 448 449 static ssize_t 450 bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, 451 char *buf) 452 { 453 struct Scsi_Host *shost = class_to_shost(dev); 454 struct bfad_im_port_s *im_port = 455 (struct bfad_im_port_s *) shost->hostdata[0]; 456 struct bfad_s *bfad = im_port->bfad; 457 char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN]; 458 459 bfa_get_adapter_model(&bfad->bfa, model_descr); 460 return snprintf(buf, PAGE_SIZE, "%s\n", model_descr); 461 } 462 463 static ssize_t 464 bfad_im_node_name_show(struct device *dev, struct device_attribute *attr, 465 char *buf) 466 { 467 struct Scsi_Host *shost = class_to_shost(dev); 468 struct bfad_im_port_s *im_port = 469 (struct bfad_im_port_s *) shost->hostdata[0]; 470 struct bfad_port_s *port = im_port->port; 471 u64 nwwn; 472 473 nwwn = bfa_fcs_port_get_nwwn(port->fcs_port); 474 return snprintf(buf, PAGE_SIZE, "0x%llx\n", bfa_os_htonll(nwwn)); 475 } 476 477 static ssize_t 478 bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, 479 char *buf) 480 { 481 struct Scsi_Host *shost = class_to_shost(dev); 482 struct bfad_im_port_s *im_port = 483 (struct bfad_im_port_s *) shost->hostdata[0]; 484 struct bfad_s *bfad = im_port->bfad; 485 char model[BFA_ADAPTER_MODEL_NAME_LEN]; 486 char fw_ver[BFA_VERSION_LEN]; 487 488 bfa_get_adapter_model(&bfad->bfa, model); 489 bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); 490 return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n", 491 model, fw_ver, BFAD_DRIVER_VERSION); 492 } 493 494 static ssize_t 495 bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr, 496 char *buf) 497 { 498 struct Scsi_Host *shost = class_to_shost(dev); 499 struct bfad_im_port_s *im_port = 500 (struct bfad_im_port_s *) shost->hostdata[0]; 501 struct bfad_s *bfad = im_port->bfad; 502 char hw_ver[BFA_VERSION_LEN]; 503 504 bfa_get_pci_chip_rev(&bfad->bfa, hw_ver); 505 return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver); 506 } 507 508 static ssize_t 509 bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr, 510 char *buf) 511 { 512 return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION); 513 } 514 515 static ssize_t 516 bfad_im_optionrom_version_show(struct device *dev, 517 struct device_attribute *attr, char *buf) 518 { 519 struct Scsi_Host *shost = class_to_shost(dev); 520 struct bfad_im_port_s *im_port = 521 (struct bfad_im_port_s *) shost->hostdata[0]; 522 struct bfad_s *bfad = im_port->bfad; 523 char optrom_ver[BFA_VERSION_LEN]; 524 525 bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver); 526 return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver); 527 } 528 529 static ssize_t 530 bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr, 531 char *buf) 532 { 533 struct Scsi_Host *shost = class_to_shost(dev); 534 struct bfad_im_port_s *im_port = 535 (struct bfad_im_port_s *) shost->hostdata[0]; 536 struct bfad_s *bfad = im_port->bfad; 537 char fw_ver[BFA_VERSION_LEN]; 538 539 bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); 540 return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver); 541 } 542 543 static ssize_t 544 bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr, 545 char *buf) 546 { 547 struct Scsi_Host *shost = class_to_shost(dev); 548 struct bfad_im_port_s *im_port = 549 (struct bfad_im_port_s *) shost->hostdata[0]; 550 struct bfad_s *bfad = im_port->bfad; 551 552 return snprintf(buf, PAGE_SIZE, "%d\n", 553 bfa_get_nports(&bfad->bfa)); 554 } 555 556 static ssize_t 557 bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr, 558 char *buf) 559 { 560 return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME); 561 } 562 563 static ssize_t 564 bfad_im_num_of_discovered_ports_show(struct device *dev, 565 struct device_attribute *attr, char *buf) 566 { 567 struct Scsi_Host *shost = class_to_shost(dev); 568 struct bfad_im_port_s *im_port = 569 (struct bfad_im_port_s *) shost->hostdata[0]; 570 struct bfad_port_s *port = im_port->port; 571 struct bfad_s *bfad = im_port->bfad; 572 int nrports = 2048; 573 wwn_t *rports = NULL; 574 unsigned long flags; 575 576 rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC); 577 if (rports == NULL) 578 return -ENOMEM; 579 580 spin_lock_irqsave(&bfad->bfad_lock, flags); 581 bfa_fcs_port_get_rports(port->fcs_port, rports, &nrports); 582 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 583 kfree(rports); 584 585 return snprintf(buf, PAGE_SIZE, "%d\n", nrports); 586 } 587 588 static DEVICE_ATTR(serial_number, S_IRUGO, 589 bfad_im_serial_num_show, NULL); 590 static DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL); 591 static DEVICE_ATTR(model_description, S_IRUGO, 592 bfad_im_model_desc_show, NULL); 593 static DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL); 594 static DEVICE_ATTR(symbolic_name, S_IRUGO, 595 bfad_im_symbolic_name_show, NULL); 596 static DEVICE_ATTR(hardware_version, S_IRUGO, 597 bfad_im_hw_version_show, NULL); 598 static DEVICE_ATTR(driver_version, S_IRUGO, 599 bfad_im_drv_version_show, NULL); 600 static DEVICE_ATTR(option_rom_version, S_IRUGO, 601 bfad_im_optionrom_version_show, NULL); 602 static DEVICE_ATTR(firmware_version, S_IRUGO, 603 bfad_im_fw_version_show, NULL); 604 static DEVICE_ATTR(number_of_ports, S_IRUGO, 605 bfad_im_num_of_ports_show, NULL); 606 static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL); 607 static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO, 608 bfad_im_num_of_discovered_ports_show, NULL); 609 610 struct device_attribute *bfad_im_host_attrs[] = { 611 &dev_attr_serial_number, 612 &dev_attr_model, 613 &dev_attr_model_description, 614 &dev_attr_node_name, 615 &dev_attr_symbolic_name, 616 &dev_attr_hardware_version, 617 &dev_attr_driver_version, 618 &dev_attr_option_rom_version, 619 &dev_attr_firmware_version, 620 &dev_attr_number_of_ports, 621 &dev_attr_driver_name, 622 &dev_attr_number_of_discovered_ports, 623 NULL, 624 }; 625 626 struct device_attribute *bfad_im_vport_attrs[] = { 627 &dev_attr_serial_number, 628 &dev_attr_model, 629 &dev_attr_model_description, 630 &dev_attr_node_name, 631 &dev_attr_symbolic_name, 632 &dev_attr_hardware_version, 633 &dev_attr_driver_version, 634 &dev_attr_option_rom_version, 635 &dev_attr_firmware_version, 636 &dev_attr_number_of_ports, 637 &dev_attr_driver_name, 638 &dev_attr_number_of_discovered_ports, 639 NULL, 640 }; 641 642 643