diff options
| author | James Smart <james.smart@emulex.com> | 2010-09-29 11:18:45 -0400 |
|---|---|---|
| committer | James Bottomley <James.Bottomley@suse.de> | 2010-10-07 18:26:19 -0400 |
| commit | d439d286f573afab8c164dbc953ce1d214585a40 (patch) | |
| tree | eec9c3089e49ae0938b4fff282afd2472d9b7fdc | |
| parent | bf5eefb007e7c5498a41af2dd65d957ae9793a63 (diff) | |
[SCSI] lpfc 8.3.17: Code Cleanup and Locking fixes
- Move Unload flag earlier in vport deletei to stop ELS traffic
- Replaced some unnecessary spin_lock_irqsave with spin_lock_irq
- Fixed circular spinlock dependency between low-level driver and SCSI midlayer
- Remove duplicate code from lpfc_els_retry routine
- Make all error values negative
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_bsg.c | 81 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 34 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 34 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 100 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 8 |
6 files changed, 142 insertions, 117 deletions
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 49d0cf99c24c..10cfc64782ad 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c | |||
| @@ -259,6 +259,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job) | |||
| 259 | struct bsg_job_data *dd_data; | 259 | struct bsg_job_data *dd_data; |
| 260 | uint32_t creg_val; | 260 | uint32_t creg_val; |
| 261 | int rc = 0; | 261 | int rc = 0; |
| 262 | int iocb_stat; | ||
| 262 | 263 | ||
| 263 | /* in case no data is transferred */ | 264 | /* in case no data is transferred */ |
| 264 | job->reply->reply_payload_rcv_len = 0; | 265 | job->reply->reply_payload_rcv_len = 0; |
| @@ -373,14 +374,13 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job) | |||
| 373 | readl(phba->HCregaddr); /* flush */ | 374 | readl(phba->HCregaddr); /* flush */ |
| 374 | } | 375 | } |
| 375 | 376 | ||
| 376 | rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0); | 377 | iocb_stat = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0); |
| 377 | 378 | if (iocb_stat == IOCB_SUCCESS) | |
| 378 | if (rc == IOCB_SUCCESS) | ||
| 379 | return 0; /* done for now */ | 379 | return 0; /* done for now */ |
| 380 | else if (rc == IOCB_BUSY) | 380 | else if (iocb_stat == IOCB_BUSY) |
| 381 | rc = EAGAIN; | 381 | rc = -EAGAIN; |
| 382 | else | 382 | else |
| 383 | rc = EIO; | 383 | rc = -EIO; |
| 384 | 384 | ||
| 385 | 385 | ||
| 386 | /* iocb failed so cleanup */ | 386 | /* iocb failed so cleanup */ |
| @@ -631,9 +631,9 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job) | |||
| 631 | if (rc == IOCB_SUCCESS) | 631 | if (rc == IOCB_SUCCESS) |
| 632 | return 0; /* done for now */ | 632 | return 0; /* done for now */ |
| 633 | else if (rc == IOCB_BUSY) | 633 | else if (rc == IOCB_BUSY) |
| 634 | rc = EAGAIN; | 634 | rc = -EAGAIN; |
| 635 | else | 635 | else |
| 636 | rc = EIO; | 636 | rc = -EIO; |
| 637 | 637 | ||
| 638 | pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, | 638 | pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, |
| 639 | job->request_payload.sg_cnt, DMA_TO_DEVICE); | 639 | job->request_payload.sg_cnt, DMA_TO_DEVICE); |
| @@ -1299,7 +1299,7 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag, | |||
| 1299 | /* Allocate buffer for command iocb */ | 1299 | /* Allocate buffer for command iocb */ |
| 1300 | ctiocb = lpfc_sli_get_iocbq(phba); | 1300 | ctiocb = lpfc_sli_get_iocbq(phba); |
| 1301 | if (!ctiocb) { | 1301 | if (!ctiocb) { |
| 1302 | rc = ENOMEM; | 1302 | rc = -ENOMEM; |
| 1303 | goto no_ctiocb; | 1303 | goto no_ctiocb; |
| 1304 | } | 1304 | } |
| 1305 | 1305 | ||
| @@ -1649,17 +1649,18 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi) | |||
| 1649 | 1649 | ||
| 1650 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1650 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
| 1651 | if (!mbox) | 1651 | if (!mbox) |
| 1652 | return ENOMEM; | 1652 | return -ENOMEM; |
| 1653 | 1653 | ||
| 1654 | status = lpfc_reg_rpi(phba, 0, phba->pport->fc_myDID, | 1654 | status = lpfc_reg_rpi(phba, 0, phba->pport->fc_myDID, |
| 1655 | (uint8_t *)&phba->pport->fc_sparam, mbox, 0); | 1655 | (uint8_t *)&phba->pport->fc_sparam, mbox, 0); |
| 1656 | if (status) { | 1656 | if (status) { |
| 1657 | mempool_free(mbox, phba->mbox_mem_pool); | 1657 | mempool_free(mbox, phba->mbox_mem_pool); |
| 1658 | return ENOMEM; | 1658 | return -ENOMEM; |
| 1659 | } | 1659 | } |
| 1660 | 1660 | ||
| 1661 | dmabuff = (struct lpfc_dmabuf *) mbox->context1; | 1661 | dmabuff = (struct lpfc_dmabuf *) mbox->context1; |
| 1662 | mbox->context1 = NULL; | 1662 | mbox->context1 = NULL; |
| 1663 | mbox->context2 = NULL; | ||
| 1663 | status = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); | 1664 | status = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); |
| 1664 | 1665 | ||
| 1665 | if ((status != MBX_SUCCESS) || (mbox->u.mb.mbxStatus)) { | 1666 | if ((status != MBX_SUCCESS) || (mbox->u.mb.mbxStatus)) { |
| @@ -1667,7 +1668,7 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi) | |||
| 1667 | kfree(dmabuff); | 1668 | kfree(dmabuff); |
| 1668 | if (status != MBX_TIMEOUT) | 1669 | if (status != MBX_TIMEOUT) |
| 1669 | mempool_free(mbox, phba->mbox_mem_pool); | 1670 | mempool_free(mbox, phba->mbox_mem_pool); |
| 1670 | return ENODEV; | 1671 | return -ENODEV; |
| 1671 | } | 1672 | } |
| 1672 | 1673 | ||
| 1673 | *rpi = mbox->u.mb.un.varWords[0]; | 1674 | *rpi = mbox->u.mb.un.varWords[0]; |
| @@ -1693,7 +1694,7 @@ static int lpfcdiag_loop_self_unreg(struct lpfc_hba *phba, uint16_t rpi) | |||
| 1693 | /* Allocate mboxq structure */ | 1694 | /* Allocate mboxq structure */ |
| 1694 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1695 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
| 1695 | if (mbox == NULL) | 1696 | if (mbox == NULL) |
| 1696 | return ENOMEM; | 1697 | return -ENOMEM; |
| 1697 | 1698 | ||
| 1698 | lpfc_unreg_login(phba, 0, rpi, mbox); | 1699 | lpfc_unreg_login(phba, 0, rpi, mbox); |
| 1699 | status = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); | 1700 | status = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); |
| @@ -1701,7 +1702,7 @@ static int lpfcdiag_loop_self_unreg(struct lpfc_hba *phba, uint16_t rpi) | |||
| 1701 | if ((status != MBX_SUCCESS) || (mbox->u.mb.mbxStatus)) { | 1702 | if ((status != MBX_SUCCESS) || (mbox->u.mb.mbxStatus)) { |
| 1702 | if (status != MBX_TIMEOUT) | 1703 | if (status != MBX_TIMEOUT) |
| 1703 | mempool_free(mbox, phba->mbox_mem_pool); | 1704 | mempool_free(mbox, phba->mbox_mem_pool); |
| 1704 | return EIO; | 1705 | return -EIO; |
| 1705 | } | 1706 | } |
| 1706 | 1707 | ||
| 1707 | mempool_free(mbox, phba->mbox_mem_pool); | 1708 | mempool_free(mbox, phba->mbox_mem_pool); |
| @@ -1730,6 +1731,8 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi, | |||
| 1730 | struct ulp_bde64 *bpl = NULL; | 1731 | struct ulp_bde64 *bpl = NULL; |
| 1731 | struct lpfc_sli_ct_request *ctreq = NULL; | 1732 | struct lpfc_sli_ct_request *ctreq = NULL; |
| 1732 | int ret_val = 0; | 1733 | int ret_val = 0; |
| 1734 | int time_left; | ||
| 1735 | int iocb_stat; | ||
| 1733 | unsigned long flags; | 1736 | unsigned long flags; |
| 1734 | 1737 | ||
| 1735 | *txxri = 0; | 1738 | *txxri = 0; |
| @@ -1737,7 +1740,7 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi, | |||
| 1737 | evt = lpfc_bsg_event_new(FC_REG_CT_EVENT, current->pid, | 1740 | evt = lpfc_bsg_event_new(FC_REG_CT_EVENT, current->pid, |
| 1738 | SLI_CT_ELX_LOOPBACK); | 1741 | SLI_CT_ELX_LOOPBACK); |
| 1739 | if (!evt) | 1742 | if (!evt) |
| 1740 | return ENOMEM; | 1743 | return -ENOMEM; |
| 1741 | 1744 | ||
| 1742 | spin_lock_irqsave(&phba->ct_ev_lock, flags); | 1745 | spin_lock_irqsave(&phba->ct_ev_lock, flags); |
| 1743 | list_add(&evt->node, &phba->ct_ev_waiters); | 1746 | list_add(&evt->node, &phba->ct_ev_waiters); |
| @@ -1770,7 +1773,7 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi, | |||
| 1770 | if (cmdiocbq == NULL || rspiocbq == NULL || | 1773 | if (cmdiocbq == NULL || rspiocbq == NULL || |
| 1771 | dmabuf == NULL || bpl == NULL || ctreq == NULL || | 1774 | dmabuf == NULL || bpl == NULL || ctreq == NULL || |
| 1772 | dmabuf->virt == NULL) { | 1775 | dmabuf->virt == NULL) { |
| 1773 | ret_val = ENOMEM; | 1776 | ret_val = -ENOMEM; |
| 1774 | goto err_get_xri_exit; | 1777 | goto err_get_xri_exit; |
| 1775 | } | 1778 | } |
| 1776 | 1779 | ||
| @@ -1806,24 +1809,24 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi, | |||
| 1806 | cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC; | 1809 | cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC; |
| 1807 | cmdiocbq->vport = phba->pport; | 1810 | cmdiocbq->vport = phba->pport; |
| 1808 | 1811 | ||
| 1809 | ret_val = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq, | 1812 | iocb_stat = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq, |
| 1810 | rspiocbq, | 1813 | rspiocbq, |
| 1811 | (phba->fc_ratov * 2) | 1814 | (phba->fc_ratov * 2) |
| 1812 | + LPFC_DRVR_TIMEOUT); | 1815 | + LPFC_DRVR_TIMEOUT); |
| 1813 | if (ret_val) | 1816 | if (iocb_stat) { |
| 1817 | ret_val = -EIO; | ||
| 1814 | goto err_get_xri_exit; | 1818 | goto err_get_xri_exit; |
| 1815 | 1819 | } | |
| 1816 | *txxri = rsp->ulpContext; | 1820 | *txxri = rsp->ulpContext; |
| 1817 | 1821 | ||
| 1818 | evt->waiting = 1; | 1822 | evt->waiting = 1; |
| 1819 | evt->wait_time_stamp = jiffies; | 1823 | evt->wait_time_stamp = jiffies; |
| 1820 | ret_val = wait_event_interruptible_timeout( | ||
