diff options
author | James Bottomley <jejb@mulgrave.(none)> | 2005-10-29 11:28:33 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-10-29 11:28:33 -0400 |
commit | 604a3e3042eb89ffaa4f735ef9208281aae786c7 (patch) | |
tree | 54c4ad58274b0bb79386c6c57b4849bfb92d4118 /drivers/scsi/lpfc/lpfc_els.c | |
parent | 21568f5387636fe2bfb9ee42383d76de11ed99c7 (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.c | 30 |
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; |