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