aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
authorJames Bottomley <jejb@mulgrave.(none)>2005-10-29 11:28:33 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-10-29 11:28:33 -0400
commit604a3e3042eb89ffaa4f735ef9208281aae786c7 (patch)
tree54c4ad58274b0bb79386c6c57b4849bfb92d4118 /drivers/scsi/lpfc/lpfc_els.c
parent21568f5387636fe2bfb9ee42383d76de11ed99c7 (diff)
[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,
122 122
123 if (elsiocb == NULL) 123 if (elsiocb == NULL)
124 return NULL; 124 return NULL;
125 memset(elsiocb, 0, sizeof (struct lpfc_iocbq));
126 icmd = &elsiocb->iocb; 125 icmd = &elsiocb->iocb;
127 126
128 /* fill in BDEs for command */ 127 /* fill in BDEs for command */
@@ -133,7 +132,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
133 if (pcmd) 132 if (pcmd)
134 kfree(pcmd); 133 kfree(pcmd);
135 134
136 list_add_tail(&elsiocb->list, lpfc_iocb_list); 135 spin_lock_irq(phba->host->host_lock);
136 lpfc_sli_release_iocbq(phba, elsiocb);
137 spin_unlock_irq(phba->host->host_lock);
137 return NULL; 138 return NULL;
138 } 139 }
139 140
@@ -150,7 +151,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
150 kfree(prsp); 151 kfree(prsp);
151 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); 152 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
152 kfree(pcmd); 153 kfree(pcmd);
153 list_add_tail(&elsiocb->list, lpfc_iocb_list); 154 spin_lock_irq(phba->host->host_lock);
155 lpfc_sli_release_iocbq(phba, elsiocb);
156 spin_unlock_irq(phba->host->host_lock);
154 return NULL; 157 return NULL;
155 } 158 }
156 INIT_LIST_HEAD(&prsp->list); 159 INIT_LIST_HEAD(&prsp->list);
@@ -164,7 +167,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
164 pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, 167 pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
165 &pbuflist->phys); 168 &pbuflist->phys);
166 if (pbuflist == 0 || pbuflist->virt == 0) { 169 if (pbuflist == 0 || pbuflist->virt == 0) {
167 list_add_tail(&elsiocb->list, lpfc_iocb_list); 170 spin_lock_irq(phba->host->host_lock);
171 lpfc_sli_release_iocbq(phba, elsiocb);
172 spin_unlock_irq(phba->host->host_lock);
168 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); 173 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
169 lpfc_mbuf_free(phba, prsp->virt, prsp->phys); 174 lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
170 kfree(pcmd); 175 kfree(pcmd);
@@ -596,10 +601,8 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba)
596 spin_unlock_irq(phba->host->host_lock); 601 spin_unlock_irq(phba->host->host_lock);
597 (iocb->iocb_cmpl) (phba, iocb, iocb); 602 (iocb->iocb_cmpl) (phba, iocb, iocb);
598 spin_lock_irq(phba->host->host_lock); 603 spin_lock_irq(phba->host->host_lock);
599 } else { 604 } else
600 list_add_tail(&iocb->list, 605 lpfc_sli_release_iocbq(phba, iocb);
601 &phba->lpfc_iocb_list);
602 }
603 } 606 }
604 } 607 }
605 } 608 }
@@ -1713,7 +1716,7 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb)
1713 kfree(buf_ptr); 1716 kfree(buf_ptr);
1714 } 1717 }
1715 spin_lock_irq(phba->host->host_lock); 1718 spin_lock_irq(phba->host->host_lock);
1716 list_add_tail(&elsiocb->list, &phba->lpfc_iocb_list); 1719 lpfc_sli_release_iocbq(phba, elsiocb);
1717 spin_unlock_irq(phba->host->host_lock); 1720 spin_unlock_irq(phba->host->host_lock);
1718 return 0; 1721 return 0;
1719} 1722}
@@ -2929,9 +2932,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
2929 spin_unlock_irq(phba->host->host_lock); 2932 spin_unlock_irq(phba->host->host_lock);
2930 (piocb->iocb_cmpl) (phba, piocb, piocb); 2933 (piocb->iocb_cmpl) (phba, piocb, piocb);
2931 spin_lock_irq(phba->host->host_lock); 2934 spin_lock_irq(phba->host->host_lock);
2932 } else { 2935 } else
2933 list_add_tail(&piocb->list, &phba->lpfc_iocb_list); 2936 lpfc_sli_release_iocbq(phba, piocb);
2934 }
2935 } 2937 }
2936 if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) { 2938 if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
2937 phba->els_tmofunc.expires = jiffies + HZ * timeout; 2939 phba->els_tmofunc.expires = jiffies + HZ * timeout;
@@ -2996,7 +2998,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
2996 spin_lock_irq(phba->host->host_lock); 2998 spin_lock_irq(phba->host->host_lock);
2997 } 2999 }
2998 else 3000 else
2999 list_add_tail(&piocb->list, &phba->lpfc_iocb_list); 3001 lpfc_sli_release_iocbq(phba, piocb);
3000 } 3002 }
3001 3003
3002 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { 3004 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
@@ -3033,7 +3035,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
3033 spin_lock_irq(phba->host->host_lock); 3035 spin_lock_irq(phba->host->host_lock);
3034 } 3036 }
3035 else 3037 else
3036 list_add_tail(&piocb->list, &phba->lpfc_iocb_list); 3038 lpfc_sli_release_iocbq(phba, piocb);
3037 } 3039 }
3038 spin_unlock_irq(phba->host->host_lock); 3040 spin_unlock_irq(phba->host->host_lock);
3039 return; 3041 return;