summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
authorJames Bottomley2005-10-29 17:28:33 +0200
committerJames Bottomley2005-10-29 17:28:33 +0200
commit604a3e3042eb89ffaa4f735ef9208281aae786c7 (patch)
tree54c4ad58274b0bb79386c6c57b4849bfb92d4118 /drivers/scsi/lpfc/lpfc_els.c
parent[SCSI] lpfc: Remove RPI hash from the driver (diff)
downloadkernel-qcow2-linux-604a3e3042eb89ffaa4f735ef9208281aae786c7.tar.gz
kernel-qcow2-linux-604a3e3042eb89ffaa4f735ef9208281aae786c7.tar.xz
kernel-qcow2-linux-604a3e3042eb89ffaa4f735ef9208281aae786c7.zip
[SCSI] lpfc: Fix for "command completion for iotax x?? not found"
From: James Smart <James.Smart@emulex.com> There were scenarios where the error handlers could reuse an iotag value of an active io. Remove all possibility of this by pre-assigning iotag resources to command resources. Signed-off-by: James Smart <James.Smart@emulex.com> Rejections fixed up and Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 63caf7fe9725..e931ae6e7464 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -122,7 +122,6 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
if (elsiocb == NULL)
return NULL;
- memset(elsiocb, 0, sizeof (struct lpfc_iocbq));
icmd = &elsiocb->iocb;
/* fill in BDEs for command */
@@ -133,7 +132,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
if (pcmd)
kfree(pcmd);
- list_add_tail(&elsiocb->list, lpfc_iocb_list);
+ spin_lock_irq(phba->host->host_lock);
+ lpfc_sli_release_iocbq(phba, elsiocb);
+ spin_unlock_irq(phba->host->host_lock);
return NULL;
}
@@ -150,7 +151,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
kfree(prsp);
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
kfree(pcmd);
- list_add_tail(&elsiocb->list, lpfc_iocb_list);
+ spin_lock_irq(phba->host->host_lock);
+ lpfc_sli_release_iocbq(phba, elsiocb);
+ spin_unlock_irq(phba->host->host_lock);
return NULL;
}
INIT_LIST_HEAD(&prsp->list);
@@ -164,7 +167,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
&pbuflist->phys);
if (pbuflist == 0 || pbuflist->virt == 0) {
- list_add_tail(&elsiocb->list, lpfc_iocb_list);
+ spin_lock_irq(phba->host->host_lock);
+ lpfc_sli_release_iocbq(phba, elsiocb);
+ spin_unlock_irq(phba->host->host_lock);
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
kfree(pcmd);
@@ -596,10 +601,8 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba)
spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&iocb->list,
- &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, iocb);
}
}
}
@@ -1713,7 +1716,7 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb)
kfree(buf_ptr);
}
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&elsiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, elsiocb);
spin_unlock_irq(phba->host->host_lock);
return 0;
}
@@ -2929,9 +2932,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
spin_unlock_irq(phba->host->host_lock);
(piocb->iocb_cmpl) (phba, piocb, piocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, piocb);
}
if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
phba->els_tmofunc.expires = jiffies + HZ * timeout;
@@ -2996,7 +2998,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
spin_lock_irq(phba->host->host_lock);
}
else
- list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, piocb);
}
list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
@@ -3033,7 +3035,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
spin_lock_irq(phba->host->host_lock);
}
else
- list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, piocb);
}
spin_unlock_irq(phba->host->host_lock);
return;