diff options
| author | James Smart <James.Smart@Emulex.Com> | 2006-08-17 11:57:58 -0400 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-08-19 16:46:05 -0400 |
| commit | 33ccf8d1080bdccb4751a92f6da361a6e01b7cc0 (patch) | |
| tree | 48128e331e0e46af0258864325eb1550287cca61 | |
| parent | 3a0c56d801df6785b30e36c19e89d7e971c151da (diff) | |
[SCSI] lpfc 8.1.9 : Misc Bug Fixes
Misc Bug Fixes:
- Cap MBX_DOWN_LINK command timeout to 60 seconds
- Fix double free of ndlp object
- Don't free mbox structures on error. The completion handlers expect to do so.
- Clear host attention work items when going offline
- Fixed discovery issues in multi-initiator environments.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 15 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 1 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 22 |
5 files changed, 38 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 76f8bd53e230..d384c16f4a87 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
| @@ -222,7 +222,7 @@ lpfc_issue_lip(struct Scsi_Host *host) | |||
| 222 | pmboxq->mb.mbxCommand = MBX_DOWN_LINK; | 222 | pmboxq->mb.mbxCommand = MBX_DOWN_LINK; |
| 223 | pmboxq->mb.mbxOwner = OWN_HOST; | 223 | pmboxq->mb.mbxOwner = OWN_HOST; |
| 224 | 224 | ||
| 225 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); | 225 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2); |
| 226 | 226 | ||
| 227 | if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) { | 227 | if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) { |
| 228 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | 228 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 60f5cca0abe9..3567de613162 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
| @@ -1848,9 +1848,12 @@ static void | |||
| 1848 | lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 1848 | lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
| 1849 | struct lpfc_iocbq * rspiocb) | 1849 | struct lpfc_iocbq * rspiocb) |
| 1850 | { | 1850 | { |
| 1851 | IOCB_t *irsp; | ||
| 1851 | struct lpfc_nodelist *ndlp; | 1852 | struct lpfc_nodelist *ndlp; |
| 1852 | LPFC_MBOXQ_t *mbox = NULL; | 1853 | LPFC_MBOXQ_t *mbox = NULL; |
| 1853 | 1854 | ||
| 1855 | irsp = &rspiocb->iocb; | ||
| 1856 | |||
| 1854 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 1857 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
| 1855 | if (cmdiocb->context_un.mbox) | 1858 | if (cmdiocb->context_un.mbox) |
| 1856 | mbox = cmdiocb->context_un.mbox; | 1859 | mbox = cmdiocb->context_un.mbox; |
| @@ -1893,9 +1896,15 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
| 1893 | mempool_free( mbox, phba->mbox_mem_pool); | 1896 | mempool_free( mbox, phba->mbox_mem_pool); |
| 1894 | } else { | 1897 | } else { |
| 1895 | mempool_free( mbox, phba->mbox_mem_pool); | 1898 | mempool_free( mbox, phba->mbox_mem_pool); |
| 1896 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 1899 | /* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */ |
| 1897 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1900 | if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && |
| 1898 | ndlp = NULL; | 1901 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || |
| 1902 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | ||
| 1903 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) { | ||
| 1904 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | ||
| 1905 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
| 1906 | ndlp = NULL; | ||
| 1907 | } | ||
| 1899 | } | 1908 | } |
| 1900 | } | 1909 | } |
| 1901 | } | 1910 | } |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 1c3f2689155b..b2f1552f1848 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
| @@ -1557,6 +1557,8 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
| 1557 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1557 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
| 1558 | } | 1558 | } |
| 1559 | } | 1559 | } |
| 1560 | |||
| 1561 | spin_lock_irq(phba->host->host_lock); | ||
| 1560 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { | 1562 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
| 1561 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 1563 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && |
| 1562 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 1564 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
| @@ -1569,6 +1571,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
| 1569 | mempool_free(mb, phba->mbox_mem_pool); | 1571 | mempool_free(mb, phba->mbox_mem_pool); |
| 1570 | } | 1572 | } |
| 1571 | } | 1573 | } |
| 1574 | spin_unlock_irq(phba->host->host_lock); | ||
| 1572 | 1575 | ||
| 1573 | lpfc_els_abort(phba,ndlp,0); | 1576 | lpfc_els_abort(phba,ndlp,0); |
| 1574 | spin_lock_irq(phba->host->host_lock); | 1577 | spin_lock_irq(phba->host->host_lock); |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 16dc8c82b5ce..f6948ffe689a 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
| @@ -1379,6 +1379,7 @@ lpfc_offline(struct lpfc_hba * phba) | |||
| 1379 | /* stop all timers associated with this hba */ | 1379 | /* stop all timers associated with this hba */ |
| 1380 | lpfc_stop_timer(phba); | 1380 | lpfc_stop_timer(phba); |
| 1381 | phba->work_hba_events = 0; | 1381 | phba->work_hba_events = 0; |
| 1382 | phba->work_ha = 0; | ||
| 1382 | 1383 | ||
| 1383 | lpfc_printf_log(phba, | 1384 | lpfc_printf_log(phba, |
| 1384 | KERN_WARNING, | 1385 | KERN_WARNING, |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index b38021a32c96..20449a8dd53d 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
| @@ -393,6 +393,20 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
| 393 | mbox->context2 = ndlp; | 393 | mbox->context2 = ndlp; |
| 394 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); | 394 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); |
| 395 | 395 | ||
| 396 | /* | ||
| 397 | * If there is an outstanding PLOGI issued, abort it before | ||
| 398 | * sending ACC rsp for received PLOGI. If pending plogi | ||
| 399 | * is not canceled here, the plogi will be rejected by | ||
| 400 | * remote port and will be retried. On a configuration with | ||
| 401 | * single discovery thread, this will cause a huge delay in | ||
| 402 | * discovery. Also this will cause multiple state machines | ||
| 403 | * running in parallel for this node. | ||
| 404 | */ | ||
| 405 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) { | ||
| 406 | /* software abort outstanding PLOGI */ | ||
| 407 | lpfc_els_abort(phba, ndlp, 1); | ||
| 408 | } | ||
| 409 | |||
| 396 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); | 410 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); |
| 397 | return 1; | 411 | return 1; |
| 398 | 412 | ||
| @@ -1601,7 +1615,13 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, | |||
| 1601 | 1615 | ||
| 1602 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1616 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
| 1603 | 1617 | ||
| 1604 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1618 | /* |
| 1619 | * Do not start discovery if discovery is about to start | ||
| 1620 | * or discovery in progress for this node. Starting discovery | ||
| 1621 | * here will affect the counting of discovery threads. | ||
| 1622 | */ | ||
| 1623 | if ((!(ndlp->nlp_flag & NLP_DELAY_TMO)) && | ||
| 1624 | (ndlp->nlp_flag & NLP_NPR_2B_DISC)){ | ||
| 1605 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1625 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
| 1606 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1626 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
| 1607 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1627 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
