aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2012-05-09 21:17:07 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-05-17 05:57:29 -0400
commit4f2e66c6d225a14fcf77d826fe71f6137cb27352 (patch)
treeb6235968d1a223d83e750d41aab8100f912a68ea /drivers/scsi/lpfc/lpfc_sli.c
parenta7dd9c0f44966b4328b52c5e32f8c3345e3482e5 (diff)
[SCSI] lpfc 8.3.31: Fixed system panic due to midlayer abort and driver complete race on SCSI cmd
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 57eaaa51e1d6..7c4067913c29 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -502,7 +502,7 @@ lpfc_resp_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
502 * allocation is successful, it returns pointer to the newly 502 * allocation is successful, it returns pointer to the newly
503 * allocated iocb object else it returns NULL. 503 * allocated iocb object else it returns NULL.
504 **/ 504 **/
505static struct lpfc_iocbq * 505struct lpfc_iocbq *
506__lpfc_sli_get_iocbq(struct lpfc_hba *phba) 506__lpfc_sli_get_iocbq(struct lpfc_hba *phba)
507{ 507{
508 struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; 508 struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
@@ -1259,7 +1259,7 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1259 struct lpfc_iocbq *piocb) 1259 struct lpfc_iocbq *piocb)
1260{ 1260{
1261 list_add_tail(&piocb->list, &pring->txcmplq); 1261 list_add_tail(&piocb->list, &pring->txcmplq);
1262 piocb->iocb_flag |= LPFC_IO_ON_Q; 1262 piocb->iocb_flag |= LPFC_IO_ON_TXCMPLQ;
1263 pring->txcmplq_cnt++; 1263 pring->txcmplq_cnt++;
1264 if (pring->txcmplq_cnt > pring->txcmplq_max) 1264 if (pring->txcmplq_cnt > pring->txcmplq_max)
1265 pring->txcmplq_max = pring->txcmplq_cnt; 1265 pring->txcmplq_max = pring->txcmplq_cnt;
@@ -2558,9 +2558,9 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
2558 if (iotag != 0 && iotag <= phba->sli.last_iotag) { 2558 if (iotag != 0 && iotag <= phba->sli.last_iotag) {
2559 cmd_iocb = phba->sli.iocbq_lookup[iotag]; 2559 cmd_iocb = phba->sli.iocbq_lookup[iotag];
2560 list_del_init(&cmd_iocb->list); 2560 list_del_init(&cmd_iocb->list);
2561 if (cmd_iocb->iocb_flag & LPFC_IO_ON_Q) { 2561 if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) {
2562 pring->txcmplq_cnt--; 2562 pring->txcmplq_cnt--;
2563 cmd_iocb->iocb_flag &= ~LPFC_IO_ON_Q; 2563 cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
2564 } 2564 }
2565 return cmd_iocb; 2565 return cmd_iocb;
2566 } 2566 }
@@ -2593,14 +2593,14 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba,
2593 2593
2594 if (iotag != 0 && iotag <= phba->sli.last_iotag) { 2594 if (iotag != 0 && iotag <= phba->sli.last_iotag) {
2595 cmd_iocb = phba->sli.iocbq_lookup[iotag]; 2595 cmd_iocb = phba->sli.iocbq_lookup[iotag];
2596 list_del_init(&cmd_iocb->list); 2596 if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) {
2597 if (cmd_iocb->iocb_flag & LPFC_IO_ON_Q) { 2597 /* remove from txcmpl queue list */
2598 cmd_iocb->iocb_flag &= ~LPFC_IO_ON_Q; 2598 list_del_init(&cmd_iocb->list);
2599 cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
2599 pring->txcmplq_cnt--; 2600 pring->txcmplq_cnt--;
2601 return cmd_iocb;
2600 } 2602 }
2601 return cmd_iocb;
2602 } 2603 }
2603
2604 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 2604 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
2605 "0372 iotag x%x is out off range: max iotag (x%x)\n", 2605 "0372 iotag x%x is out off range: max iotag (x%x)\n",
2606 iotag, phba->sli.last_iotag); 2606 iotag, phba->sli.last_iotag);
@@ -3468,6 +3468,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
3468 /* Retrieve everything on the txcmplq */ 3468 /* Retrieve everything on the txcmplq */
3469 list_splice_init(&pring->txcmplq, &txcmplq); 3469 list_splice_init(&pring->txcmplq, &txcmplq);
3470 pring->txcmplq_cnt = 0; 3470 pring->txcmplq_cnt = 0;
3471
3472 /* Indicate the I/O queues are flushed */
3473 phba->hba_flag |= HBA_FCP_IOQ_FLUSH;
3471 spin_unlock_irq(&phba->hbalock); 3474 spin_unlock_irq(&phba->hbalock);
3472 3475
3473 /* Flush the txq */ 3476 /* Flush the txq */
@@ -6069,6 +6072,8 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
6069 else 6072 else
6070 phba->hba_flag &= ~HBA_FIP_SUPPORT; 6073 phba->hba_flag &= ~HBA_FIP_SUPPORT;
6071 6074
6075 phba->hba_flag &= ~HBA_FCP_IOQ_FLUSH;
6076
6072 if (phba->sli_rev != LPFC_SLI_REV4) { 6077 if (phba->sli_rev != LPFC_SLI_REV4) {
6073 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, 6078 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
6074 "0376 READ_REV Error. SLI Level %d " 6079 "0376 READ_REV Error. SLI Level %d "