1 /******************************************************************* 2 * This file is part of the Emulex Linux Device Driver for * 3 * Enterprise Fibre Channel Host Bus Adapters. * 4 * Refer to the README file included with this package for * 5 * driver version and adapter support. * 6 * Copyright (C) 2004 Emulex Corporation. * 7 * www.emulex.com * 8 * * 9 * This program is free software; you can redistribute it and/or * 10 * modify it under the terms of the GNU General Public License * 11 * as published by the Free Software Foundation; either version 2 * 12 * of the License, or (at your option) any later version. * 13 * * 14 * This program is distributed in the hope that it will be useful, * 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 * GNU General Public License for more details, a copy of which * 18 * can be found in the file COPYING included with this package. * 19 *******************************************************************/ 20 21 /* 22 * $Id: lpfc_attr.c 1.24 2005/04/13 11:58:55EDT sf_support Exp $ 23 */ 24 25 #include <linux/ctype.h> 26 #include <linux/pci.h> 27 #include <linux/interrupt.h> 28 29 #include <scsi/scsi_device.h> 30 #include <scsi/scsi_host.h> 31 #include <scsi/scsi_tcq.h> 32 #include <scsi/scsi_transport_fc.h> 33 34 #include "lpfc_hw.h" 35 #include "lpfc_sli.h" 36 #include "lpfc_disc.h" 37 #include "lpfc_scsi.h" 38 #include "lpfc.h" 39 #include "lpfc_logmsg.h" 40 #include "lpfc_version.h" 41 #include "lpfc_compat.h" 42 #include "lpfc_crtn.h" 43 44 45 static void 46 lpfc_jedec_to_ascii(int incr, char hdw[]) 47 { 48 int i, j; 49 for (i = 0; i < 8; i++) { 50 j = (incr & 0xf); 51 if (j <= 9) 52 hdw[7 - i] = 0x30 + j; 53 else 54 hdw[7 - i] = 0x61 + j - 10; 55 incr = (incr >> 4); 56 } 57 hdw[8] = 0; 58 return; 59 } 60 61 static ssize_t 62 lpfc_drvr_version_show(struct class_device *cdev, char *buf) 63 { 64 return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n"); 65 } 66 67 static ssize_t 68 management_version_show(struct class_device *cdev, char *buf) 69 { 70 return snprintf(buf, PAGE_SIZE, DFC_API_VERSION "\n"); 71 } 72 73 static ssize_t 74 lpfc_info_show(struct class_device *cdev, char *buf) 75 { 76 struct Scsi_Host *host = class_to_shost(cdev); 77 return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host)); 78 } 79 80 static ssize_t 81 lpfc_serialnum_show(struct class_device *cdev, char *buf) 82 { 83 struct Scsi_Host *host = class_to_shost(cdev); 84 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 85 return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber); 86 } 87 88 static ssize_t 89 lpfc_modeldesc_show(struct class_device *cdev, char *buf) 90 { 91 struct Scsi_Host *host = class_to_shost(cdev); 92 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 93 return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc); 94 } 95 96 static ssize_t 97 lpfc_modelname_show(struct class_device *cdev, char *buf) 98 { 99 struct Scsi_Host *host = class_to_shost(cdev); 100 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 101 return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName); 102 } 103 104 static ssize_t 105 lpfc_programtype_show(struct class_device *cdev, char *buf) 106 { 107 struct Scsi_Host *host = class_to_shost(cdev); 108 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 109 return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType); 110 } 111 112 static ssize_t 113 lpfc_portnum_show(struct class_device *cdev, char *buf) 114 { 115 struct Scsi_Host *host = class_to_shost(cdev); 116 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 117 return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port); 118 } 119 120 static ssize_t 121 lpfc_fwrev_show(struct class_device *cdev, char *buf) 122 { 123 struct Scsi_Host *host = class_to_shost(cdev); 124 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 125 char fwrev[32]; 126 lpfc_decode_firmware_rev(phba, fwrev, 1); 127 return snprintf(buf, PAGE_SIZE, "%s\n",fwrev); 128 } 129 130 static ssize_t 131 lpfc_hdw_show(struct class_device *cdev, char *buf) 132 { 133 char hdw[9]; 134 struct Scsi_Host *host = class_to_shost(cdev); 135 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 136 lpfc_vpd_t *vp = &phba->vpd; 137 lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); 138 return snprintf(buf, PAGE_SIZE, "%s\n", hdw); 139 } 140 static ssize_t 141 lpfc_option_rom_version_show(struct class_device *cdev, char *buf) 142 { 143 struct Scsi_Host *host = class_to_shost(cdev); 144 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 145 return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion); 146 } 147 static ssize_t 148 lpfc_state_show(struct class_device *cdev, char *buf) 149 { 150 struct Scsi_Host *host = class_to_shost(cdev); 151 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 152 int len = 0; 153 switch (phba->hba_state) { 154 case LPFC_INIT_START: 155 case LPFC_INIT_MBX_CMDS: 156 case LPFC_LINK_DOWN: 157 len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n"); 158 break; 159 case LPFC_LINK_UP: 160 case LPFC_LOCAL_CFG_LINK: 161 len += snprintf(buf + len, PAGE_SIZE-len, "Link Up\n"); 162 break; 163 case LPFC_FLOGI: 164 case LPFC_FABRIC_CFG_LINK: 165 case LPFC_NS_REG: 166 case LPFC_NS_QRY: 167 case LPFC_BUILD_DISC_LIST: 168 case LPFC_DISC_AUTH: 169 case LPFC_CLEAR_LA: 170 len += snprintf(buf + len, PAGE_SIZE-len, 171 "Link Up - Discovery\n"); 172 break; 173 case LPFC_HBA_READY: 174 len += snprintf(buf + len, PAGE_SIZE-len, 175 "Link Up - Ready:\n"); 176 if (phba->fc_topology == TOPOLOGY_LOOP) { 177 if (phba->fc_flag & FC_PUBLIC_LOOP) 178 len += snprintf(buf + len, PAGE_SIZE-len, 179 " Public Loop\n"); 180 else 181 len += snprintf(buf + len, PAGE_SIZE-len, 182 " Private Loop\n"); 183 } else { 184 if (phba->fc_flag & FC_FABRIC) 185 len += snprintf(buf + len, PAGE_SIZE-len, 186 " Fabric\n"); 187 else 188 len += snprintf(buf + len, PAGE_SIZE-len, 189 " Point-2-Point\n"); 190 } 191 } 192 return len; 193 } 194 195 static ssize_t 196 lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) 197 { 198 struct Scsi_Host *host = class_to_shost(cdev); 199 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 200 return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt + 201 phba->fc_unmap_cnt); 202 } 203 204 205 static ssize_t 206 lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count) 207 { 208 struct Scsi_Host *host = class_to_shost(cdev); 209 struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0]; 210 int val = 0; 211 LPFC_MBOXQ_t *pmboxq; 212 int mbxstatus = MBXERR_ERROR; 213 214 if ((sscanf(buf, "%d", &val) != 1) || 215 (val != 1)) 216 return -EINVAL; 217 218 if ((phba->fc_flag & FC_OFFLINE_MODE) || 219 (phba->hba_state != LPFC_HBA_READY)) 220 return -EPERM; 221 222 pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); 223 224 if (!pmboxq) 225 return -ENOMEM; 226 227 memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); 228 lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed); 229 mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 230 231 if (mbxstatus == MBX_TIMEOUT) 232 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 233 else 234 mempool_free( pmboxq, phba->mbox_mem_pool); 235 236 if (mbxstatus == MBXERR_ERROR) 237 return -EIO; 238 239 return strlen(buf); 240 } 241 242 static ssize_t 243 lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) 244 { 245 struct Scsi_Host *host = class_to_shost(cdev); 246 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 247 return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); 248 } 249 250 static ssize_t 251 lpfc_board_online_show(struct class_device *cdev, char *buf) 252 { 253 struct Scsi_Host *host = class_to_shost(cdev); 254 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 255 256 if (!phba) return 0; 257 258 if (phba->fc_flag & FC_OFFLINE_MODE) 259 return snprintf(buf, PAGE_SIZE, "0\n"); 260 else 261 return snprintf(buf, PAGE_SIZE, "1\n"); 262 } 263 264 static ssize_t 265 lpfc_board_online_store(struct class_device *cdev, const char *buf, 266 size_t count) 267 { 268 struct Scsi_Host *host = class_to_shost(cdev); 269 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 270 struct completion online_compl; 271 int val=0, status=0; 272 273 if (sscanf(buf, "%d", &val) != 1) 274 return 0; 275 276 init_completion(&online_compl); 277 278 if (val) 279 lpfc_workq_post_event(phba, &status, &online_compl, 280 LPFC_EVT_ONLINE); 281 else 282 lpfc_workq_post_event(phba, &status, &online_compl, 283 LPFC_EVT_OFFLINE); 284 wait_for_completion(&online_compl); 285 if (!status) 286 return strlen(buf); 287 else 288 return 0; 289 } 290 291 292 #define lpfc_param_show(attr) \ 293 static ssize_t \ 294 lpfc_##attr##_show(struct class_device *cdev, char *buf) \ 295 { \ 296 struct Scsi_Host *host = class_to_shost(cdev);\ 297 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ 298 int val = 0;\ 299 if (phba){\ 300 val = phba->cfg_##attr;\ 301 return snprintf(buf, PAGE_SIZE, "%d\n",\ 302 phba->cfg_##attr);\ 303 }\ 304 return 0;\ 305 } 306 307 #define lpfc_param_store(attr, minval, maxval) \ 308 static ssize_t \ 309 lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ 310 { \ 311 struct Scsi_Host *host = class_to_shost(cdev);\ 312 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ 313 int val = 0;\ 314 if (!isdigit(buf[0]))\ 315 return -EINVAL;\ 316 if (sscanf(buf, "0x%x", &val) != 1)\ 317 if (sscanf(buf, "%d", &val) != 1)\ 318 return -EINVAL;\ 319 if (phba){\ 320 if (val >= minval && val <= maxval) {\ 321 phba->cfg_##attr = val;\ 322 return strlen(buf);\ 323 }\ 324 }\ 325 return 0;\ 326 } 327 328 #define LPFC_ATTR_R_NOINIT(name, desc) \ 329 extern int lpfc_##name;\ 330 module_param(lpfc_##name, int, 0);\ 331 MODULE_PARM_DESC(lpfc_##name, desc);\ 332 lpfc_param_show(name)\ 333 static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) 334 335 #define LPFC_ATTR_R(name, defval, minval, maxval, desc) \ 336 static int lpfc_##name = defval;\ 337 module_param(lpfc_##name, int, 0);\ 338 MODULE_PARM_DESC(lpfc_##name, desc);\ 339 lpfc_param_show(name)\ 340 static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) 341 342 #define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \ 343 static int lpfc_##name = defval;\ 344 module_param(lpfc_##name, int, 0);\ 345 MODULE_PARM_DESC(lpfc_##name, desc);\ 346 lpfc_param_show(name)\ 347 lpfc_param_store(name, minval, maxval)\ 348 static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ 349 lpfc_##name##_show, lpfc_##name##_store) 350 351 static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL); 352 static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL); 353 static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL); 354 static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL); 355 static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL); 356 static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_portnum_show, NULL); 357 static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL); 358 static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL); 359 static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL); 360 static CLASS_DEVICE_ATTR(option_rom_version, S_IRUGO, 361 lpfc_option_rom_version_show, NULL); 362 static CLASS_DEVICE_ATTR(num_discovered_ports, S_IRUGO, 363 lpfc_num_discovered_ports_show, NULL); 364 static CLASS_DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL); 365 static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, 366 NULL); 367 static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, 368 NULL); 369 static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip); 370 static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, 371 lpfc_board_online_show, lpfc_board_online_store); 372 373 374 /* 375 # lpfc_log_verbose: Only turn this flag on if you are willing to risk being 376 # deluged with LOTS of information. 377 # You can set a bit mask to record specific types of verbose messages: 378 # 379 # LOG_ELS 0x1 ELS events 380 # LOG_DISCOVERY 0x2 Link discovery events 381 # LOG_MBOX 0x4 Mailbox events 382 # LOG_INIT 0x8 Initialization events 383 # LOG_LINK_EVENT 0x10 Link events 384 # LOG_IP 0x20 IP traffic history 385 # LOG_FCP 0x40 FCP traffic history 386 # LOG_NODE 0x80 Node table events 387 # LOG_MISC 0x400 Miscellaneous events 388 # LOG_SLI 0x800 SLI events 389 # LOG_CHK_COND 0x1000 FCP Check condition flag 390 # LOG_LIBDFC 0x2000 LIBDFC events 391 # LOG_ALL_MSG 0xffff LOG all messages 392 */ 393 LPFC_ATTR_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask"); 394 395 /* 396 # lun_queue_depth: This parameter is used to limit the number of outstanding 397 # commands per FCP LUN. Value range is [1,128]. Default value is 30. 398 */ 399 LPFC_ATTR_R(lun_queue_depth, 30, 1, 128, 400 "Max number of FCP commands we can queue to a specific LUN"); 401 402 /* 403 # Some disk devices have a "select ID" or "select Target" capability. 404 # From a protocol standpoint "select ID" usually means select the 405 # Fibre channel "ALPA". In the FC-AL Profile there is an "informative 406 # annex" which contains a table that maps a "select ID" (a number 407 # between 0 and 7F) to an ALPA. By default, for compatibility with 408 # older drivers, the lpfc driver scans this table from low ALPA to high 409 # ALPA. 410 # 411 # Turning on the scan-down variable (on = 1, off = 0) will 412 # cause the lpfc driver to use an inverted table, effectively 413 # scanning ALPAs from high to low. Value range is [0,1]. Default value is 1. 414 # 415 # (Note: This "select ID" functionality is a LOOP ONLY characteristic 416 # and will not work across a fabric. Also this parameter will take 417 # effect only in the case when ALPA map is not available.) 418 */ 419 LPFC_ATTR_R(scan_down, 1, 0, 1, 420 "Start scanning for devices from highest ALPA to lowest"); 421 422 /* 423 # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear 424 # until the timer expires. Value range is [0,255]. Default value is 20. 425 # NOTE: this MUST be less then the SCSI Layer command timeout - 1. 426 */ 427 LPFC_ATTR_RW(nodev_tmo, 30, 0, 255, 428 "Seconds driver will hold I/O waiting for a device to come back"); 429 430 /* 431 # lpfc_topology: link topology for init link 432 # 0x0 = attempt loop mode then point-to-point 433 # 0x02 = attempt point-to-point mode only 434 # 0x04 = attempt loop mode only 435 # 0x06 = attempt point-to-point mode then loop 436 # Set point-to-point mode if you want to run as an N_Port. 437 # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. 438 # Default value is 0. 439 */ 440 LPFC_ATTR_R(topology, 0, 0, 6, "Select Fibre Channel topology"); 441 442 /* 443 # lpfc_link_speed: Link speed selection for initializing the Fibre Channel 444 # connection. 445 # 0 = auto select (default) 446 # 1 = 1 Gigabaud 447 # 2 = 2 Gigabaud 448 # 4 = 4 Gigabaud 449 # Value range is [0,4]. Default value is 0. 450 */ 451 LPFC_ATTR_R(link_speed, 0, 0, 4, "Select link speed"); 452 453 /* 454 # lpfc_fcp_class: Determines FC class to use for the FCP protocol. 455 # Value range is [2,3]. Default value is 3. 456 */ 457 LPFC_ATTR_R(fcp_class, 3, 2, 3, 458 "Select Fibre Channel class of service for FCP sequences"); 459 460 /* 461 # lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range 462 # is [0,1]. Default value is 0. 463 */ 464 LPFC_ATTR_RW(use_adisc, 0, 0, 1, 465 "Use ADISC on rediscovery to authenticate FCP devices"); 466 467 /* 468 # lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value 469 # range is [0,1]. Default value is 0. 470 */ 471 LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support"); 472 473 /* 474 # lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing 475 # cr_delay (msec) or cr_count outstanding commands. cr_delay can take 476 # value [0,63]. cr_count can take value [0,255]. Default value of cr_delay 477 # is 0. Default value of cr_count is 1. The cr_count feature is disabled if 478 # cr_delay is set to 0. 479 */ 480 static int lpfc_cr_delay = 0; 481 module_param(lpfc_cr_delay, int , 0); 482 MODULE_PARM_DESC(lpfc_cr_delay, "A count of milliseconds after which an " 483 "interrupt response is generated"); 484 485 static int lpfc_cr_count = 1; 486 module_param(lpfc_cr_count, int, 0); 487 MODULE_PARM_DESC(lpfc_cr_count, "A count of I/O completions after which an " 488 "interrupt response is generated"); 489 490 /* 491 # lpfc_fdmi_on: controls FDMI support. 492 # 0 = no FDMI support 493 # 1 = support FDMI without attribute of hostname 494 # 2 = support FDMI with attribute of hostname 495 # Value range [0,2]. Default value is 0. 496 */ 497 LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support"); 498 499 /* 500 # Specifies the maximum number of ELS cmds we can have outstanding (for 501 # discovery). Value range is [1,64]. Default value = 32. 502 */ 503 static int lpfc_discovery_threads = 32; 504 module_param(lpfc_discovery_threads, int, 0); 505 MODULE_PARM_DESC(lpfc_discovery_threads, "Maximum number of ELS commands " 506 "during discovery"); 507 508 /* 509 # lpfc_max_luns: maximum number of LUNs per target driver will support 510 # Value range is [1,32768]. Default value is 256. 511 # NOTE: The SCSI layer will scan each target for this many luns 512 */ 513 LPFC_ATTR_R(max_luns, 256, 1, 32768, 514 "Maximum number of LUNs per target driver will support"); 515 516 struct class_device_attribute *lpfc_host_attrs[] = { 517 &class_device_attr_info, 518 &class_device_attr_serialnum, 519 &class_device_attr_modeldesc, 520 &class_device_attr_modelname, 521 &class_device_attr_programtype, 522 &class_device_attr_portnum, 523 &class_device_attr_fwrev, 524 &class_device_attr_hdw, 525 &class_device_attr_option_rom_version, 526 &class_device_attr_state, 527 &class_device_attr_num_discovered_ports, 528 &class_device_attr_lpfc_drvr_version, 529 &class_device_attr_lpfc_log_verbose, 530 &class_device_attr_lpfc_lun_queue_depth, 531 &class_device_attr_lpfc_nodev_tmo, 532 &class_device_attr_lpfc_fcp_class, 533 &class_device_attr_lpfc_use_adisc, 534 &class_device_attr_lpfc_ack0, 535 &class_device_attr_lpfc_topology, 536 &class_device_attr_lpfc_scan_down, 537 &class_device_attr_lpfc_link_speed, 538 &class_device_attr_lpfc_fdmi_on, 539 &class_device_attr_lpfc_max_luns, 540 &class_device_attr_nport_evt_cnt, 541 &class_device_attr_management_version, 542 &class_device_attr_issue_lip, 543 &class_device_attr_board_online, 544 NULL, 545 }; 546 547 static ssize_t 548 sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) 549 { 550 size_t buf_off; 551 struct Scsi_Host *host = class_to_shost(container_of(kobj, 552 struct class_device, kobj)); 553 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 554 555 if ((off + count) > FF_REG_AREA_SIZE) 556 return -ERANGE; 557 558 if (count == 0) return 0; 559 560 if (off % 4 || count % 4 || (unsigned long)buf % 4) 561 return -EINVAL; 562 563 spin_lock_irq(phba->host->host_lock); 564 565 if (!(phba->fc_flag & FC_OFFLINE_MODE)) { 566 spin_unlock_irq(phba->host->host_lock); 567 return -EPERM; 568 } 569 570 for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) 571 writel(*((uint32_t *)(buf + buf_off)), 572 phba->ctrl_regs_memmap_p + off + buf_off); 573 574 spin_unlock_irq(phba->host->host_lock); 575 576 return count; 577 } 578 579 static ssize_t 580 sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) 581 { 582 size_t buf_off; 583 uint32_t * tmp_ptr; 584 struct Scsi_Host *host = class_to_shost(container_of(kobj, 585 struct class_device, kobj)); 586 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 587 588 if (off > FF_REG_AREA_SIZE) 589 return -ERANGE; 590 591 if ((off + count) > FF_REG_AREA_SIZE) 592 count = FF_REG_AREA_SIZE - off; 593 594 if (count == 0) return 0; 595 596 if (off % 4 || count % 4 || (unsigned long)buf % 4) 597 return -EINVAL; 598 599 spin_lock_irq(phba->host->host_lock); 600 601 for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) { 602 tmp_ptr = (uint32_t *)(buf + buf_off); 603 *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off); 604 } 605 606 spin_unlock_irq(phba->host->host_lock); 607 608 return count; 609 } 610 611 static struct bin_attribute sysfs_ctlreg_attr = { 612 .attr = { 613 .name = "ctlreg", 614 .mode = S_IRUSR | S_IWUSR, 615 .owner = THIS_MODULE, 616 }, 617 .size = 256, 618 .read = sysfs_ctlreg_read, 619 .write = sysfs_ctlreg_write, 620 }; 621 622 623 static void 624 sysfs_mbox_idle (struct lpfc_hba * phba) 625 { 626 phba->sysfs_mbox.state = SMBOX_IDLE; 627 phba->sysfs_mbox.offset = 0; 628 629 if (phba->sysfs_mbox.mbox) { 630 mempool_free(phba->sysfs_mbox.mbox, 631 phba->mbox_mem_pool); 632 phba->sysfs_mbox.mbox = NULL; 633 } 634 } 635 636 static ssize_t 637 sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) 638 { 639 struct Scsi_Host * host = 640 class_to_shost(container_of(kobj, struct class_device, kobj)); 641 struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata[0]; 642 struct lpfcMboxq * mbox = NULL; 643 644 if ((count + off) > MAILBOX_CMD_SIZE) 645 return -ERANGE; 646 647 if (off % 4 || count % 4 || (unsigned long)buf % 4) 648 return -EINVAL; 649 650 if (count == 0) 651 return 0; 652 653 if (off == 0) { 654 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 655 if (!mbox) 656 return -ENOMEM; 657 658 } 659 660 spin_lock_irq(host->host_lock); 661 662 if (off == 0) { 663 if (phba->sysfs_mbox.mbox) 664 mempool_free(mbox, phba->mbox_mem_pool); 665 else 666 phba->sysfs_mbox.mbox = mbox; 667 phba->sysfs_mbox.state = SMBOX_WRITING; 668 } else { 669 if (phba->sysfs_mbox.state != SMBOX_WRITING || 670 phba->sysfs_mbox.offset != off || 671 phba->sysfs_mbox.mbox == NULL ) { 672 sysfs_mbox_idle(phba); 673 spin_unlock_irq(host->host_lock); 674 return -EINVAL; 675 } 676 } 677 678 memcpy((uint8_t *) & phba->sysfs_mbox.mbox->mb + off, 679 buf, count); 680 681 phba->sysfs_mbox.offset = off + count; 682 683 spin_unlock_irq(host->host_lock); 684 685 return count; 686 } 687 688 static ssize_t 689 sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) 690 { 691 struct Scsi_Host *host = 692 class_to_shost(container_of(kobj, struct class_device, 693 kobj)); 694 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 695 int rc; 696 697 if (off > sizeof(MAILBOX_t)) 698 return -ERANGE; 699 700 if ((count + off) > sizeof(MAILBOX_t)) 701 count = sizeof(MAILBOX_t) - off; 702 703 if (off % 4 || count % 4 || (unsigned long)buf % 4) 704 return -EINVAL; 705 706 if (off && count == 0) 707 return 0; 708 709 spin_lock_irq(phba->host->host_lock); 710 711 if (off == 0 && 712 phba->sysfs_mbox.state == SMBOX_WRITING && 713 phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) { 714 715 switch (phba->sysfs_mbox.mbox->mb.mbxCommand) { 716 /* Offline only */ 717 case MBX_WRITE_NV: 718 case MBX_INIT_LINK: 719 case MBX_DOWN_LINK: 720 case MBX_CONFIG_LINK: 721 case MBX_CONFIG_RING: 722 case MBX_RESET_RING: 723 case MBX_UNREG_LOGIN: 724 case MBX_CLEAR_LA: 725 case MBX_DUMP_CONTEXT: 726 case MBX_RUN_DIAGS: 727 case MBX_RESTART: 728 case MBX_FLASH_WR_ULA: 729 case MBX_SET_MASK: 730 case MBX_SET_SLIM: 731 case MBX_SET_DEBUG: 732 if (!(phba->fc_flag & FC_OFFLINE_MODE)) { 733 printk(KERN_WARNING "mbox_read:Command 0x%x " 734 "is illegal in on-line state\n", 735 phba->sysfs_mbox.mbox->mb.mbxCommand); 736 sysfs_mbox_idle(phba); 737 spin_unlock_irq(phba->host->host_lock); 738 return -EPERM; 739 } 740 case MBX_LOAD_SM: 741 case MBX_READ_NV: 742 case MBX_READ_CONFIG: 743 case MBX_READ_RCONFIG: 744 case MBX_READ_STATUS: 745 case MBX_READ_XRI: 746 case MBX_READ_REV: 747 case MBX_READ_LNK_STAT: 748 case MBX_DUMP_MEMORY: 749 case MBX_DOWN_LOAD: 750 case MBX_UPDATE_CFG: 751 case MBX_LOAD_AREA: 752 case MBX_LOAD_EXP_ROM: 753 break; 754 case MBX_READ_SPARM64: 755 case MBX_READ_LA: 756 case MBX_READ_LA64: 757 case MBX_REG_LOGIN: 758 case MBX_REG_LOGIN64: 759 case MBX_CONFIG_PORT: 760 case MBX_RUN_BIU_DIAG: 761 printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n", 762 phba->sysfs_mbox.mbox->mb.mbxCommand); 763 sysfs_mbox_idle(phba); 764 spin_unlock_irq(phba->host->host_lock); 765 return -EPERM; 766 default: 767 printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n", 768 phba->sysfs_mbox.mbox->mb.mbxCommand); 769 sysfs_mbox_idle(phba); 770 spin_unlock_irq(phba->host->host_lock); 771 return -EPERM; 772 } 773 774 if ((phba->fc_flag & FC_OFFLINE_MODE) || 775 (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){ 776 777 spin_unlock_irq(phba->host->host_lock); 778 rc = lpfc_sli_issue_mbox (phba, 779 phba->sysfs_mbox.mbox, 780 MBX_POLL); 781 spin_lock_irq(phba->host->host_lock); 782 783 } else { 784 spin_unlock_irq(phba->host->host_lock); 785 rc = lpfc_sli_issue_mbox_wait (phba, 786 phba->sysfs_mbox.mbox, 787 phba->fc_ratov * 2); 788 spin_lock_irq(phba->host->host_lock); 789 } 790 791 if (rc != MBX_SUCCESS) { 792 sysfs_mbox_idle(phba); 793 spin_unlock_irq(host->host_lock); 794 return -ENODEV; 795 } 796 phba->sysfs_mbox.state = SMBOX_READING; 797 } 798 else if (phba->sysfs_mbox.offset != off || 799 phba->sysfs_mbox.state != SMBOX_READING) { 800 printk(KERN_WARNING "mbox_read: Bad State\n"); 801 sysfs_mbox_idle(phba); 802 spin_unlock_irq(host->host_lock); 803 return -EINVAL; 804 } 805 806 memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count); 807 808 phba->sysfs_mbox.offset = off + count; 809 810 if (phba->sysfs_mbox.offset == sizeof(MAILBOX_t)) 811 sysfs_mbox_idle(phba); 812 813 spin_unlock_irq(phba->host->host_lock); 814 815 return count; 816 } 817 818 static struct bin_attribute sysfs_mbox_attr = { 819 .attr = { 820 .name = "mbox", 821 .mode = S_IRUSR | S_IWUSR, 822 .owner = THIS_MODULE, 823 }, 824 .size = sizeof(MAILBOX_t), 825 .read = sysfs_mbox_read, 826 .write = sysfs_mbox_write, 827 }; 828 829 int 830 lpfc_alloc_sysfs_attr(struct lpfc_hba *phba) 831 { 832 struct Scsi_Host *host = phba->host; 833 int error; 834 835 error = sysfs_create_bin_file(&host->shost_classdev.kobj, 836 &sysfs_ctlreg_attr); 837 if (error) 838 goto out; 839 840 error = sysfs_create_bin_file(&host->shost_classdev.kobj, 841 &sysfs_mbox_attr); 842 if (error) 843 goto out_remove_ctlreg_attr; 844 845 return 0; 846 out_remove_ctlreg_attr: 847 sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr); 848 out: 849 return error; 850 } 851 852 void 853 lpfc_free_sysfs_attr(struct lpfc_hba *phba) 854 { 855 struct Scsi_Host *host = phba->host; 856 857 sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_mbox_attr); 858 sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr); 859 } 860 861 862 /* 863 * Dynamic FC Host Attributes Support 864 */ 865 866 static void 867 lpfc_get_host_port_id(struct Scsi_Host *shost) 868 { 869 struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; 870 /* note: fc_myDID already in cpu endianness */ 871 fc_host_port_id(shost) = phba->fc_myDID; 872 } 873 874 static void 875 lpfc_get_host_port_type(struct Scsi_Host *shost) 876 { 877 struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; 878 879 spin_lock_irq(shost->host_lock); 880 881 if (phba->hba_state == LPFC_HBA_READY) { 882 if (phba->fc_topology == TOPOLOGY_LOOP) { 883 if (phba->fc_flag & FC_PUBLIC_LOOP) 884 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; 885 else 886 fc_host_port_type(shost) = FC_PORTTYPE_LPORT; 887 } else { 888 if (phba->fc_flag & FC_FABRIC) 889 fc_host_port_type(shost) = FC_PORTTYPE_NPORT; 890 else 891 fc_host_port_type(shost) = FC_PORTTYPE_PTP; 892 } 893 } else 894 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; 895 896 spin_unlock_irq(shost->host_lock); 897 } 898 899 static void 900 lpfc_get_host_port_state(struct Scsi_Host *shost) 901 { 902 struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; 903 904 spin_lock_irq(shost->host_lock); 905 906 if (phba->fc_flag & FC_OFFLINE_MODE) 907 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; 908 else { 909 switch (phba->hba_state) { 910 case LPFC_INIT_START: 911 case LPFC_INIT_MBX_CMDS: 912 case LPFC_LINK_DOWN: 913 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; 914 break; 915 case LPFC_LINK_UP: 916 case LPFC_LOCAL_CFG_LINK: 917 case LPFC_FLOGI: 918 case LPFC_FABRIC_CFG_LINK: 919 case LPFC_NS_REG: 920 case LPFC_NS_QRY: 921 case LPFC_BUILD_DISC_LIST: 922 case LPFC_DISC_AUTH: 923 case LPFC_CLEAR_LA: 924 case LPFC_HBA_READY: 925 /* Links up, beyond this port_type reports state */ 926 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; 927 break; 928 case LPFC_HBA_ERROR: 929 fc_host_port_state(shost) = FC_PORTSTATE_ERROR; 930 break; 931 default: 932 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; 933 break; 934 } 935 } 936 937 spin_unlock_irq(shost->host_lock); 938 } 939 940 static void 941 lpfc_get_host_speed(struct Scsi_Host *shost) 942 { 943 struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; 944 945 spin_lock_irq(shost->host_lock); 946 947 if (phba->hba_state == LPFC_HBA_READY) { 948 switch(phba->fc_linkspeed) { 949 case LA_1GHZ_LINK: 950 fc_host_speed(shost) = FC_PORTSPEED_1GBIT; 951 break; 952 case LA_2GHZ_LINK: 953 fc_host_speed(shost) = FC_PORTSPEED_2GBIT; 954 break; 955 case LA_4GHZ_LINK: 956 fc_host_speed(shost) = FC_PORTSPEED_4GBIT; 957 break; 958 default: 959 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; 960 break; 961 } 962 } 963 964 spin_unlock_irq(shost->host_lock); 965 } 966 967 static void 968 lpfc_get_host_fabric_name (struct Scsi_Host *shost) 969 { 970 struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; 971 u64 nodename; 972 973 spin_lock_irq(shost->host_lock); 974 975 if ((phba->fc_flag & FC_FABRIC) || 976 ((phba->fc_topology == TOPOLOGY_LOOP) && 977 (phba->fc_flag & FC_PUBLIC_LOOP))) 978 memcpy(&nodename, &phba->fc_fabparam.nodeName, sizeof(u64)); 979 else 980 /* fabric is local port if there is no F/FL_Port */ 981 memcpy(&nodename, &phba->fc_nodename, sizeof(u64)); 982 983 spin_unlock_irq(shost->host_lock); 984 985 fc_host_fabric_name(shost) = be64_to_cpu(nodename); 986 } 987 988 989 static struct fc_host_statistics * 990 lpfc_get_stats(struct Scsi_Host *shost) 991 { 992 struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; 993 struct lpfc_sli *psli = &phba->sli; 994 struct fc_host_statistics *hs = 995 (struct fc_host_statistics *)phba->link_stats; 996 LPFC_MBOXQ_t *pmboxq; 997 MAILBOX_t *pmb; 998 int rc=0; 999 1000 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 1001 if (!pmboxq) 1002 return NULL; 1003 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); 1004 1005 pmb = &pmboxq->mb; 1006 pmb->mbxCommand = MBX_READ_STATUS; 1007 pmb->mbxOwner = OWN_HOST; 1008 pmboxq->context1 = NULL; 1009 1010 if ((phba->fc_flag & FC_OFFLINE_MODE) || 1011 (!(psli->sli_flag & LPFC_SLI2_ACTIVE))){ 1012 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); 1013 } else 1014 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 1015 1016 if (rc != MBX_SUCCESS) { 1017 if (pmboxq) { 1018 if (rc == MBX_TIMEOUT) 1019 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 1020 else 1021 mempool_free( pmboxq, phba->mbox_mem_pool); 1022 } 1023 return NULL; 1024 } 1025 1026 hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt; 1027 hs->tx_words = (pmb->un.varRdStatus.xmitByteCnt * 256); 1028 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt; 1029 hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256); 1030 1031 memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); 1032 pmb->mbxCommand = MBX_READ_LNK_STAT; 1033 pmb->mbxOwner = OWN_HOST; 1034 pmboxq->context1 = NULL; 1035 1036 if ((phba->fc_flag & FC_OFFLINE_MODE) || 1037 (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) { 1038 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); 1039 } else 1040 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 1041 1042 if (rc != MBX_SUCCESS) { 1043 if (pmboxq) { 1044 if (rc == MBX_TIMEOUT) 1045 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 1046 else 1047 mempool_free( pmboxq, phba->mbox_mem_pool); 1048 } 1049 return NULL; 1050 } 1051 1052 hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; 1053 hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt; 1054 hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt; 1055 hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt; 1056 hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord; 1057 hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt; 1058 hs->error_frames = pmb->un.varRdLnk.crcCnt; 1059 1060 if (phba->fc_topology == TOPOLOGY_LOOP) { 1061 hs->lip_count = (phba->fc_eventTag >> 1); 1062 hs->nos_count = -1; 1063 } else { 1064 hs->lip_count = -1; 1065 hs->nos_count = (phba->fc_eventTag >> 1); 1066 } 1067 1068 hs->dumped_frames = -1; 1069 1070 /* FIX ME */ 1071 /*hs->SecondsSinceLastReset = (jiffies - lpfc_loadtime) / HZ;*/ 1072 1073 return hs; 1074 } 1075 1076 1077 /* 1078 * The LPFC driver treats linkdown handling as target loss events so there 1079 * are no sysfs handlers for link_down_tmo. 1080 */ 1081 static void 1082 lpfc_get_starget_port_id(struct scsi_target *starget) 1083 { 1084 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 1085 struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; 1086 uint32_t did = -1; 1087 struct lpfc_nodelist *ndlp = NULL; 1088 1089 spin_lock_irq(shost->host_lock); 1090 /* Search the mapped list for this target ID */ 1091 list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { 1092 if (starget->id == ndlp->nlp_sid) { 1093 did = ndlp->nlp_DID; 1094 break; 1095 } 1096 } 1097 spin_unlock_irq(shost->host_lock); 1098 1099 fc_starget_port_id(starget) = did; 1100 } 1101 1102 static void 1103 lpfc_get_starget_node_name(struct scsi_target *starget) 1104 { 1105 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 1106 struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; 1107 uint64_t node_name = 0; 1108 struct lpfc_nodelist *ndlp = NULL; 1109 1110 spin_lock_irq(shost->host_lock); 1111 /* Search the mapped list for this target ID */ 1112 list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { 1113 if (starget->id == ndlp->nlp_sid) { 1114 memcpy(&node_name, &ndlp->nlp_nodename, 1115 sizeof(struct lpfc_name)); 1116 break; 1117 } 1118 } 1119 spin_unlock_irq(shost->host_lock); 1120 1121 fc_starget_node_name(starget) = be64_to_cpu(node_name); 1122 } 1123 1124 static void 1125 lpfc_get_starget_port_name(struct scsi_target *starget) 1126 { 1127 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 1128 struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; 1129 uint64_t port_name = 0; 1130 struct lpfc_nodelist *ndlp = NULL; 1131 1132 spin_lock_irq(shost->host_lock); 1133 /* Search the mapped list for this target ID */ 1134 list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { 1135 if (starget->id == ndlp->nlp_sid) { 1136 memcpy(&port_name, &ndlp->nlp_portname, 1137 sizeof(struct lpfc_name)); 1138 break; 1139 } 1140 } 1141 spin_unlock_irq(shost->host_lock); 1142 1143 fc_starget_port_name(starget) = be64_to_cpu(port_name); 1144 } 1145 1146 static void 1147 lpfc_get_rport_loss_tmo(struct fc_rport *rport) 1148 { 1149 /* 1150 * Return the driver's global value for device loss timeout plus 1151 * five seconds to allow the driver's nodev timer to run. 1152 */ 1153 rport->dev_loss_tmo = lpfc_nodev_tmo + 5; 1154 } 1155 1156 static void 1157 lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) 1158 { 1159 /* 1160 * The driver doesn't have a per-target timeout setting. Set 1161 * this value globally. lpfc_nodev_tmo should be greater then 0. 1162 */ 1163 if (timeout) 1164 lpfc_nodev_tmo = timeout; 1165 else 1166 lpfc_nodev_tmo = 1; 1167 rport->dev_loss_tmo = lpfc_nodev_tmo + 5; 1168 } 1169 1170 1171 #define lpfc_rport_show_function(field, format_string, sz, cast) \ 1172 static ssize_t \ 1173 lpfc_show_rport_##field (struct class_device *cdev, char *buf) \ 1174 { \ 1175 struct fc_rport *rport = transport_class_to_rport(cdev); \ 1176 struct lpfc_rport_data *rdata = rport->hostdata; \ 1177 return snprintf(buf, sz, format_string, \ 1178 (rdata->target) ? cast rdata->target->field : 0); \ 1179 } 1180 1181 #define lpfc_rport_rd_attr(field, format_string, sz) \ 1182 lpfc_rport_show_function(field, format_string, sz, ) \ 1183 static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL) 1184 1185 1186 struct fc_function_template lpfc_transport_functions = { 1187 /* fixed attributes the driver supports */ 1188 .show_host_node_name = 1, 1189 .show_host_port_name = 1, 1190 .show_host_supported_classes = 1, 1191 .show_host_supported_fc4s = 1, 1192 .show_host_symbolic_name = 1, 1193 .show_host_supported_speeds = 1, 1194 .show_host_maxframe_size = 1, 1195 1196 /* dynamic attributes the driver supports */ 1197 .get_host_port_id = lpfc_get_host_port_id, 1198 .show_host_port_id = 1, 1199 1200 .get_host_port_type = lpfc_get_host_port_type, 1201 .show_host_port_type = 1, 1202 1203 .get_host_port_state = lpfc_get_host_port_state, 1204 .show_host_port_state = 1, 1205 1206 /* active_fc4s is shown but doesn't change (thus no get function) */ 1207 .show_host_active_fc4s = 1, 1208 1209 .get_host_speed = lpfc_get_host_speed, 1210 .show_host_speed = 1, 1211 1212 .get_host_fabric_name = lpfc_get_host_fabric_name, 1213 .show_host_fabric_name = 1, 1214 1215 /* 1216 * The LPFC driver treats linkdown handling as target loss events 1217 * so there are no sysfs handlers for link_down_tmo. 1218 */ 1219 1220 .get_fc_host_stats = lpfc_get_stats, 1221 1222 /* the LPFC driver doesn't support resetting stats yet */ 1223 1224 .dd_fcrport_size = sizeof(struct lpfc_rport_data), 1225 .show_rport_maxframe_size = 1, 1226 .show_rport_supported_classes = 1, 1227 1228 .get_rport_dev_loss_tmo = lpfc_get_rport_loss_tmo, 1229 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo, 1230 .show_rport_dev_loss_tmo = 1, 1231 1232 .get_starget_port_id = lpfc_get_starget_port_id, 1233 .show_starget_port_id = 1, 1234 1235 .get_starget_node_name = lpfc_get_starget_node_name, 1236 .show_starget_node_name = 1, 1237 1238 .get_starget_port_name = lpfc_get_starget_port_name, 1239 .show_starget_port_name = 1, 1240 }; 1241 1242 void 1243 lpfc_get_cfgparam(struct lpfc_hba *phba) 1244 { 1245 phba->cfg_log_verbose = lpfc_log_verbose; 1246 phba->cfg_cr_delay = lpfc_cr_delay; 1247 phba->cfg_cr_count = lpfc_cr_count; 1248 phba->cfg_lun_queue_depth = lpfc_lun_queue_depth; 1249 phba->cfg_fcp_class = lpfc_fcp_class; 1250 phba->cfg_use_adisc = lpfc_use_adisc; 1251 phba->cfg_ack0 = lpfc_ack0; 1252 phba->cfg_topology = lpfc_topology; 1253 phba->cfg_scan_down = lpfc_scan_down; 1254 phba->cfg_nodev_tmo = lpfc_nodev_tmo; 1255 phba->cfg_link_speed = lpfc_link_speed; 1256 phba->cfg_fdmi_on = lpfc_fdmi_on; 1257 phba->cfg_discovery_threads = lpfc_discovery_threads; 1258 phba->cfg_max_luns = lpfc_max_luns; 1259 1260 /* 1261 * The total number of segments is the configuration value plus 2 1262 * since the IOCB need a command and response bde. 1263 */ 1264 phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2; 1265 1266 /* 1267 * Since the sg_tablesize is module parameter, the sg_dma_buf_size 1268 * used to create the sg_dma_buf_pool must be dynamically calculated 1269 */ 1270 phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + 1271 sizeof(struct fcp_rsp) + 1272 (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64)); 1273 1274 switch (phba->pcidev->device) { 1275 case PCI_DEVICE_ID_LP101: 1276 case PCI_DEVICE_ID_BSMB: 1277 case PCI_DEVICE_ID_ZSMB: 1278 phba->cfg_hba_queue_depth = LPFC_LP101_HBA_Q_DEPTH; 1279 break; 1280 case PCI_DEVICE_ID_RFLY: 1281 case PCI_DEVICE_ID_PFLY: 1282 case PCI_DEVICE_ID_BMID: 1283 case PCI_DEVICE_ID_ZMID: 1284 case PCI_DEVICE_ID_TFLY: 1285 phba->cfg_hba_queue_depth = LPFC_LC_HBA_Q_DEPTH; 1286 break; 1287 default: 1288 phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH; 1289 } 1290 return; 1291 } 1292