diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-06-17 19:56:39 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-06-17 22:38:11 -0500 |
commit | 858c9f6c19c6f9bf86cbbc64ce0d17c61d6131b8 (patch) | |
tree | 9591b15b4424066023e375ad0aa33fdd37e1c452 /drivers/scsi/lpfc/lpfc_attr.c | |
parent | 92d7f7b0cde3ad2260e7462b40867b57efd49851 (diff) | |
download | lwn-858c9f6c19c6f9bf86cbbc64ce0d17c61d6131b8.tar.gz lwn-858c9f6c19c6f9bf86cbbc64ce0d17c61d6131b8.zip |
[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.c | 117 |
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) } lpfc_set_loopback_flag(phba); - if (mbxstatus == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else + if (mbxstatus != MBX_TIMEOUT) mempool_free(pmboxq, phba->mbox_mem_pool); if (mbxstatus == MBXERR_ERROR) @@ -439,30 +437,11 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) return -EIO; } -static ssize_t -lpfc_max_vpi_show(struct class_device *cdev, char *buf) -{ - struct Scsi_Host *shost = class_to_shost(cdev); - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - struct lpfc_hba *phba = vport->phba; - - return snprintf(buf, PAGE_SIZE, "%d\n", phba->max_vpi); -} - -static ssize_t -lpfc_used_vpi_show(struct class_device *cdev, char *buf) -{ - struct Scsi_Host *shost = class_to_shost(cdev); - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - struct lpfc_hba *phba = vport->phba; - - /* Don't count the physical port */ - return snprintf(buf, PAGE_SIZE, "%d\n", phba->vpi_cnt-1); -} - int -lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri, - uint32_t *axri, uint32_t *mrpi, uint32_t *arpi) +lpfc_get_hba_info(struct lpfc_hba *phba, + uint32_t *mxri, uint32_t *axri, + uint32_t *mrpi, uint32_t *arpi, + uint32_t *mvpi, uint32_t *avpi) { struct lpfc_sli *psli = &phba->sli; LPFC_MBOXQ_t *pmboxq; @@ -498,9 +477,7 @@ lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri, rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { - if (rc == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else + if (rc != MBX_TIMEOUT) mempool_free(pmboxq, phba->mbox_mem_pool); return 0; } @@ -513,6 +490,10 @@ lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri, *mxri = pmb->un.varRdConfig.max_xri; if (axri) *axri = pmb->un.varRdConfig.avail_xri; + if (mvpi) + *mvpi = pmb->un.varRdConfig.max_vpi; + if (avpi) + *avpi = pmb->un.varRdConfig.avail_vpi; mempool_free(pmboxq, phba->mbox_mem_pool); return 1; @@ -526,7 +507,7 @@ lpfc_max_rpi_show(struct class_device *cdev, char *buf) struct lpfc_hba *phba = vport->phba; uint32_t cnt; - if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL)) + if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL, NULL, NULL)) return snprintf(buf, PAGE_SIZE, "%d\n", cnt); return snprintf(buf, PAGE_SIZE, "Unknown\n"); } @@ -539,7 +520,7 @@ lpfc_used_rpi_show(struct class_device *cdev, char *buf) struct lpfc_hba *phba = vport->phba; uint32_t cnt, acnt; - if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt)) + if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt, NULL, NULL)) return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); return snprintf(buf, PAGE_SIZE, "Unknown\n"); } @@ -552,7 +533,7 @@ lpfc_max_xri_show(struct class_device *cdev, char *buf) struct lpfc_hba *phba = vport->phba; uint32_t cnt; - if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL)) + if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL, NULL, NULL)) return snprintf(buf, PAGE_SIZE, "%d\n", cnt); return snprintf(buf, PAGE_SIZE, "Unknown\n"); } @@ -565,7 +546,33 @@ lpfc_used_xri_show(struct class_device *cdev, char *buf) struct lpfc_hba *phba = vport->phba; uint32_t cnt, acnt; - if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL)) + if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL, NULL, NULL)) + return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); + return snprintf(buf, PAGE_SIZE, "Unknown\n"); +} + +static ssize_t +lpfc_max_vpi_show(struct class_device *cdev, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; + uint32_t cnt; + + if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, NULL)) + return snprintf(buf, PAGE_SIZE, "%d\n", cnt); + return snprintf(buf, PAGE_SIZE, "Unknown\n"); +} + +static ssize_t +lpfc_used_vpi_show(struct class_device *cdev, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; + uint32_t cnt, acnt; + + if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, &acnt)) return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); return snprintf(buf, PAGE_SIZE, "Unknown\n"); } @@ -995,9 +1002,7 @@ MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:" " 2 - select SLI-2 even on SLI-3 capable HBAs," " 3 - select SLI-3"); -int lpfc_npiv_enable = 0; -module_param(lpfc_npiv_enable, int, 0); -MODULE_PARM_DESC(lpfc_npiv_enable, "Enable NPIV functionality"); +LPFC_ATTR_R(npiv_enable, 0, 0, 1, "Enable NPIV functionality"); /* # 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) return -EINVAL; } +static void +lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba) +{ + struct lpfc_vport *vport; + struct Scsi_Host *shost; + struct lpfc_nodelist *ndlp; + + list_for_each_entry(vport, &phba->port_list, listentry) { + shost = lpfc_shost_from_vport(vport); + spin_lock_irq(shost->host_lock); + list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) + if (ndlp->rport) + ndlp->rport->dev_loss_tmo = + phba->cfg_devloss_tmo; + spin_unlock_irq(shost->host_lock); + } +} + static int lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) { @@ -1067,6 +1090,7 @@ lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { phba->cfg_nodev_tmo = val; phba->cfg_devloss_tmo = val; + lpfc_update_rport_devloss_tmo(phba); return 0; } @@ -1102,6 +1126,7 @@ lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val) phba->cfg_nodev_tmo = val; phba->cfg_devloss_tmo = val; phba->dev_loss_tmo_changed = 1; + lpfc_update_rport_devloss_tmo(phba); return 0; } @@ -1358,6 +1383,7 @@ struct class_device_attribute *lpfc_hba_attrs[] = { &class_device_attr_lpfc_multi_ring_type, &class_device_attr_lpfc_fdmi_on, &class_device_attr_lpfc_max_luns, + &class_device_attr_lpfc_npiv_enable, &class_device_attr_nport_evt_cnt, &class_device_attr_management_version, &class_device_attr_board_mode, @@ -1641,8 +1667,6 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) if (rc != MBX_SUCCESS) { if (rc == MBX_TIMEOUT) { - phba->sysfs_mbox.mbox->mbox_cmpl = - lpfc_sli_def_mbox_cmpl; phba->sysfs_mbox.mbox = NULL; } sysfs_mbox_idle(phba); @@ -1886,9 +1910,7 @@ lpfc_get_stats(struct Scsi_Host *shost) rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { - if (rc == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else + if (rc != MBX_TIMEOUT) mempool_free(pmboxq, phba->mbox_mem_pool); return NULL; } @@ -1913,9 +1935,7 @@ lpfc_get_stats(struct Scsi_Host *shost) rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { - if (rc == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else + if (rc != MBX_TIMEOUT) mempool_free(pmboxq, phba->mbox_mem_pool); return NULL; } @@ -1993,9 +2013,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { - if (rc == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else + if (rc != MBX_TIMEOUT) mempool_free(pmboxq, phba->mbox_mem_pool); return; } @@ -2013,9 +2031,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { - if (rc == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else + if (rc != MBX_TIMEOUT) mempool_free( pmboxq, phba->mbox_mem_pool); return; } @@ -2253,6 +2269,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_max_luns_init(phba, lpfc_max_luns); lpfc_poll_tmo_init(phba, lpfc_poll_tmo); lpfc_peer_port_login_init(phba, lpfc_peer_port_login); + lpfc_npiv_enable_init(phba, lpfc_npiv_enable); lpfc_vport_restrict_login_init(phba, lpfc_vport_restrict_login); lpfc_use_msi_init(phba, lpfc_use_msi); lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); |