diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-06-17 20:56:38 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-06-17 23:27:39 -0400 |
commit | 92d7f7b0cde3ad2260e7462b40867b57efd49851 (patch) | |
tree | fadb1d8f1a817c2f85937b5e9c3b830bdecb5555 /drivers/scsi/lpfc/lpfc_attr.c | |
parent | ed957684294618602b48f1950b0c9bbcb036583f (diff) |
[SCSI] lpfc: NPIV: add NPIV support on top of SLI-3
NPIV support is added to the driver. It utilizes the interfaces of
the fc transport for the creation and deletion of vports. Within the
driver, a new Scsi_Host is created for each NPIV instance, and is
paired with a new instance of a FC port. This allows N FC Port
elements to share a single Adapter.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_attr.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 308 |
1 files changed, 295 insertions, 13 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b8adff8cea6a..5cb7924fe3d7 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "lpfc_version.h" | 39 | #include "lpfc_version.h" |
40 | #include "lpfc_compat.h" | 40 | #include "lpfc_compat.h" |
41 | #include "lpfc_crtn.h" | 41 | #include "lpfc_crtn.h" |
42 | #include "lpfc_vport.h" | ||
42 | 43 | ||
43 | #define LPFC_DEF_DEVLOSS_TMO 30 | 44 | #define LPFC_DEF_DEVLOSS_TMO 30 |
44 | #define LPFC_MIN_DEVLOSS_TMO 1 | 45 | #define LPFC_MIN_DEVLOSS_TMO 1 |
@@ -139,7 +140,7 @@ lpfc_fwrev_show(struct class_device *cdev, char *buf) | |||
139 | char fwrev[32]; | 140 | char fwrev[32]; |
140 | 141 | ||
141 | lpfc_decode_firmware_rev(phba, fwrev, 1); | 142 | lpfc_decode_firmware_rev(phba, fwrev, 1); |
142 | return snprintf(buf, PAGE_SIZE, "%s\n",fwrev); | 143 | return snprintf(buf, PAGE_SIZE, "%s, sli-%d\n", fwrev, phba->sli_rev); |
143 | } | 144 | } |
144 | 145 | ||
145 | static ssize_t | 146 | static ssize_t |
@@ -178,10 +179,11 @@ lpfc_state_show(struct class_device *cdev, char *buf) | |||
178 | case LPFC_INIT_MBX_CMDS: | 179 | case LPFC_INIT_MBX_CMDS: |
179 | case LPFC_LINK_DOWN: | 180 | case LPFC_LINK_DOWN: |
180 | case LPFC_HBA_ERROR: | 181 | case LPFC_HBA_ERROR: |
181 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Down"); | 182 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n"); |
182 | break; | 183 | break; |
183 | case LPFC_LINK_UP: | 184 | case LPFC_LINK_UP: |
184 | case LPFC_CLEAR_LA: | 185 | case LPFC_CLEAR_LA: |
186 | case LPFC_HBA_READY: | ||
185 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - \n"); | 187 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - \n"); |
186 | 188 | ||
187 | switch (vport->port_state) { | 189 | switch (vport->port_state) { |
@@ -190,8 +192,9 @@ lpfc_state_show(struct class_device *cdev, char *buf) | |||
190 | break; | 192 | break; |
191 | case LPFC_LOCAL_CFG_LINK: | 193 | case LPFC_LOCAL_CFG_LINK: |
192 | len += snprintf(buf + len, PAGE_SIZE-len, | 194 | len += snprintf(buf + len, PAGE_SIZE-len, |
193 | "configuring\n"); | 195 | "Configuring Link\n"); |
194 | break; | 196 | break; |
197 | case LPFC_FDISC: | ||
195 | case LPFC_FLOGI: | 198 | case LPFC_FLOGI: |
196 | case LPFC_FABRIC_CFG_LINK: | 199 | case LPFC_FABRIC_CFG_LINK: |
197 | case LPFC_NS_REG: | 200 | case LPFC_NS_REG: |
@@ -205,7 +208,11 @@ lpfc_state_show(struct class_device *cdev, char *buf) | |||
205 | len += snprintf(buf + len, PAGE_SIZE - len, "Ready\n"); | 208 | len += snprintf(buf + len, PAGE_SIZE - len, "Ready\n"); |
206 | break; | 209 | break; |
207 | 210 | ||
208 | case LPFC_STATE_UNKNOWN: | 211 | case LPFC_VPORT_FAILED: |
212 | len += snprintf(buf + len, PAGE_SIZE - len, "Failed\n"); | ||
213 | break; | ||
214 | |||
215 | case LPFC_VPORT_UNKNOWN: | ||
209 | len += snprintf(buf + len, PAGE_SIZE - len, | 216 | len += snprintf(buf + len, PAGE_SIZE - len, |
210 | "Unknown\n"); | 217 | "Unknown\n"); |
211 | break; | 218 | break; |
@@ -433,6 +440,151 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) | |||
433 | } | 440 | } |
434 | 441 | ||
435 | static ssize_t | 442 | static ssize_t |
443 | lpfc_max_vpi_show(struct class_device *cdev, char *buf) | ||
444 | { | ||
445 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
446 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
447 | struct lpfc_hba *phba = vport->phba; | ||
448 | |||
449 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->max_vpi); | ||
450 | } | ||
451 | |||
452 | static ssize_t | ||
453 | lpfc_used_vpi_show(struct class_device *cdev, char *buf) | ||
454 | { | ||
455 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
456 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
457 | struct lpfc_hba *phba = vport->phba; | ||
458 | |||
459 | /* Don't count the physical port */ | ||
460 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->vpi_cnt-1); | ||
461 | } | ||
462 | |||
463 | int | ||
464 | lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri, | ||
465 | uint32_t *axri, uint32_t *mrpi, uint32_t *arpi) | ||
466 | { | ||
467 | struct lpfc_sli *psli = &phba->sli; | ||
468 | LPFC_MBOXQ_t *pmboxq; | ||
469 | MAILBOX_t *pmb; | ||
470 | int rc = 0; | ||
471 | |||
472 | /* | ||
473 | * prevent udev from issuing mailbox commands until the port is | ||
474 | * configured. | ||
475 | */ | ||
476 | if (phba->link_state < LPFC_LINK_DOWN || | ||
477 | !phba->mbox_mem_pool || | ||
478 | (phba->sli.sli_flag & LPFC_SLI2_ACTIVE) == 0) | ||
479 | return 0; | ||
480 | |||
481 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) | ||
482 | return 0; | ||
483 | |||
484 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
485 | if (!pmboxq) | ||
486 | return 0; | ||
487 | memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | ||
488 | |||
489 | pmb = &pmboxq->mb; | ||
490 | pmb->mbxCommand = MBX_READ_CONFIG; | ||
491 | pmb->mbxOwner = OWN_HOST; | ||
492 | pmboxq->context1 = NULL; | ||
493 | |||
494 | if ((phba->pport->fc_flag & FC_OFFLINE_MODE) || | ||
495 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | ||
496 | rc = MBX_NOT_FINISHED; | ||
497 | else | ||
498 | rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); | ||
499 | |||
500 | if (rc != MBX_SUCCESS) { | ||
501 | if (rc == MBX_TIMEOUT) | ||
502 | pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | ||
503 | else | ||
504 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | if (mrpi) | ||
509 | *mrpi = pmb->un.varRdConfig.max_rpi; | ||
510 | if (arpi) | ||
511 | *arpi = pmb->un.varRdConfig.avail_rpi; | ||
512 | if (mxri) | ||
513 | *mxri = pmb->un.varRdConfig.max_xri; | ||
514 | if (axri) | ||
515 | *axri = pmb->un.varRdConfig.avail_xri; | ||
516 | |||
517 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
518 | return 1; | ||
519 | } | ||
520 | |||
521 | static ssize_t | ||
522 | lpfc_max_rpi_show(struct class_device *cdev, char *buf) | ||
523 | { | ||
524 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
525 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
526 | struct lpfc_hba *phba = vport->phba; | ||
527 | uint32_t cnt; | ||
528 | |||
529 | if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL)) | ||
530 | return snprintf(buf, PAGE_SIZE, "%d\n", cnt); | ||
531 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | ||
532 | } | ||
533 | |||
534 | static ssize_t | ||
535 | lpfc_used_rpi_show(struct class_device *cdev, char *buf) | ||
536 | { | ||
537 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
538 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
539 | struct lpfc_hba *phba = vport->phba; | ||
540 | uint32_t cnt, acnt; | ||
541 | |||
542 | if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt)) | ||
543 | return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); | ||
544 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | ||
545 | } | ||
546 | |||
547 | static ssize_t | ||
548 | lpfc_max_xri_show(struct class_device *cdev, char *buf) | ||
549 | { | ||
550 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
551 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
552 | struct lpfc_hba *phba = vport->phba; | ||
553 | uint32_t cnt; | ||
554 | |||
555 | if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL)) | ||
556 | return snprintf(buf, PAGE_SIZE, "%d\n", cnt); | ||
557 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | ||
558 | } | ||
559 | |||
560 | static ssize_t | ||
561 | lpfc_used_xri_show(struct class_device *cdev, char *buf) | ||
562 | { | ||
563 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
564 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
565 | struct lpfc_hba *phba = vport->phba; | ||
566 | uint32_t cnt, acnt; | ||
567 | |||
568 | if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL)) | ||
569 | return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); | ||
570 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | ||
571 | } | ||
572 | |||
573 | static ssize_t | ||
574 | lpfc_npiv_info_show(struct class_device *cdev, char *buf) | ||
575 | { | ||
576 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
577 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
578 | struct lpfc_hba *phba = vport->phba; | ||
579 | |||
580 | if (!(phba->max_vpi)) | ||
581 | return snprintf(buf, PAGE_SIZE, "NPIV Not Supported\n"); | ||
582 | if (vport->port_type == LPFC_PHYSICAL_PORT) | ||
583 | return snprintf(buf, PAGE_SIZE, "NPIV Physical\n"); | ||
584 | return snprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi); | ||
585 | } | ||
586 | |||
587 | static ssize_t | ||
436 | lpfc_poll_show(struct class_device *cdev, char *buf) | 588 | lpfc_poll_show(struct class_device *cdev, char *buf) |
437 | { | 589 | { |
438 | struct Scsi_Host *shost = class_to_shost(cdev); | 590 | struct Scsi_Host *shost = class_to_shost(cdev); |
@@ -640,6 +792,13 @@ static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, | |||
640 | static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, | 792 | static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, |
641 | lpfc_board_mode_show, lpfc_board_mode_store); | 793 | lpfc_board_mode_show, lpfc_board_mode_store); |
642 | static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); | 794 | static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); |
795 | static CLASS_DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL); | ||
796 | static CLASS_DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL); | ||
797 | static CLASS_DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL); | ||
798 | static CLASS_DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL); | ||
799 | static CLASS_DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL); | ||
800 | static CLASS_DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL); | ||
801 | static CLASS_DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL); | ||
643 | 802 | ||
644 | 803 | ||
645 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; | 804 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; |
@@ -829,6 +988,17 @@ MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:" | |||
829 | static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR, | 988 | static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR, |
830 | lpfc_poll_show, lpfc_poll_store); | 989 | lpfc_poll_show, lpfc_poll_store); |
831 | 990 | ||
991 | int lpfc_sli_mode = 0; | ||
992 | module_param(lpfc_sli_mode, int, 0); | ||
993 | MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:" | ||
994 | " 0 - auto (SLI-3 if supported)," | ||
995 | " 2 - select SLI-2 even on SLI-3 capable HBAs," | ||
996 | " 3 - select SLI-3"); | ||
997 | |||
998 | int lpfc_npiv_enable = 0; | ||
999 | module_param(lpfc_npiv_enable, int, 0); | ||
1000 | MODULE_PARM_DESC(lpfc_npiv_enable, "Enable NPIV functionality"); | ||
1001 | |||
832 | /* | 1002 | /* |
833 | # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear | 1003 | # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear |
834 | # until the timer expires. Value range is [0,255]. Default value is 30. | 1004 | # until the timer expires. Value range is [0,255]. Default value is 30. |
@@ -985,6 +1155,33 @@ LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192, | |||
985 | "Max number of FCP commands we can queue to a lpfc HBA"); | 1155 | "Max number of FCP commands we can queue to a lpfc HBA"); |
986 | 1156 | ||
987 | /* | 1157 | /* |
1158 | # peer_port_login: This parameter allows/prevents logins | ||
1159 | # between peer ports hosted on the same physical port. | ||
1160 | # When this parameter is set 0 peer ports of same physical port | ||
1161 | # are not allowed to login to each other. | ||
1162 | # When this parameter is set 1 peer ports of same physical port | ||
1163 | # are allowed to login to each other. | ||
1164 | # Default value of this parameter is 0. | ||
1165 | */ | ||
1166 | LPFC_ATTR_R(peer_port_login, 0, 0, 1, | ||
1167 | "Allow peer ports on the same physical port to login to each " | ||
1168 | "other."); | ||
1169 | |||
1170 | /* | ||
1171 | # vport_restrict_login: This parameter allows/prevents logins | ||
1172 | # between Virtual Ports and remote initiators. | ||
1173 | # When this parameter is not set (0) Virtual Ports will accept PLOGIs from | ||
1174 | # other initiators and will attempt to PLOGI all remote ports. | ||
1175 | # When this parameter is set (1) Virtual Ports will reject PLOGIs from | ||
1176 | # remote ports and will not attempt to PLOGI to other initiators. | ||
1177 | # This parameter does not restrict to the physical port. | ||
1178 | # This parameter does not restrict logins to Fabric resident remote ports. | ||
1179 | # Default value of this parameter is 1. | ||
1180 | */ | ||
1181 | LPFC_ATTR_RW(vport_restrict_login, 1, 0, 1, | ||
1182 | "Restrict virtual ports login to remote initiators."); | ||
1183 | |||
1184 | /* | ||
988 | # Some disk devices have a "select ID" or "select Target" capability. | 1185 | # Some disk devices have a "select ID" or "select Target" capability. |
989 | # From a protocol standpoint "select ID" usually means select the | 1186 | # From a protocol standpoint "select ID" usually means select the |
990 | # Fibre channel "ALPA". In the FC-AL Profile there is an "informative | 1187 | # Fibre channel "ALPA". In the FC-AL Profile there is an "informative |
@@ -1127,6 +1324,7 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255, | |||
1127 | LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); | 1324 | LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); |
1128 | 1325 | ||
1129 | 1326 | ||
1327 | |||
1130 | struct class_device_attribute *lpfc_hba_attrs[] = { | 1328 | struct class_device_attribute *lpfc_hba_attrs[] = { |
1131 | &class_device_attr_info, | 1329 | &class_device_attr_info, |
1132 | &class_device_attr_serialnum, | 1330 | &class_device_attr_serialnum, |
@@ -1143,6 +1341,8 @@ struct class_device_attribute *lpfc_hba_attrs[] = { | |||
1143 | &class_device_attr_lpfc_log_verbose, | 1341 | &class_device_attr_lpfc_log_verbose, |
1144 | &class_device_attr_lpfc_lun_queue_depth, | 1342 | &class_device_attr_lpfc_lun_queue_depth, |
1145 | &class_device_attr_lpfc_hba_queue_depth, | 1343 | &class_device_attr_lpfc_hba_queue_depth, |
1344 | &class_device_attr_lpfc_peer_port_login, | ||
1345 | &class_device_attr_lpfc_vport_restrict_login, | ||
1146 | &class_device_attr_lpfc_nodev_tmo, | 1346 | &class_device_attr_lpfc_nodev_tmo, |
1147 | &class_device_attr_lpfc_devloss_tmo, | 1347 | &class_device_attr_lpfc_devloss_tmo, |
1148 | &class_device_attr_lpfc_fcp_class, | 1348 | &class_device_attr_lpfc_fcp_class, |
@@ -1161,6 +1361,13 @@ struct class_device_attribute *lpfc_hba_attrs[] = { | |||
1161 | &class_device_attr_nport_evt_cnt, | 1361 | &class_device_attr_nport_evt_cnt, |
1162 | &class_device_attr_management_version, | 1362 | &class_device_attr_management_version, |
1163 | &class_device_attr_board_mode, | 1363 | &class_device_attr_board_mode, |
1364 | &class_device_attr_max_vpi, | ||
1365 | &class_device_attr_used_vpi, | ||
1366 | &class_device_attr_max_rpi, | ||
1367 | &class_device_attr_used_rpi, | ||
1368 | &class_device_attr_max_xri, | ||
1369 | &class_device_attr_used_xri, | ||
1370 | &class_device_attr_npiv_info, | ||
1164 | &class_device_attr_issue_reset, | 1371 | &class_device_attr_issue_reset, |
1165 | &class_device_attr_lpfc_poll, | 1372 | &class_device_attr_lpfc_poll, |
1166 | &class_device_attr_lpfc_poll_tmo, | 1373 | &class_device_attr_lpfc_poll_tmo, |
@@ -1299,7 +1506,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1299 | } else { | 1506 | } else { |
1300 | if (phba->sysfs_mbox.state != SMBOX_WRITING || | 1507 | if (phba->sysfs_mbox.state != SMBOX_WRITING || |
1301 | phba->sysfs_mbox.offset != off || | 1508 | phba->sysfs_mbox.offset != off || |
1302 | phba->sysfs_mbox.mbox == NULL ) { | 1509 | phba->sysfs_mbox.mbox == NULL) { |
1303 | sysfs_mbox_idle(phba); | 1510 | sysfs_mbox_idle(phba); |
1304 | spin_unlock_irq(&phba->hbalock); | 1511 | spin_unlock_irq(&phba->hbalock); |
1305 | return -EAGAIN; | 1512 | return -EAGAIN; |
@@ -1406,6 +1613,8 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1406 | return -EPERM; | 1613 | return -EPERM; |
1407 | } | 1614 | } |
1408 | 1615 | ||
1616 | phba->sysfs_mbox.mbox->vport = vport; | ||
1617 | |||
1409 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | 1618 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { |
1410 | sysfs_mbox_idle(phba); | 1619 | sysfs_mbox_idle(phba); |
1411 | spin_unlock_irq(&phba->hbalock); | 1620 | spin_unlock_irq(&phba->hbalock); |
@@ -1480,12 +1689,12 @@ lpfc_alloc_sysfs_attr(struct lpfc_vport *vport) | |||
1480 | int error; | 1689 | int error; |
1481 | 1690 | ||
1482 | error = sysfs_create_bin_file(&shost->shost_classdev.kobj, | 1691 | error = sysfs_create_bin_file(&shost->shost_classdev.kobj, |
1483 | &sysfs_ctlreg_attr); | 1692 | &sysfs_ctlreg_attr); |
1484 | if (error) | 1693 | if (error) |
1485 | goto out; | 1694 | goto out; |
1486 | 1695 | ||
1487 | error = sysfs_create_bin_file(&shost->shost_classdev.kobj, | 1696 | error = sysfs_create_bin_file(&shost->shost_classdev.kobj, |
1488 | &sysfs_mbox_attr); | 1697 | &sysfs_mbox_attr); |
1489 | if (error) | 1698 | if (error) |
1490 | goto out_remove_ctlreg_attr; | 1699 | goto out_remove_ctlreg_attr; |
1491 | 1700 | ||
@@ -1527,7 +1736,9 @@ lpfc_get_host_port_type(struct Scsi_Host *shost) | |||
1527 | 1736 | ||
1528 | spin_lock_irq(shost->host_lock); | 1737 | spin_lock_irq(shost->host_lock); |
1529 | 1738 | ||
1530 | if (lpfc_is_link_up(phba)) { | 1739 | if (vport->port_type == LPFC_NPIV_PORT) { |
1740 | fc_host_port_type(shost) = FC_PORTTYPE_NPIV; | ||
1741 | } else if (lpfc_is_link_up(phba)) { | ||
1531 | if (phba->fc_topology == TOPOLOGY_LOOP) { | 1742 | if (phba->fc_topology == TOPOLOGY_LOOP) { |
1532 | if (vport->fc_flag & FC_PUBLIC_LOOP) | 1743 | if (vport->fc_flag & FC_PUBLIC_LOOP) |
1533 | fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; | 1744 | fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; |
@@ -1563,6 +1774,7 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) | |||
1563 | break; | 1774 | break; |
1564 | case LPFC_LINK_UP: | 1775 | case LPFC_LINK_UP: |
1565 | case LPFC_CLEAR_LA: | 1776 | case LPFC_CLEAR_LA: |
1777 | case LPFC_HBA_READY: | ||
1566 | /* Links up, beyond this port_type reports state */ | 1778 | /* Links up, beyond this port_type reports state */ |
1567 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; | 1779 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; |
1568 | break; | 1780 | break; |
@@ -1644,13 +1856,14 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1644 | unsigned long seconds; | 1856 | unsigned long seconds; |
1645 | int rc = 0; | 1857 | int rc = 0; |
1646 | 1858 | ||
1647 | /* prevent udev from issuing mailbox commands | 1859 | /* |
1648 | * until the port is configured. | 1860 | * prevent udev from issuing mailbox commands until the port is |
1649 | */ | 1861 | * configured. |
1862 | */ | ||
1650 | if (phba->link_state < LPFC_LINK_DOWN || | 1863 | if (phba->link_state < LPFC_LINK_DOWN || |
1651 | !phba->mbox_mem_pool || | 1864 | !phba->mbox_mem_pool || |
1652 | (phba->sli.sli_flag & LPFC_SLI2_ACTIVE) == 0) | 1865 | (phba->sli.sli_flag & LPFC_SLI2_ACTIVE) == 0) |
1653 | return NULL; | 1866 | return NULL; |
1654 | 1867 | ||
1655 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) | 1868 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) |
1656 | return NULL; | 1869 | return NULL; |
@@ -1664,6 +1877,7 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1664 | pmb->mbxCommand = MBX_READ_STATUS; | 1877 | pmb->mbxCommand = MBX_READ_STATUS; |
1665 | pmb->mbxOwner = OWN_HOST; | 1878 | pmb->mbxOwner = OWN_HOST; |
1666 | pmboxq->context1 = NULL; | 1879 | pmboxq->context1 = NULL; |
1880 | pmboxq->vport = vport; | ||
1667 | 1881 | ||
1668 | if ((vport->fc_flag & FC_OFFLINE_MODE) || | 1882 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
1669 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | 1883 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) |
@@ -1690,6 +1904,7 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1690 | pmb->mbxCommand = MBX_READ_LNK_STAT; | 1904 | pmb->mbxCommand = MBX_READ_LNK_STAT; |
1691 | pmb->mbxOwner = OWN_HOST; | 1905 | pmb->mbxOwner = OWN_HOST; |
1692 | pmboxq->context1 = NULL; | 1906 | pmboxq->context1 = NULL; |
1907 | pmboxq->vport = vport; | ||
1693 | 1908 | ||
1694 | if ((vport->fc_flag & FC_OFFLINE_MODE) || | 1909 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
1695 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | 1910 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) |
@@ -1701,7 +1916,7 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1701 | if (rc == MBX_TIMEOUT) | 1916 | if (rc == MBX_TIMEOUT) |
1702 | pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1917 | pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
1703 | else | 1918 | else |
1704 | mempool_free( pmboxq, phba->mbox_mem_pool); | 1919 | mempool_free(pmboxq, phba->mbox_mem_pool); |
1705 | return NULL; | 1920 | return NULL; |
1706 | } | 1921 | } |
1707 | 1922 | ||
@@ -1769,6 +1984,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) | |||
1769 | pmb->mbxOwner = OWN_HOST; | 1984 | pmb->mbxOwner = OWN_HOST; |
1770 | pmb->un.varWords[0] = 0x1; /* reset request */ | 1985 | pmb->un.varWords[0] = 0x1; /* reset request */ |
1771 | pmboxq->context1 = NULL; | 1986 | pmboxq->context1 = NULL; |
1987 | pmboxq->vport = vport; | ||
1772 | 1988 | ||
1773 | if ((vport->fc_flag & FC_OFFLINE_MODE) || | 1989 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
1774 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | 1990 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) |
@@ -1788,6 +2004,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) | |||
1788 | pmb->mbxCommand = MBX_READ_LNK_STAT; | 2004 | pmb->mbxCommand = MBX_READ_LNK_STAT; |
1789 | pmb->mbxOwner = OWN_HOST; | 2005 | pmb->mbxOwner = OWN_HOST; |
1790 | pmboxq->context1 = NULL; | 2006 | pmboxq->context1 = NULL; |
2007 | pmboxq->vport = vport; | ||
1791 | 2008 | ||
1792 | if ((vport->fc_flag & FC_OFFLINE_MODE) || | 2009 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
1793 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | 2010 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) |
@@ -1950,6 +2167,69 @@ struct fc_function_template lpfc_transport_functions = { | |||
1950 | .issue_fc_host_lip = lpfc_issue_lip, | 2167 | .issue_fc_host_lip = lpfc_issue_lip, |
1951 | .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk, | 2168 | .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk, |
1952 | .terminate_rport_io = lpfc_terminate_rport_io, | 2169 | .terminate_rport_io = lpfc_terminate_rport_io, |
2170 | |||
2171 | .vport_create = lpfc_vport_create, | ||
2172 | .vport_delete = lpfc_vport_delete, | ||
2173 | .dd_fcvport_size = sizeof(struct lpfc_vport *), | ||
2174 | }; | ||
2175 | |||
2176 | struct fc_function_template lpfc_vport_transport_functions = { | ||
2177 | /* fixed attributes the driver supports */ | ||
2178 | .show_host_node_name = 1, | ||
2179 | .show_host_port_name = 1, | ||
2180 | .show_host_supported_classes = 1, | ||
2181 | .show_host_supported_fc4s = 1, | ||
2182 | .show_host_supported_speeds = 1, | ||
2183 | .show_host_maxframe_size = 1, | ||
2184 | |||
2185 | /* dynamic attributes the driver supports */ | ||
2186 | .get_host_port_id = lpfc_get_host_port_id, | ||
2187 | .show_host_port_id = 1, | ||
2188 | |||
2189 | .get_host_port_type = lpfc_get_host_port_type, | ||
2190 | .show_host_port_type = 1, | ||
2191 | |||
2192 | .get_host_port_state = lpfc_get_host_port_state, | ||
2193 | .show_host_port_state = 1, | ||
2194 | |||
2195 | /* active_fc4s is shown but doesn't change (thus no get function) */ | ||
2196 | .show_host_active_fc4s = 1, | ||
2197 | |||
2198 | .get_host_speed = lpfc_get_host_speed, | ||
2199 | .show_host_speed = 1, | ||
2200 | |||
2201 | .get_host_fabric_name = lpfc_get_host_fabric_name, | ||
2202 | .show_host_fabric_name = 1, | ||
2203 | |||
2204 | /* | ||
2205 | * The LPFC driver treats linkdown handling as target loss events | ||
2206 | * so there are no sysfs handlers for link_down_tmo. | ||
2207 | */ | ||
2208 | |||
2209 | .get_fc_host_stats = lpfc_get_stats, | ||
2210 | .reset_fc_host_stats = lpfc_reset_stats, | ||
2211 | |||
2212 | .dd_fcrport_size = sizeof(struct lpfc_rport_data), | ||
2213 | .show_rport_maxframe_size = 1, | ||
2214 | .show_rport_supported_classes = 1, | ||
2215 | |||
2216 | .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo, | ||
2217 | .show_rport_dev_loss_tmo = 1, | ||
2218 | |||
2219 | .get_starget_port_id = lpfc_get_starget_port_id, | ||
2220 | .show_starget_port_id = 1, | ||
2221 | |||
2222 | .get_starget_node_name = lpfc_get_starget_node_name, | ||
2223 | .show_starget_node_name = 1, | ||
2224 | |||
2225 | .get_starget_port_name = lpfc_get_starget_port_name, | ||
2226 | .show_starget_port_name = 1, | ||
2227 | |||
2228 | .issue_fc_host_lip = lpfc_issue_lip, | ||
2229 | .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk, | ||
2230 | .terminate_rport_io = lpfc_terminate_rport_io, | ||
2231 | |||
2232 | .vport_disable = lpfc_vport_disable, | ||
1953 | }; | 2233 | }; |
1954 | 2234 | ||
1955 | void | 2235 | void |
@@ -1972,6 +2252,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
1972 | lpfc_discovery_threads_init(phba, lpfc_discovery_threads); | 2252 | lpfc_discovery_threads_init(phba, lpfc_discovery_threads); |
1973 | lpfc_max_luns_init(phba, lpfc_max_luns); | 2253 | lpfc_max_luns_init(phba, lpfc_max_luns); |
1974 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); | 2254 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); |
2255 | lpfc_peer_port_login_init(phba, lpfc_peer_port_login); | ||
2256 | lpfc_vport_restrict_login_init(phba, lpfc_vport_restrict_login); | ||
1975 | lpfc_use_msi_init(phba, lpfc_use_msi); | 2257 | lpfc_use_msi_init(phba, lpfc_use_msi); |
1976 | lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); | 2258 | lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); |
1977 | lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo); | 2259 | lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo); |