aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_attr.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-06-17 20:56:39 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-06-17 23:38:11 -0400
commit858c9f6c19c6f9bf86cbbc64ce0d17c61d6131b8 (patch)
tree9591b15b4424066023e375ad0aa33fdd37e1c452 /drivers/scsi/lpfc/lpfc_attr.c
parent92d7f7b0cde3ad2260e7462b40867b57efd49851 (diff)
[SCSI] lpfc: bug fixes
Following the NPIV support, the following changes have been accumulated in the testing and qualification of the driver: - Fix affinity of ELS ring to slow/deferred event processing - Fix Ring attention masks - Defer dev_loss_tmo timeout handling to worker thread - Consolidate link down error classification for better error checking - Remove unused/deprecated nlp_initiator_tmr timer - Fix for async scan - move adapter init code back into pci_probe_one context. Fix async scan interfaces. - Expand validation of ability to create vports - Extract VPI resource cnt from firmware - Tuning of Login/Reject policies to better deal with overwhelmned targets - Misc ELS and discovery fixes - Export the npiv_enable attribute to sysfs - Mailbox handling fix - Add debugfs support - A few other small misc fixes: - wrong return values, double-frees, bad locking - Added adapter failure heartbeat 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.c117
1 files changed, 67 insertions, 50 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 5cb7924fe3d7..6a2c1ac42442 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -282,9 +282,7 @@ lpfc_issue_lip(struct Scsi_Host *shost)
282 } 282 }
283 283
284 lpfc_set_loopback_flag(phba); 284 lpfc_set_loopback_flag(phba);
285 if (mbxstatus == MBX_TIMEOUT) 285 if (mbxstatus != MBX_TIMEOUT)
286 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
287 else
288 mempool_free(pmboxq, phba->mbox_mem_pool); 286 mempool_free(pmboxq, phba->mbox_mem_pool);
289 287
290 if (mbxstatus == MBXERR_ERROR) 288 if (mbxstatus == MBXERR_ERROR)
@@ -439,30 +437,11 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count)
439 return -EIO; 437 return -EIO;
440} 438}
441 439
442static ssize_t
443lpfc_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
452static ssize_t
453lpfc_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
463int 440int
464lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri, 441lpfc_get_hba_info(struct lpfc_hba *phba,
465 uint32_t *axri, uint32_t *mrpi, uint32_t *arpi) 442 uint32_t *mxri, uint32_t *axri,
443 uint32_t *mrpi, uint32_t *arpi,
444 uint32_t *mvpi, uint32_t *avpi)
466{ 445{
467 struct lpfc_sli *psli = &phba->sli; 446 struct lpfc_sli *psli = &phba->sli;
468 LPFC_MBOXQ_t *pmboxq; 447 LPFC_MBOXQ_t *pmboxq;
@@ -498,9 +477,7 @@ lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri,
498 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 477 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
499 478
500 if (rc != MBX_SUCCESS) { 479 if (rc != MBX_SUCCESS) {
501 if (rc == MBX_TIMEOUT) 480 if (rc != MBX_TIMEOUT)
502 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
503 else
504 mempool_free(pmboxq, phba->mbox_mem_pool); 481 mempool_free(pmboxq, phba->mbox_mem_pool);
505 return 0; 482 return 0;
506 } 483 }
@@ -513,6 +490,10 @@ lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri,
513 *mxri = pmb->un.varRdConfig.max_xri; 490 *mxri = pmb->un.varRdConfig.max_xri;
514 if (axri) 491 if (axri)
515 *axri = pmb->un.varRdConfig.avail_xri; 492 *axri = pmb->un.varRdConfig.avail_xri;
493 if (mvpi)
494 *mvpi = pmb->un.varRdConfig.max_vpi;
495 if (avpi)
496 *avpi = pmb->un.varRdConfig.avail_vpi;
516 497
517 mempool_free(pmboxq, phba->mbox_mem_pool); 498 mempool_free(pmboxq, phba->mbox_mem_pool);
518 return 1; 499 return 1;
@@ -526,7 +507,7 @@ lpfc_max_rpi_show(struct class_device *cdev, char *buf)
526 struct lpfc_hba *phba = vport->phba; 507 struct lpfc_hba *phba = vport->phba;
527 uint32_t cnt; 508 uint32_t cnt;
528 509
529 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL)) 510 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL, NULL, NULL))
530 return snprintf(buf, PAGE_SIZE, "%d\n", cnt); 511 return snprintf(buf, PAGE_SIZE, "%d\n", cnt);
531 return snprintf(buf, PAGE_SIZE, "Unknown\n"); 512 return snprintf(buf, PAGE_SIZE, "Unknown\n");
532} 513}
@@ -539,7 +520,7 @@ lpfc_used_rpi_show(struct class_device *cdev, char *buf)
539 struct lpfc_hba *phba = vport->phba; 520 struct lpfc_hba *phba = vport->phba;
540 uint32_t cnt, acnt; 521 uint32_t cnt, acnt;
541 522
542 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt)) 523 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt, NULL, NULL))
543 return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); 524 return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
544 return snprintf(buf, PAGE_SIZE, "Unknown\n"); 525 return snprintf(buf, PAGE_SIZE, "Unknown\n");
545} 526}
@@ -552,7 +533,7 @@ lpfc_max_xri_show(struct class_device *cdev, char *buf)
552 struct lpfc_hba *phba = vport->phba; 533 struct lpfc_hba *phba = vport->phba;
553 uint32_t cnt; 534 uint32_t cnt;
554 535
555 if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL)) 536 if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL, NULL, NULL))
556 return snprintf(buf, PAGE_SIZE, "%d\n", cnt); 537 return snprintf(buf, PAGE_SIZE, "%d\n", cnt);
557 return snprintf(buf, PAGE_SIZE, "Unknown\n"); 538 return snprintf(buf, PAGE_SIZE, "Unknown\n");
558} 539}
@@ -565,7 +546,33 @@ lpfc_used_xri_show(struct class_device *cdev, char *buf)
565 struct lpfc_hba *phba = vport->phba; 546 struct lpfc_hba *phba = vport->phba;
566 uint32_t cnt, acnt; 547 uint32_t cnt, acnt;
567 548
568 if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL)) 549 if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL, NULL, NULL))
550 return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
551 return snprintf(buf, PAGE_SIZE, "Unknown\n");
552}
553
554static ssize_t
555lpfc_max_vpi_show(struct class_device *cdev, char *buf)
556{
557 struct Scsi_Host *shost = class_to_shost(cdev);
558 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
559 struct lpfc_hba *phba = vport->phba;
560 uint32_t cnt;
561
562 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, NULL))
563 return snprintf(buf, PAGE_SIZE, "%d\n", cnt);
564 return snprintf(buf, PAGE_SIZE, "Unknown\n");
565}
566
567static ssize_t
568lpfc_used_vpi_show(struct class_device *cdev, char *buf)
569{
570 struct Scsi_Host *shost = class_to_shost(cdev);
571 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
572 struct lpfc_hba *phba = vport->phba;
573 uint32_t cnt, acnt;
574
575 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, &acnt))
569 return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); 576 return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
570 return snprintf(buf, PAGE_SIZE, "Unknown\n"); 577 return snprintf(buf, PAGE_SIZE, "Unknown\n");
571} 578}
@@ -995,9 +1002,7 @@ MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:"
995 " 2 - select SLI-2 even on SLI-3 capable HBAs," 1002 " 2 - select SLI-2 even on SLI-3 capable HBAs,"
996 " 3 - select SLI-3"); 1003 " 3 - select SLI-3");
997 1004
998int lpfc_npiv_enable = 0; 1005LPFC_ATTR_R(npiv_enable, 0, 0, 1, "Enable NPIV functionality");
999module_param(lpfc_npiv_enable, int, 0);
1000MODULE_PARM_DESC(lpfc_npiv_enable, "Enable NPIV functionality");
1001 1006
1002/* 1007/*
1003# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear 1008# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
@@ -1052,6 +1057,24 @@ lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val)
1052 return -EINVAL; 1057 return -EINVAL;
1053} 1058}
1054 1059
1060static void
1061lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba)
1062{
1063 struct lpfc_vport *vport;
1064 struct Scsi_Host *shost;
1065 struct lpfc_nodelist *ndlp;
1066
1067 list_for_each_entry(vport, &phba->port_list, listentry) {
1068 shost = lpfc_shost_from_vport(vport);
1069 spin_lock_irq(shost->host_lock);
1070 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
1071 if (ndlp->rport)
1072 ndlp->rport->dev_loss_tmo =
1073 phba->cfg_devloss_tmo;
1074 spin_unlock_irq(shost->host_lock);
1075 }
1076}
1077
1055static int 1078static int
1056lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) 1079lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
1057{ 1080{
@@ -1067,6 +1090,7 @@ lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
1067 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { 1090 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
1068 phba->cfg_nodev_tmo = val; 1091 phba->cfg_nodev_tmo = val;
1069 phba->cfg_devloss_tmo = val; 1092 phba->cfg_devloss_tmo = val;
1093 lpfc_update_rport_devloss_tmo(phba);
1070 return 0; 1094 return 0;
1071 } 1095 }
1072 1096
@@ -1102,6 +1126,7 @@ lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val)
1102 phba->cfg_nodev_tmo = val; 1126 phba->cfg_nodev_tmo = val;
1103 phba->cfg_devloss_tmo = val; 1127 phba->cfg_devloss_tmo = val;
1104 phba->dev_loss_tmo_changed = 1; 1128 phba->dev_loss_tmo_changed = 1;
1129 lpfc_update_rport_devloss_tmo(phba);
1105 return 0; 1130 return 0;
1106 } 1131 }
1107 1132
@@ -1358,6 +1383,7 @@ struct class_device_attribute *lpfc_hba_attrs[] = {
1358 &class_device_attr_lpfc_multi_ring_type, 1383 &class_device_attr_lpfc_multi_ring_type,
1359 &class_device_attr_lpfc_fdmi_on, 1384 &class_device_attr_lpfc_fdmi_on,
1360 &class_device_attr_lpfc_max_luns, 1385 &class_device_attr_lpfc_max_luns,
1386 &class_device_attr_lpfc_npiv_enable,
1361 &class_device_attr_nport_evt_cnt, 1387 &class_device_attr_nport_evt_cnt,
1362 &class_device_attr_management_version, 1388 &class_device_attr_management_version,
1363 &class_device_attr_board_mode, 1389 &class_device_attr_board_mode,
@@ -1641,8 +1667,6 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
1641 1667
1642 if (rc != MBX_SUCCESS) { 1668 if (rc != MBX_SUCCESS) {
1643 if (rc == MBX_TIMEOUT) { 1669 if (rc == MBX_TIMEOUT) {
1644 phba->sysfs_mbox.mbox->mbox_cmpl =
1645 lpfc_sli_def_mbox_cmpl;
1646 phba->sysfs_mbox.mbox = NULL; 1670 phba->sysfs_mbox.mbox = NULL;
1647 } 1671 }
1648 sysfs_mbox_idle(phba); 1672 sysfs_mbox_idle(phba);
@@ -1886,9 +1910,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
1886 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 1910 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1887 1911
1888 if (rc != MBX_SUCCESS) { 1912 if (rc != MBX_SUCCESS) {
1889 if (rc == MBX_TIMEOUT) 1913 if (rc != MBX_TIMEOUT)
1890 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1891 else
1892 mempool_free(pmboxq, phba->mbox_mem_pool); 1914 mempool_free(pmboxq, phba->mbox_mem_pool);
1893 return NULL; 1915 return NULL;
1894 } 1916 }
@@ -1913,9 +1935,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
1913 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 1935 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1914 1936
1915 if (rc != MBX_SUCCESS) { 1937 if (rc != MBX_SUCCESS) {
1916 if (rc == MBX_TIMEOUT) 1938 if (rc != MBX_TIMEOUT)
1917 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1918 else
1919 mempool_free(pmboxq, phba->mbox_mem_pool); 1939 mempool_free(pmboxq, phba->mbox_mem_pool);
1920 return NULL; 1940 return NULL;
1921 } 1941 }
@@ -1993,9 +2013,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
1993 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 2013 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1994 2014
1995 if (rc != MBX_SUCCESS) { 2015 if (rc != MBX_SUCCESS) {
1996 if (rc == MBX_TIMEOUT) 2016 if (rc != MBX_TIMEOUT)
1997 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1998 else
1999 mempool_free(pmboxq, phba->mbox_mem_pool); 2017 mempool_free(pmboxq, phba->mbox_mem_pool);
2000 return; 2018 return;
2001 } 2019 }
@@ -2013,9 +2031,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
2013 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 2031 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
2014 2032
2015 if (rc != MBX_SUCCESS) { 2033 if (rc != MBX_SUCCESS) {
2016 if (rc == MBX_TIMEOUT) 2034 if (rc != MBX_TIMEOUT)
2017 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
2018 else
2019 mempool_free( pmboxq, phba->mbox_mem_pool); 2035 mempool_free( pmboxq, phba->mbox_mem_pool);
2020 return; 2036 return;
2021 } 2037 }
@@ -2253,6 +2269,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
2253 lpfc_max_luns_init(phba, lpfc_max_luns); 2269 lpfc_max_luns_init(phba, lpfc_max_luns);
2254 lpfc_poll_tmo_init(phba, lpfc_poll_tmo); 2270 lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
2255 lpfc_peer_port_login_init(phba, lpfc_peer_port_login); 2271 lpfc_peer_port_login_init(phba, lpfc_peer_port_login);
2272 lpfc_npiv_enable_init(phba, lpfc_npiv_enable);
2256 lpfc_vport_restrict_login_init(phba, lpfc_vport_restrict_login); 2273 lpfc_vport_restrict_login_init(phba, lpfc_vport_restrict_login);
2257 lpfc_use_msi_init(phba, lpfc_use_msi); 2274 lpfc_use_msi_init(phba, lpfc_use_msi);
2258 lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); 2275 lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo);