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