aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.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_sli.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_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c281
1 files changed, 122 insertions, 159 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 71ff2b6a642f..a8097e6c9dce 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -65,6 +65,18 @@ typedef enum _lpfc_iocb_type {
65 LPFC_ABORT_IOCB 65 LPFC_ABORT_IOCB
66} lpfc_iocb_type; 66} lpfc_iocb_type;
67 67
68void
69lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
70{
71 size_t start_clean = (size_t)(&((struct lpfc_iocbq *)NULL)->iocb);
72
73 /*
74 * Clean all volatile data fields, preserve iotag and node struct.
75 */
76 memset((char*)iocbq + start_clean, 0, sizeof(*iocbq) - start_clean);
77 list_add_tail(&iocbq->list, &phba->lpfc_iocb_list);
78}
79
68/* 80/*
69 * Translate the iocb command to an iocb command type used to decide the final 81 * Translate the iocb command to an iocb command type used to decide the final
70 * disposition of each completed IOCB. 82 * disposition of each completed IOCB.
@@ -265,41 +277,69 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
265 return iocb; 277 return iocb;
266} 278}
267 279
268static uint32_t 280uint16_t
269lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_sli_ring * pring) 281lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
270{ 282{
271 uint32_t search_start; 283 struct lpfc_iocbq ** new_arr;
284 struct lpfc_iocbq ** old_arr;
285 size_t new_len;
286 struct lpfc_sli *psli = &phba->sli;
287 uint16_t iotag;
272 288
273 if (pring->fast_lookup == NULL) { 289 spin_lock_irq(phba->host->host_lock);
274 pring->iotag_ctr++; 290 iotag = psli->last_iotag;
275 if (pring->iotag_ctr >= pring->iotag_max) 291 if(++iotag < psli->iocbq_lookup_len) {
276 pring->iotag_ctr = 1; 292 psli->last_iotag = iotag;
277 return pring->iotag_ctr; 293 psli->iocbq_lookup[iotag] = iocbq;
294 spin_unlock_irq(phba->host->host_lock);
295 iocbq->iotag = iotag;
296 return iotag;
297 }
298 else if (psli->iocbq_lookup_len < (0xffff
299 - LPFC_IOCBQ_LOOKUP_INCREMENT)) {
300 new_len = psli->iocbq_lookup_len + LPFC_IOCBQ_LOOKUP_INCREMENT;
301 spin_unlock_irq(phba->host->host_lock);
302 new_arr = kmalloc(new_len * sizeof (struct lpfc_iocbq *),
303 GFP_KERNEL);
304 if (new_arr) {
305 memset((char *)new_arr, 0,
306 new_len * sizeof (struct lpfc_iocbq *));
307 spin_lock_irq(phba->host->host_lock);
308 old_arr = psli->iocbq_lookup;
309 if (new_len <= psli->iocbq_lookup_len) {
310 /* highly unprobable case */
311 kfree(new_arr);
312 iotag = psli->last_iotag;
313 if(++iotag < psli->iocbq_lookup_len) {
314 psli->last_iotag = iotag;
315 psli->iocbq_lookup[iotag] = iocbq;
316 spin_unlock_irq(phba->host->host_lock);
317 iocbq->iotag = iotag;
318 return iotag;
319 }
320 spin_unlock_irq(phba->host->host_lock);
321 return 0;
322 }
323 if (psli->iocbq_lookup)
324 memcpy(new_arr, old_arr,
325 ((psli->last_iotag + 1) *
326 sizeof (struct lpfc_iocbq *)));
327 psli->iocbq_lookup = new_arr;
328 psli->iocbq_lookup_len = new_len;
329 psli->last_iotag = iotag;
330 psli->iocbq_lookup[iotag] = iocbq;
331 spin_unlock_irq(phba->host->host_lock);
332 iocbq->iotag = iotag;
333 kfree(old_arr);
334 return iotag;
335 }
278 } 336 }
279 337
280 search_start = pring->iotag_ctr; 338 lpfc_printf_log(phba, KERN_ERR,LOG_SLI,
281 339 "%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n",
282 do { 340 phba->brd_no, psli->last_iotag);
283 pring->iotag_ctr++;
284 if (pring->iotag_ctr >= pring->fast_iotag)
285 pring->iotag_ctr = 1;
286
287 if (*(pring->fast_lookup + pring->iotag_ctr) == NULL)
288 return pring->iotag_ctr;
289
290 } while (pring->iotag_ctr != search_start);
291 341
292 /* 342 return 0;
293 * Outstanding I/O count for ring <ringno> is at max <fast_iotag>
294 */
295 lpfc_printf_log(phba,
296 KERN_ERR,
297 LOG_SLI,
298 "%d:0318 Outstanding I/O count for ring %d is at max x%x\n",
299 phba->brd_no,
300 pring->ringno,
301 pring->fast_iotag);
302 return (0);
303} 343}
304 344
305static void 345static void
@@ -307,10 +347,9 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
307 IOCB_t *iocb, struct lpfc_iocbq *nextiocb) 347 IOCB_t *iocb, struct lpfc_iocbq *nextiocb)
308{ 348{
309 /* 349 /*
310 * Allocate and set up an iotag 350 * Set up an iotag
311 */ 351 */
312 nextiocb->iocb.ulpIoTag = 352 nextiocb->iocb.ulpIoTag = (nextiocb->iocb_cmpl) ? nextiocb->iotag : 0;
313 lpfc_sli_next_iotag(phba, &phba->sli.ring[phba->sli.fcp_ring]);
314 353
315 /* 354 /*
316 * Issue iocb command to adapter 355 * Issue iocb command to adapter
@@ -326,9 +365,8 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
326 */ 365 */
327 if (nextiocb->iocb_cmpl) 366 if (nextiocb->iocb_cmpl)
328 lpfc_sli_ringtxcmpl_put(phba, pring, nextiocb); 367 lpfc_sli_ringtxcmpl_put(phba, pring, nextiocb);
329 else { 368 else
330 list_add_tail(&nextiocb->list, &phba->lpfc_iocb_list); 369 lpfc_sli_release_iocbq(phba, nextiocb);
331 }
332 370
333 /* 371 /*
334 * Let the HBA know what IOCB slot will be the next one the 372 * Let the HBA know what IOCB slot will be the next one the
@@ -752,80 +790,28 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
752} 790}
753 791
754static struct lpfc_iocbq * 792static struct lpfc_iocbq *
755lpfc_sli_txcmpl_ring_search_slow(struct lpfc_sli_ring * pring, 793lpfc_sli_iocbq_lookup(struct lpfc_hba * phba,
756 struct lpfc_iocbq * prspiocb) 794 struct lpfc_sli_ring * pring,
795 struct lpfc_iocbq * prspiocb)
757{ 796{
758 IOCB_t *icmd = NULL;
759 IOCB_t *irsp = NULL;
760 struct lpfc_iocbq *cmd_iocb;
761 struct lpfc_iocbq *iocb, *next_iocb;
762 uint16_t iotag;
763
764 irsp = &prspiocb->iocb;
765 iotag = irsp->ulpIoTag;
766 cmd_iocb = NULL;
767
768 /* Search through txcmpl from the begining */
769 list_for_each_entry_safe(iocb, next_iocb, &(pring->txcmplq), list) {
770 icmd = &iocb->iocb;
771 if (iotag == icmd->ulpIoTag) {
772 /* Found a match. */
773 cmd_iocb = iocb;
774 list_del(&iocb->list);
775 pring->txcmplq_cnt--;
776 break;
777 }
778 }
779
780 return (cmd_iocb);
781}
782
783static struct lpfc_iocbq *
784lpfc_sli_txcmpl_ring_iotag_lookup(struct lpfc_hba * phba,
785 struct lpfc_sli_ring * pring,
786 struct lpfc_iocbq * prspiocb)
787{
788 IOCB_t *irsp = NULL;
789 struct lpfc_iocbq *cmd_iocb = NULL; 797 struct lpfc_iocbq *cmd_iocb = NULL;
790 uint16_t iotag; 798 uint16_t iotag;
791 799
792 if (unlikely(pring->fast_lookup == NULL)) 800 iotag = prspiocb->iocb.ulpIoTag;
793 return NULL; 801
794 802 if (iotag != 0 && iotag <= phba->sli.last_iotag) {
795 /* Use fast lookup based on iotag for completion */ 803 cmd_iocb = phba->sli.iocbq_lookup[iotag];
796 irsp = &prspiocb->iocb; 804 list_del(&cmd_iocb->list);
797 iotag = irsp->ulpIoTag; 805 pring->txcmplq_cnt--;
798 if (iotag < pring->fast_iotag) { 806 return cmd_iocb;
799 cmd_iocb = *(pring->fast_lookup + iotag);
800 *(pring->fast_lookup + iotag) = NULL;
801 if (cmd_iocb) {
802 list_del(&cmd_iocb->list);
803 pring->txcmplq_cnt--;
804 return cmd_iocb;
805 } else {
806 /*
807 * This is clearly an error. A ring that uses iotags
808 * should never have a interrupt for a completion that
809 * is not on the ring. Return NULL and log a error.
810 */
811 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
812 "%d:0327 Rsp ring %d error - command "
813 "completion for iotag x%x not found\n",
814 phba->brd_no, pring->ringno, iotag);
815 return NULL;
816 }
817 } 807 }
818 808
819 /*
820 * Rsp ring <ringno> get: iotag <iotag> greater then
821 * configured max <fast_iotag> wd0 <irsp>. This is an
822 * error. Just return NULL.
823 */
824 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 809 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
825 "%d:0317 Rsp ring %d get: iotag x%x greater then " 810 "%d:0317 iotag x%x is out off "
826 "configured max x%x wd0 x%x\n", 811 "range: max iotag x%x wd0 x%x\n",
827 phba->brd_no, pring->ringno, iotag, pring->fast_iotag, 812 phba->brd_no, iotag,
828 *(((uint32_t *) irsp) + 7)); 813 phba->sli.last_iotag,
814 *(((uint32_t *) &prspiocb->iocb) + 7));
829 return NULL; 815 return NULL;
830} 816}
831 817
@@ -839,7 +825,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
839 825
840 /* Based on the iotag field, get the cmd IOCB from the txcmplq */ 826 /* Based on the iotag field, get the cmd IOCB from the txcmplq */
841 spin_lock_irqsave(phba->host->host_lock, iflag); 827 spin_lock_irqsave(phba->host->host_lock, iflag);
842 cmdiocbp = lpfc_sli_txcmpl_ring_search_slow(pring, saveq); 828 cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq);
843 if (cmdiocbp) { 829 if (cmdiocbp) {
844 if (cmdiocbp->iocb_cmpl) { 830 if (cmdiocbp->iocb_cmpl) {
845 /* 831 /*
@@ -861,9 +847,8 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
861 (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); 847 (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
862 spin_lock_irqsave(phba->host->host_lock, iflag); 848 spin_lock_irqsave(phba->host->host_lock, iflag);
863 } 849 }
864 } else { 850 } else
865 list_add_tail(&cmdiocbp->list, &phba->lpfc_iocb_list); 851 lpfc_sli_release_iocbq(phba, cmdiocbp);
866 }
867 } else { 852 } else {
868 /* 853 /*
869 * Unknown initiating command based on the response iotag. 854 * Unknown initiating command based on the response iotag.
@@ -990,9 +975,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
990 break; 975 break;
991 } 976 }
992 977
993 cmdiocbq = lpfc_sli_txcmpl_ring_iotag_lookup(phba, 978 cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
994 pring, 979 &rspiocbq);
995 &rspiocbq);
996 if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { 980 if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
997 spin_unlock_irqrestore( 981 spin_unlock_irqrestore(
998 phba->host->host_lock, iflag); 982 phba->host->host_lock, iflag);
@@ -1213,8 +1197,8 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
1213 } else if (type == LPFC_ABORT_IOCB) { 1197 } else if (type == LPFC_ABORT_IOCB) {
1214 if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) && 1198 if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) &&
1215 ((cmdiocbp = 1199 ((cmdiocbp =
1216 lpfc_sli_txcmpl_ring_search_slow(pring, 1200 lpfc_sli_iocbq_lookup(phba, pring,
1217 saveq)))) { 1201 saveq)))) {
1218 /* Call the specified completion 1202 /* Call the specified completion
1219 routine */ 1203 routine */
1220 if (cmdiocbp->iocb_cmpl) { 1204 if (cmdiocbp->iocb_cmpl) {
@@ -1226,10 +1210,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
1226 spin_lock_irqsave( 1210 spin_lock_irqsave(
1227 phba->host->host_lock, 1211 phba->host->host_lock,
1228 iflag); 1212 iflag);
1229 } else { 1213 } else
1230 list_add_tail(&cmdiocbp->list, 1214 lpfc_sli_release_iocbq(phba,
1231 lpfc_iocb_list); 1215 cmdiocbp);
1232 }
1233 } 1216 }
1234 } else if (type == LPFC_UNKNOWN_IOCB) { 1217 } else if (type == LPFC_UNKNOWN_IOCB) {
1235 if (irsp->ulpCommand == CMD_ADAPTER_MSG) { 1218 if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
@@ -1264,12 +1247,12 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
1264 next_iocb, 1247 next_iocb,
1265 &saveq->list, 1248 &saveq->list,
1266 list) { 1249 list) {
1267 list_add_tail(&rspiocbp->list, 1250 lpfc_sli_release_iocbq(phba,
1268 lpfc_iocb_list); 1251 rspiocbp);
1269 } 1252 }
1270 } 1253 }
1271 1254
1272 list_add_tail(&saveq->list, lpfc_iocb_list); 1255 lpfc_sli_release_iocbq(phba, saveq);
1273 } 1256 }
1274 } 1257 }
1275 1258
@@ -1314,7 +1297,6 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
1314 struct lpfc_iocbq *iocb, *next_iocb; 1297 struct lpfc_iocbq *iocb, *next_iocb;
1315 IOCB_t *icmd = NULL, *cmd = NULL; 1298 IOCB_t *icmd = NULL, *cmd = NULL;
1316 int errcnt; 1299 int errcnt;
1317 uint16_t iotag;
1318 1300
1319 errcnt = 0; 1301 errcnt = 0;
1320 1302
@@ -1331,9 +1313,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
1331 spin_unlock_irq(phba->host->host_lock); 1313 spin_unlock_irq(phba->host->host_lock);
1332 (iocb->iocb_cmpl) (phba, iocb, iocb); 1314 (iocb->iocb_cmpl) (phba, iocb, iocb);
1333 spin_lock_irq(phba->host->host_lock); 1315 spin_lock_irq(phba->host->host_lock);
1334 } else { 1316 } else
1335 list_add_tail(&iocb->list, &phba->lpfc_iocb_list); 1317 lpfc_sli_release_iocbq(phba, iocb);
1336 }
1337 } 1318 }
1338 pring->txq_cnt = 0; 1319 pring->txq_cnt = 0;
1339 INIT_LIST_HEAD(&(pring->txq)); 1320 INIT_LIST_HEAD(&(pring->txq));
@@ -1343,13 +1324,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
1343 cmd = &iocb->iocb; 1324 cmd = &iocb->iocb;
1344 1325
1345 /* 1326 /*
1346 * Imediate abort of IOCB, clear fast_lookup entry, 1327 * Imediate abort of IOCB, deque and call compl
1347 * if any, deque and call compl
1348 */ 1328 */
1349 iotag = cmd->ulpIoTag;
1350 if (iotag && pring->fast_lookup &&
1351 (iotag < pring->fast_iotag))
1352 pring->fast_lookup[iotag] = NULL;
1353 1329
1354 list_del_init(&iocb->list); 1330 list_del_init(&iocb->list);
1355 pring->txcmplq_cnt--; 1331 pring->txcmplq_cnt--;
@@ -1360,9 +1336,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
1360 spin_unlock_irq(phba->host->host_lock); 1336 spin_unlock_irq(phba->host->host_lock);
1361 (iocb->iocb_cmpl) (phba, iocb, iocb); 1337 (iocb->iocb_cmpl) (phba, iocb, iocb);
1362 spin_lock_irq(phba->host->host_lock); 1338 spin_lock_irq(phba->host->host_lock);
1363 } else { 1339 } else
1364 list_add_tail(&iocb->list, &phba->lpfc_iocb_list); 1340 lpfc_sli_release_iocbq(phba, iocb);
1365 }
1366 } 1341 }
1367 1342
1368 INIT_LIST_HEAD(&pring->txcmplq); 1343 INIT_LIST_HEAD(&pring->txcmplq);
@@ -2147,6 +2122,10 @@ lpfc_sli_setup(struct lpfc_hba *phba)
2147 psli->next_ring = LPFC_FCP_NEXT_RING; 2122 psli->next_ring = LPFC_FCP_NEXT_RING;
2148 psli->ip_ring = LPFC_IP_RING; 2123 psli->ip_ring = LPFC_IP_RING;
2149 2124
2125 psli->iocbq_lookup = NULL;
2126 psli->iocbq_lookup_len = 0;
2127 psli->last_iotag = 0;
2128
2150 for (i = 0; i < psli->num_rings; i++) { 2129 for (i = 0; i < psli->num_rings; i++) {
2151 pring = &psli->ring[i]; 2130 pring = &psli->ring[i];
2152 switch (i) { 2131 switch (i) {
@@ -2222,7 +2201,7 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
2222{ 2201{
2223 struct lpfc_sli *psli; 2202 struct lpfc_sli *psli;
2224 struct lpfc_sli_ring *pring; 2203 struct lpfc_sli_ring *pring;
2225 int i, cnt; 2204 int i;
2226 2205
2227 psli = &phba->sli; 2206 psli = &phba->sli;
2228 spin_lock_irq(phba->host->host_lock); 2207 spin_lock_irq(phba->host->host_lock);
@@ -2238,19 +2217,6 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
2238 INIT_LIST_HEAD(&pring->txcmplq); 2217 INIT_LIST_HEAD(&pring->txcmplq);
2239 INIT_LIST_HEAD(&pring->iocb_continueq); 2218 INIT_LIST_HEAD(&pring->iocb_continueq);
2240 INIT_LIST_HEAD(&pring->postbufq); 2219 INIT_LIST_HEAD(&pring->postbufq);
2241 cnt = pring->fast_iotag;
2242 spin_unlock_irq(phba->host->host_lock);
2243 if (cnt) {
2244 pring->fast_lookup =
2245 kmalloc(cnt * sizeof (struct lpfc_iocbq *),
2246 GFP_KERNEL);
2247 if (pring->fast_lookup == 0) {
2248 return (0);
2249 }
2250 memset((char *)pring->fast_lookup, 0,
2251 cnt * sizeof (struct lpfc_iocbq *));
2252 }
2253 spin_lock_irq(phba->host->host_lock);
2254 } 2220 }
2255 spin_unlock_irq(phba->host->host_lock); 2221 spin_unlock_irq(phba->host->host_lock);
2256 return (1); 2222 return (1);
@@ -2292,10 +2258,8 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
2292 flags); 2258 flags);
2293 (iocb->iocb_cmpl) (phba, iocb, iocb); 2259 (iocb->iocb_cmpl) (phba, iocb, iocb);
2294 spin_lock_irqsave(phba->host->host_lock, flags); 2260 spin_lock_irqsave(phba->host->host_lock, flags);
2295 } else { 2261 } else
2296 list_add_tail(&iocb->list, 2262 lpfc_sli_release_iocbq(phba, iocb);
2297 &phba->lpfc_iocb_list);
2298 }
2299 } 2263 }
2300 2264
2301 INIT_LIST_HEAD(&(pring->txq)); 2265 INIT_LIST_HEAD(&(pring->txq));
@@ -2436,7 +2400,7 @@ lpfc_sli_abort_elsreq_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
2436 kfree(buf_ptr); 2400 kfree(buf_ptr);
2437 } 2401 }
2438 2402
2439 list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); 2403 lpfc_sli_release_iocbq(phba, cmdiocb);
2440 return; 2404 return;
2441} 2405}
2442 2406
@@ -2454,7 +2418,6 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
2454 list_remove_head(lpfc_iocb_list, abtsiocbp, struct lpfc_iocbq, list); 2418 list_remove_head(lpfc_iocb_list, abtsiocbp, struct lpfc_iocbq, list);
2455 if (abtsiocbp == NULL) 2419 if (abtsiocbp == NULL)
2456 return 0; 2420 return 0;
2457 memset(abtsiocbp, 0, sizeof (struct lpfc_iocbq));
2458 2421
2459 iabt = &abtsiocbp->iocb; 2422 iabt = &abtsiocbp->iocb;
2460 icmd = &cmdiocb->iocb; 2423 icmd = &cmdiocb->iocb;
@@ -2473,7 +2436,7 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
2473 abtsiocbp->iocb_cmpl = lpfc_sli_abort_elsreq_cmpl; 2436 abtsiocbp->iocb_cmpl = lpfc_sli_abort_elsreq_cmpl;
2474 break; 2437 break;
2475 default: 2438 default:
2476 list_add_tail(&abtsiocbp->list, lpfc_iocb_list); 2439 lpfc_sli_release_iocbq(phba, abtsiocbp);
2477 return 0; 2440 return 0;
2478 } 2441 }
2479 2442
@@ -2485,7 +2448,7 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
2485 iabt->ulpCommand = CMD_ABORT_MXRI64_CN; 2448 iabt->ulpCommand = CMD_ABORT_MXRI64_CN;
2486 2449
2487 if (lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0) == IOCB_ERROR) { 2450 if (lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0) == IOCB_ERROR) {
2488 list_add_tail(&abtsiocbp->list, lpfc_iocb_list); 2451 lpfc_sli_release_iocbq(phba, abtsiocbp);
2489 return 0; 2452 return 0;
2490 } 2453 }
2491 2454
@@ -2563,7 +2526,7 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
2563 struct lpfc_iocbq * rspiocb) 2526 struct lpfc_iocbq * rspiocb)
2564{ 2527{
2565 spin_lock_irq(phba->host->host_lock); 2528 spin_lock_irq(phba->host->host_lock);
2566 list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); 2529 lpfc_sli_release_iocbq(phba, cmdiocb);
2567 spin_unlock_irq(phba->host->host_lock); 2530 spin_unlock_irq(phba->host->host_lock);
2568 return; 2531 return;
2569} 2532}
@@ -2604,7 +2567,6 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
2604 errcnt++; 2567 errcnt++;
2605 continue; 2568 continue;
2606 } 2569 }
2607 memset(abtsiocb, 0, sizeof (struct lpfc_iocbq));
2608 2570
2609 abtsiocb->iocb.un.acxri.abortType = ABORT_TYPE_ABTS; 2571 abtsiocb->iocb.un.acxri.abortType = ABORT_TYPE_ABTS;
2610 abtsiocb->iocb.un.acxri.abortContextTag = cmd->ulpContext; 2572 abtsiocb->iocb.un.acxri.abortContextTag = cmd->ulpContext;
@@ -2621,7 +2583,7 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
2621 abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; 2583 abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
2622 ret_val = lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0); 2584 ret_val = lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0);
2623 if (ret_val == IOCB_ERROR) { 2585 if (ret_val == IOCB_ERROR) {
2624 list_add_tail(&abtsiocb->list, lpfc_iocb_list); 2586 lpfc_sli_release_iocbq(phba, abtsiocb);
2625 errcnt++; 2587 errcnt++;
2626 continue; 2588 continue;
2627 } 2589 }
@@ -2635,8 +2597,9 @@ lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
2635 struct lpfc_iocbq * queue1, 2597 struct lpfc_iocbq * queue1,
2636 struct lpfc_iocbq * queue2) 2598 struct lpfc_iocbq * queue2)
2637{ 2599{
2638 if (queue1->context2 && queue2) 2600 struct lpfc_iocbq *save_iocbq = queue1->context2;
2639 memcpy(queue1->context2, queue2, sizeof (struct lpfc_iocbq)); 2601 if (save_iocbq && queue2)
2602 memcpy(&save_iocbq->iocb, &queue2->iocb, sizeof(queue2->iocb));
2640 2603
2641 /* The waiter is looking for LPFC_IO_HIPRI bit to be set 2604 /* The waiter is looking for LPFC_IO_HIPRI bit to be set
2642 as a signal to wake up */ 2605 as a signal to wake up */