summaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJamie Wellnitz <Jamie.Wellnitz@emulex.com>2006-03-01 06:33:12 +0300
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-03-06 18:47:46 +0300
commitb808608bd7afdf1b0a2eb096ff2b5b93781fdbb6 (patch)
treec09a1b80000231144129ef988c259117e55630aa /drivers/scsi/lpfc
parent66a9ed66000d186933892ca5121e68a071d624ac (diff)
downloadlinux-b808608bd7afdf1b0a2eb096ff2b5b93781fdbb6.tar.xz
[PATCH] lpfc 8.1.3: Fix polling mode panic
Fix polling mode panic Cause: Race between interrupt driven and polling path in harvesting iocbs from the response ring. Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c17
2 files changed, 16 insertions, 6 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 094f18f1fa05..f93799873721 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -467,6 +467,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
sdev = cmd->device;
cmd->scsi_done(cmd);
+ if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+ lpfc_release_scsi_buf(phba, lpfc_cmd);
+ return;
+ }
+
if (!result && pnode != NULL &&
((jiffies - pnode->last_ramp_up_time) >
LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index d08fd89dd44f..764aadbec71b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1154,12 +1154,17 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
&rspiocbq);
if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
- spin_unlock_irqrestore(
- phba->host->host_lock, iflag);
- (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
- &rspiocbq);
- spin_lock_irqsave(phba->host->host_lock,
- iflag);
+ if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+ (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+ &rspiocbq);
+ } else {
+ spin_unlock_irqrestore(
+ phba->host->host_lock, iflag);
+ (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+ &rspiocbq);
+ spin_lock_irqsave(phba->host->host_lock,
+ iflag);
+ }
}
break;
default: