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 static int 368 bfad_im_vport_create(struct fc_vport *fc_vport, bool disable) 369 { 370 char *vname = fc_vport->symbolic_name; 371 struct Scsi_Host *shost = fc_vport->shost; 372 struct bfad_im_port_s *im_port = 373 (struct bfad_im_port_s *) shost->hostdata[0]; 374 struct bfad_s *bfad = im_port->bfad; 375 struct bfa_port_cfg_s port_cfg; 376 int status = 0, rc; 377 unsigned long flags; 378 379 memset(&port_cfg, 0, sizeof(port_cfg)); 380 381 port_cfg.pwwn = wwn_to_u64((u8 *) &fc_vport->port_name); 382 port_cfg.nwwn = wwn_to_u64((u8 *) &fc_vport->node_name); 383 384 if (strlen(vname) > 0) 385 strcpy((char *)&port_cfg.sym_name, vname); 386 387 port_cfg.roles = BFA_PORT_ROLE_FCP_IM; 388 rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev); 389 390 if (rc == BFA_STATUS_OK) { 391 struct bfad_vport_s *vport; 392 struct bfa_fcs_vport_s *fcs_vport; 393 struct Scsi_Host *vshost; 394 395 spin_lock_irqsave(&bfad->bfad_lock, flags); 396 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, 397 port_cfg.pwwn); 398 if (fcs_vport == NULL) { 399 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 400 return VPCERR_BAD_WWN; 401 } 402 403 fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE); 404 if (disable) { 405 bfa_fcs_vport_stop(fcs_vport); 406 fc_vport_set_state(fc_vport, FC_VPORT_DISABLED); 407 } 408 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 409 410 vport = fcs_vport->vport_drv; 411 vshost = vport->drv_port.im_port->shost; 412 fc_host_node_name(vshost) = wwn_to_u64((u8 *) &port_cfg.nwwn); 413 fc_host_port_name(vshost) = wwn_to_u64((u8 *) &port_cfg.pwwn); 414 fc_vport->dd_data = vport; 415 vport->drv_port.im_port->fc_vport = fc_vport; 416 417 } else if (rc == BFA_STATUS_INVALID_WWN) 418 return VPCERR_BAD_WWN; 419 else if (rc == BFA_STATUS_VPORT_EXISTS) 420 return VPCERR_BAD_WWN; 421 else if (rc == BFA_STATUS_VPORT_MAX) 422 return VPCERR_NO_FABRIC_SUPP; 423 else if (rc == BFA_STATUS_VPORT_WWN_BP) 424 return VPCERR_BAD_WWN; 425 else 426 return FC_VPORT_FAILED; 427 428 return status; 429 } 430 431 static int 432 bfad_im_vport_delete(struct fc_vport *fc_vport) 433 { 434 struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data; 435 struct bfad_im_port_s *im_port = 436 (struct bfad_im_port_s *) vport->drv_port.im_port; 437 struct bfad_s *bfad = im_port->bfad; 438 struct bfad_port_s *port; 439 struct bfa_fcs_vport_s *fcs_vport; 440 struct Scsi_Host *vshost; 441 wwn_t pwwn; 442 int rc; 443 unsigned long flags; 444 struct completion fcomp; 445 446 if (im_port->flags & BFAD_PORT_DELETE) 447 goto free_scsi_host; 448 449 port = im_port->port; 450 451 vshost = vport->drv_port.im_port->shost; 452 pwwn = wwn_to_u64((u8 *) &fc_host_port_name(vshost)); 453 454 spin_lock_irqsave(&bfad->bfad_lock, flags); 455 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); 456 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 457 458 if (fcs_vport == NULL) 459 return VPCERR_BAD_WWN; 460 461 vport->drv_port.flags |= BFAD_PORT_DELETE; 462 463 vport->comp_del = &fcomp; 464 init_completion(vport->comp_del); 465 466 spin_lock_irqsave(&bfad->bfad_lock, flags); 467 rc = bfa_fcs_vport_delete(&vport->fcs_vport); 468 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 469 470 wait_for_completion(vport->comp_del); 471 472 free_scsi_host: 473 bfad_os_scsi_host_free(bfad, im_port); 474 475 kfree(vport); 476 477 return 0; 478 } 479 480 static int 481 bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable) 482 { 483 struct bfad_vport_s *vport; 484 struct bfad_s *bfad; 485 struct bfa_fcs_vport_s *fcs_vport; 486 struct Scsi_Host *vshost; 487 wwn_t pwwn; 488 unsigned long flags; 489 490 vport = (struct bfad_vport_s *)fc_vport->dd_data; 491 bfad = vport->drv_port.bfad; 492 vshost = vport->drv_port.im_port->shost; 493 pwwn = wwn_to_u64((u8 *) &fc_vport->port_name); 494 495 spin_lock_irqsave(&bfad->bfad_lock, flags); 496 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); 497 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 498 499 if (fcs_vport == NULL) 500 return VPCERR_BAD_WWN; 501 502 if (disable) { 503 bfa_fcs_vport_stop(fcs_vport); 504 fc_vport_set_state(fc_vport, FC_VPORT_DISABLED); 505 } else { 506 bfa_fcs_vport_start(fcs_vport); 507 fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE); 508 } 509 510 return 0; 511 } 512 513 struct fc_function_template bfad_im_fc_function_template = { 514 515 /* Target dynamic attributes */ 516 .get_starget_port_id = bfad_im_get_starget_port_id, 517 .show_starget_port_id = 1, 518 .get_starget_node_name = bfad_im_get_starget_node_name, 519 .show_starget_node_name = 1, 520 .get_starget_port_name = bfad_im_get_starget_port_name, 521 .show_starget_port_name = 1, 522 523 /* Host dynamic attribute */ 524 .get_host_port_id = bfad_im_get_host_port_id, 525 .show_host_port_id = 1, 526 527 /* Host fixed attributes */ 528 .show_host_node_name = 1, 529 .show_host_port_name = 1, 530 .show_host_supported_classes = 1, 531 .show_host_supported_fc4s = 1, 532 .show_host_supported_speeds = 1, 533 .show_host_maxframe_size = 1, 534 535 /* More host dynamic attributes */ 536 .show_host_port_type = 1, 537 .get_host_port_type = bfad_im_get_host_port_type, 538 .show_host_port_state = 1, 539 .get_host_port_state = bfad_im_get_host_port_state, 540 .show_host_active_fc4s = 1, 541 .get_host_active_fc4s = bfad_im_get_host_active_fc4s, 542 .show_host_speed = 1, 543 .get_host_speed = bfad_im_get_host_speed, 544 .show_host_fabric_name = 1, 545 .get_host_fabric_name = bfad_im_get_host_fabric_name, 546 547 .show_host_symbolic_name = 1, 548 549 /* Statistics */ 550 .get_fc_host_stats = bfad_im_get_stats, 551 .reset_fc_host_stats = bfad_im_reset_stats, 552 553 /* Allocation length for host specific data */ 554 .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *), 555 556 /* Remote port fixed attributes */ 557 .show_rport_maxframe_size = 1, 558 .show_rport_supported_classes = 1, 559 .show_rport_dev_loss_tmo = 1, 560 .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, 561 .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, 562 563 .vport_create = bfad_im_vport_create, 564 .vport_delete = bfad_im_vport_delete, 565 .vport_disable = bfad_im_vport_disable, 566 }; 567 568 struct fc_function_template bfad_im_vport_fc_function_template = { 569 570 /* Target dynamic attributes */ 571 .get_starget_port_id = bfad_im_get_starget_port_id, 572 .show_starget_port_id = 1, 573 .get_starget_node_name = bfad_im_get_starget_node_name, 574 .show_starget_node_name = 1, 575 .get_starget_port_name = bfad_im_get_starget_port_name, 576 .show_starget_port_name = 1, 577 578 /* Host dynamic attribute */ 579 .get_host_port_id = bfad_im_get_host_port_id, 580 .show_host_port_id = 1, 581 582 /* Host fixed attributes */ 583 .show_host_node_name = 1, 584 .show_host_port_name = 1, 585 .show_host_supported_classes = 1, 586 .show_host_supported_fc4s = 1, 587 .show_host_supported_speeds = 1, 588 .show_host_maxframe_size = 1, 589 590 /* More host dynamic attributes */ 591 .show_host_port_type = 1, 592 .get_host_port_type = bfad_im_get_host_port_type, 593 .show_host_port_state = 1, 594 .get_host_port_state = bfad_im_get_host_port_state, 595 .show_host_active_fc4s = 1, 596 .get_host_active_fc4s = bfad_im_get_host_active_fc4s, 597 .show_host_speed = 1, 598 .get_host_speed = bfad_im_get_host_speed, 599 .show_host_fabric_name = 1, 600 .get_host_fabric_name = bfad_im_get_host_fabric_name, 601 602 .show_host_symbolic_name = 1, 603 604 /* Statistics */ 605 .get_fc_host_stats = bfad_im_get_stats, 606 .reset_fc_host_stats = bfad_im_reset_stats, 607 608 /* Allocation length for host specific data */ 609 .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *), 610 611 /* Remote port fixed attributes */ 612 .show_rport_maxframe_size = 1, 613 .show_rport_supported_classes = 1, 614 .show_rport_dev_loss_tmo = 1, 615 .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, 616 .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, 617 }; 618 619 /** 620 * Scsi_Host_attrs SCSI host attributes 621 */ 622 static ssize_t 623 bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr, 624 char *buf) 625 { 626 struct Scsi_Host *shost = class_to_shost(dev); 627 struct bfad_im_port_s *im_port = 628 (struct bfad_im_port_s *) shost->hostdata[0]; 629 struct bfad_s *bfad = im_port->bfad; 630 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; 631 632 bfa_get_adapter_serial_num(&bfad->bfa, serial_num); 633 return snprintf(buf, PAGE_SIZE, "%s\n", serial_num); 634 } 635 636 static ssize_t 637 bfad_im_model_show(struct device *dev, struct device_attribute *attr, 638 char *buf) 639 { 640 struct Scsi_Host *shost = class_to_shost(dev); 641 struct bfad_im_port_s *im_port = 642 (struct bfad_im_port_s *) shost->hostdata[0]; 643 struct bfad_s *bfad = im_port->bfad; 644 char model[BFA_ADAPTER_MODEL_NAME_LEN]; 645 646 bfa_get_adapter_model(&bfad->bfa, model); 647 return snprintf(buf, PAGE_SIZE, "%s\n", model); 648 } 649 650 static ssize_t 651 bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, 652 char *buf) 653 { 654 struct Scsi_Host *shost = class_to_shost(dev); 655 struct bfad_im_port_s *im_port = 656 (struct bfad_im_port_s *) shost->hostdata[0]; 657 struct bfad_s *bfad = im_port->bfad; 658 char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN]; 659 660 bfa_get_adapter_model(&bfad->bfa, model_descr); 661 return snprintf(buf, PAGE_SIZE, "%s\n", model_descr); 662 } 663 664 static ssize_t 665 bfad_im_node_name_show(struct device *dev, struct device_attribute *attr, 666 char *buf) 667 { 668 struct Scsi_Host *shost = class_to_shost(dev); 669 struct bfad_im_port_s *im_port = 670 (struct bfad_im_port_s *) shost->hostdata[0]; 671 struct bfad_port_s *port = im_port->port; 672 u64 nwwn; 673 674 nwwn = bfa_fcs_port_get_nwwn(port->fcs_port); 675 return snprintf(buf, PAGE_SIZE, "0x%llx\n", bfa_os_htonll(nwwn)); 676 } 677 678 static ssize_t 679 bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, 680 char *buf) 681 { 682 struct Scsi_Host *shost = class_to_shost(dev); 683 struct bfad_im_port_s *im_port = 684 (struct bfad_im_port_s *) shost->hostdata[0]; 685 struct bfad_s *bfad = im_port->bfad; 686 char model[BFA_ADAPTER_MODEL_NAME_LEN]; 687 char fw_ver[BFA_VERSION_LEN]; 688 689 bfa_get_adapter_model(&bfad->bfa, model); 690 bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); 691 return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n", 692 model, fw_ver, BFAD_DRIVER_VERSION); 693 } 694 695 static ssize_t 696 bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr, 697 char *buf) 698 { 699 struct Scsi_Host *shost = class_to_shost(dev); 700 struct bfad_im_port_s *im_port = 701 (struct bfad_im_port_s *) shost->hostdata[0]; 702 struct bfad_s *bfad = im_port->bfad; 703 char hw_ver[BFA_VERSION_LEN]; 704 705 bfa_get_pci_chip_rev(&bfad->bfa, hw_ver); 706 return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver); 707 } 708 709 static ssize_t 710 bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr, 711 char *buf) 712 { 713 return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION); 714 } 715 716 static ssize_t 717 bfad_im_optionrom_version_show(struct device *dev, 718 struct device_attribute *attr, char *buf) 719 { 720 struct Scsi_Host *shost = class_to_shost(dev); 721 struct bfad_im_port_s *im_port = 722 (struct bfad_im_port_s *) shost->hostdata[0]; 723 struct bfad_s *bfad = im_port->bfad; 724 char optrom_ver[BFA_VERSION_LEN]; 725 726 bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver); 727 return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver); 728 } 729 730 static ssize_t 731 bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr, 732 char *buf) 733 { 734 struct Scsi_Host *shost = class_to_shost(dev); 735 struct bfad_im_port_s *im_port = 736 (struct bfad_im_port_s *) shost->hostdata[0]; 737 struct bfad_s *bfad = im_port->bfad; 738 char fw_ver[BFA_VERSION_LEN]; 739 740 bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); 741 return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver); 742 } 743 744 static ssize_t 745 bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr, 746 char *buf) 747 { 748 struct Scsi_Host *shost = class_to_shost(dev); 749 struct bfad_im_port_s *im_port = 750 (struct bfad_im_port_s *) shost->hostdata[0]; 751 struct bfad_s *bfad = im_port->bfad; 752 753 return snprintf(buf, PAGE_SIZE, "%d\n", 754 bfa_get_nports(&bfad->bfa)); 755 } 756 757 static ssize_t 758 bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr, 759 char *buf) 760 { 761 return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME); 762 } 763 764 static ssize_t 765 bfad_im_num_of_discovered_ports_show(struct device *dev, 766 struct device_attribute *attr, char *buf) 767 { 768 struct Scsi_Host *shost = class_to_shost(dev); 769 struct bfad_im_port_s *im_port = 770 (struct bfad_im_port_s *) shost->hostdata[0]; 771 struct bfad_port_s *port = im_port->port; 772 struct bfad_s *bfad = im_port->bfad; 773 int nrports = 2048; 774 wwn_t *rports = NULL; 775 unsigned long flags; 776 777 rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC); 778 if (rports == NULL) 779 return -ENOMEM; 780 781 spin_lock_irqsave(&bfad->bfad_lock, flags); 782 bfa_fcs_port_get_rports(port->fcs_port, rports, &nrports); 783 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 784 kfree(rports); 785 786 return snprintf(buf, PAGE_SIZE, "%d\n", nrports); 787 } 788 789 static DEVICE_ATTR(serial_number, S_IRUGO, 790 bfad_im_serial_num_show, NULL); 791 static DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL); 792 static DEVICE_ATTR(model_description, S_IRUGO, 793 bfad_im_model_desc_show, NULL); 794 static DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL); 795 static DEVICE_ATTR(symbolic_name, S_IRUGO, 796 bfad_im_symbolic_name_show, NULL); 797 static DEVICE_ATTR(hardware_version, S_IRUGO, 798 bfad_im_hw_version_show, NULL); 799 static DEVICE_ATTR(driver_version, S_IRUGO, 800 bfad_im_drv_version_show, NULL); 801 static DEVICE_ATTR(option_rom_version, S_IRUGO, 802 bfad_im_optionrom_version_show, NULL); 803 static DEVICE_ATTR(firmware_version, S_IRUGO, 804 bfad_im_fw_version_show, NULL); 805 static DEVICE_ATTR(number_of_ports, S_IRUGO, 806 bfad_im_num_of_ports_show, NULL); 807 static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL); 808 static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO, 809 bfad_im_num_of_discovered_ports_show, NULL); 810 811 struct device_attribute *bfad_im_host_attrs[] = { 812 &dev_attr_serial_number, 813 &dev_attr_model, 814 &dev_attr_model_description, 815 &dev_attr_node_name, 816 &dev_attr_symbolic_name, 817 &dev_attr_hardware_version, 818 &dev_attr_driver_version, 819 &dev_attr_option_rom_version, 820 &dev_attr_firmware_version, 821 &dev_attr_number_of_ports, 822 &dev_attr_driver_name, 823 &dev_attr_number_of_discovered_ports, 824 NULL, 825 }; 826 827 struct device_attribute *bfad_im_vport_attrs[] = { 828 &dev_attr_serial_number, 829 &dev_attr_model, 830 &dev_attr_model_description, 831 &dev_attr_node_name, 832 &dev_attr_symbolic_name, 833 &dev_attr_hardware_version, 834 &dev_attr_driver_version, 835 &dev_attr_option_rom_version, 836 &dev_attr_firmware_version, 837 &dev_attr_number_of_ports, 838 &dev_attr_driver_name, 839 &dev_attr_number_of_discovered_ports, 840 NULL, 841 }; 842 843 844