aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c30
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c17
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c12
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c27
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c281
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h8
9 files changed, 187 insertions, 206 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index ffc58f9a5a59..25f2650f098c 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -143,6 +143,8 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
143int lpfc_mem_alloc(struct lpfc_hba *); 143int lpfc_mem_alloc(struct lpfc_hba *);
144void lpfc_mem_free(struct lpfc_hba *); 144void lpfc_mem_free(struct lpfc_hba *);
145 145
146void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
147uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
146int lpfc_sli_hba_setup(struct lpfc_hba *); 148int lpfc_sli_hba_setup(struct lpfc_hba *);
147int lpfc_sli_hba_down(struct lpfc_hba *); 149int lpfc_sli_hba_down(struct lpfc_hba *);
148int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); 150int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 1280f0e54636..40c34a30a94a 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -235,7 +235,6 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
235 235
236 if (geniocb == NULL) 236 if (geniocb == NULL)
237 return 1; 237 return 1;
238 memset(geniocb, 0, sizeof (struct lpfc_iocbq));
239 238
240 icmd = &geniocb->iocb; 239 icmd = &geniocb->iocb;
241 icmd->un.genreq64.bdl.ulpIoTag32 = 0; 240 icmd->un.genreq64.bdl.ulpIoTag32 = 0;
@@ -279,7 +278,7 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
279 geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; 278 geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
280 spin_lock_irq(phba->host->host_lock); 279 spin_lock_irq(phba->host->host_lock);
281 if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) { 280 if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) {
282 list_add_tail(&geniocb->list, lpfc_iocb_list); 281 lpfc_sli_release_iocbq(phba, geniocb);
283 spin_unlock_irq(phba->host->host_lock); 282 spin_unlock_irq(phba->host->host_lock);
284 return 1; 283 return 1;
285 } 284 }
@@ -487,7 +486,7 @@ out:
487 kfree(inp); 486 kfree(inp);
488 kfree(bmp); 487 kfree(bmp);
489 spin_lock_irq(phba->host->host_lock); 488 spin_lock_irq(phba->host->host_lock);
490 list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); 489 lpfc_sli_release_iocbq(phba, cmdiocb);
491 spin_unlock_irq(phba->host->host_lock); 490 spin_unlock_irq(phba->host->host_lock);
492 return; 491 return;
493} 492}
@@ -526,7 +525,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
526 kfree(inp); 525 kfree(inp);
527 kfree(bmp); 526 kfree(bmp);
528 spin_lock_irq(phba->host->host_lock); 527 spin_lock_irq(phba->host->host_lock);
529 list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); 528 lpfc_sli_release_iocbq(phba, cmdiocb);
530 spin_unlock_irq(phba->host->host_lock); 529 spin_unlock_irq(phba->host->host_lock);
531 return; 530 return;
532} 531}
@@ -735,7 +734,7 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
735 kfree(inp); 734 kfree(inp);
736 kfree(bmp); 735 kfree(bmp);
737 spin_lock_irq(phba->host->host_lock); 736 spin_lock_irq(phba->host->host_lock);
738 list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); 737 lpfc_sli_release_iocbq(phba, cmdiocb);
739 spin_unlock_irq(phba->host->host_lock); 738 spin_unlock_irq(phba->host->host_lock);
740 return; 739 return;
741} 740}
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;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index cd06d4c471ac..259eeb161b82 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1445,10 +1445,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1445 iocb, iocb); 1445 iocb, iocb);
1446 spin_lock_irq(phba->host-> 1446 spin_lock_irq(phba->host->
1447 host_lock); 1447 host_lock);
1448 } else { 1448 } else
1449 list_add_tail(&iocb->list, 1449 lpfc_sli_release_iocbq(phba,
1450 &phba->lpfc_iocb_list); 1450 iocb);
1451 }
1452 } 1451 }
1453 } 1452 }
1454 spin_unlock_irq(phba->host->host_lock); 1453 spin_unlock_irq(phba->host->host_lock);
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index e591611f98e2..59e244f04c32 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -886,7 +886,6 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
886 pring->missbufcnt = cnt; 886 pring->missbufcnt = cnt;
887 return cnt; 887 return cnt;
888 } 888 }
889 memset(iocb, 0, sizeof (struct lpfc_iocbq));
890 icmd = &iocb->iocb; 889 icmd = &iocb->iocb;
891 890
892 /* 2 buffers can be posted per command */ 891 /* 2 buffers can be posted per command */
@@ -899,7 +898,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
899 if (mp1) 898 if (mp1)
900 kfree(mp1); 899 kfree(mp1);
901 spin_lock_irq(phba->host->host_lock); 900 spin_lock_irq(phba->host->host_lock);
902 list_add_tail(&iocb->list, lpfc_iocb_list); 901 lpfc_sli_release_iocbq(phba, iocb);
903 spin_unlock_irq(phba->host->host_lock); 902 spin_unlock_irq(phba->host->host_lock);
904 pring->missbufcnt = cnt; 903 pring->missbufcnt = cnt;
905 return cnt; 904 return cnt;
@@ -918,7 +917,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
918 lpfc_mbuf_free(phba, mp1->virt, mp1->phys); 917 lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
919 kfree(mp1); 918 kfree(mp1);
920 spin_lock_irq(phba->host->host_lock); 919 spin_lock_irq(phba->host->host_lock);
921 list_add_tail(&iocb->list, lpfc_iocb_list); 920 lpfc_sli_release_iocbq(phba, iocb);
922 spin_unlock_irq(phba->host->host_lock); 921 spin_unlock_irq(phba->host->host_lock);
923 pring->missbufcnt = cnt; 922 pring->missbufcnt = cnt;
924 return cnt; 923 return cnt;
@@ -955,7 +954,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
955 kfree(mp2); 954 kfree(mp2);
956 cnt++; 955 cnt++;
957 } 956 }
958 list_add_tail(&iocb->list, lpfc_iocb_list); 957 lpfc_sli_release_iocbq(phba, iocb);
959 pring->missbufcnt = cnt; 958 pring->missbufcnt = cnt;
960 spin_unlock_irq(phba->host->host_lock); 959 spin_unlock_irq(phba->host->host_lock);
961 return cnt; 960 return cnt;
@@ -1328,6 +1327,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
1328 unsigned long bar0map_len, bar2map_len; 1327 unsigned long bar0map_len, bar2map_len;
1329 int error = -ENODEV, retval; 1328 int error = -ENODEV, retval;
1330 int i; 1329 int i;
1330 uint16_t iotag;
1331 1331
1332 if (pci_enable_device(pdev)) 1332 if (pci_enable_device(pdev))
1333 goto out; 1333 goto out;
@@ -1452,6 +1452,15 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
1452 } 1452 }
1453 1453
1454 memset(iocbq_entry, 0, sizeof(struct lpfc_iocbq)); 1454 memset(iocbq_entry, 0, sizeof(struct lpfc_iocbq));
1455 iotag = lpfc_sli_next_iotag(phba, iocbq_entry);
1456 if (iotag == 0) {
1457 kfree (iocbq_entry);
1458 printk(KERN_ERR "%s: failed to allocate IOTAG. "
1459 "Unloading driver.\n",
1460 __FUNCTION__);
1461 error = -ENOMEM;
1462 goto out_free_iocbq;
1463 }
1455 spin_lock_irq(phba->host->host_lock); 1464 spin_lock_irq(phba->host->host_lock);
1456 list_add(&iocbq_entry->list, &phba->lpfc_iocb_list); 1465 list_add(&iocbq_entry->list, &phba->lpfc_iocb_list);
1457 phba->total_iocbq_bufs++; 1466 phba->total_iocbq_bufs++;
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 9a58de876d40..507a6af56f42 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -187,10 +187,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
187 spin_unlock_irq(phba->host->host_lock); 187 spin_unlock_irq(phba->host->host_lock);
188 (iocb->iocb_cmpl) (phba, iocb, iocb); 188 (iocb->iocb_cmpl) (phba, iocb, iocb);
189 spin_lock_irq(phba->host->host_lock); 189 spin_lock_irq(phba->host->host_lock);
190 } else { 190 } else
191 list_add_tail(&iocb->list, 191 lpfc_sli_release_iocbq(phba, iocb);
192 &phba->lpfc_iocb_list);
193 }
194 break; 192 break;
195 } 193 }
196 } 194 }
@@ -232,10 +230,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
232 spin_unlock_irq(phba->host->host_lock); 230 spin_unlock_irq(phba->host->host_lock);
233 (iocb->iocb_cmpl) (phba, iocb, iocb); 231 (iocb->iocb_cmpl) (phba, iocb, iocb);
234 spin_lock_irq(phba->host->host_lock); 232 spin_lock_irq(phba->host->host_lock);
235 } else { 233 } else
236 list_add_tail(&iocb->list, 234 lpfc_sli_release_iocbq(phba, iocb);
237 &phba->lpfc_iocb_list);
238 }
239 break; 235 break;
240 } 236 }
241 } 237 }
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c55ab1a630e5..51c6b677490c 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -56,6 +56,7 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
56 struct ulp_bde64 *bpl; 56 struct ulp_bde64 *bpl;
57 IOCB_t *iocb; 57 IOCB_t *iocb;
58 dma_addr_t pdma_phys; 58 dma_addr_t pdma_phys;
59 uint16_t iotag;
59 60
60 psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); 61 psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL);
61 if (!psb) 62 if (!psb)
@@ -79,6 +80,15 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
79 /* Initialize virtual ptrs to dma_buf region. */ 80 /* Initialize virtual ptrs to dma_buf region. */
80 memset(psb->data, 0, phba->cfg_sg_dma_buf_size); 81 memset(psb->data, 0, phba->cfg_sg_dma_buf_size);
81 82
83 /* Allocate iotag for psb->cur_iocbq. */
84 iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq);
85 if (iotag == 0) {
86 pci_pool_free(phba->lpfc_scsi_dma_buf_pool,
87 psb->data, psb->dma_handle);
88 kfree (psb);
89 return NULL;
90 }
91
82 psb->fcp_cmnd = psb->data; 92 psb->fcp_cmnd = psb->data;
83 psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd); 93 psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd);
84 psb->fcp_bpl = psb->data + sizeof(struct fcp_cmnd) + 94 psb->fcp_bpl = psb->data + sizeof(struct fcp_cmnd) +
@@ -626,7 +636,6 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
626 list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list); 636 list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list);
627 if (!iocbqrsp) 637 if (!iocbqrsp)
628 return FAILED; 638 return FAILED;
629 memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq));
630 639
631 iocbq->iocb_flag |= LPFC_IO_POLL; 640 iocbq->iocb_flag |= LPFC_IO_POLL;
632 ret = lpfc_sli_issue_iocb_wait_high_priority(phba, 641 ret = lpfc_sli_issue_iocb_wait_high_priority(phba,
@@ -655,8 +664,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
655 lpfc_cmd->pCmd->device->id, 664 lpfc_cmd->pCmd->device->id,
656 lpfc_cmd->pCmd->device->lun, 0, LPFC_CTX_TGT); 665 lpfc_cmd->pCmd->device->lun, 0, LPFC_CTX_TGT);
657 666
658 /* Return response IOCB to free list. */ 667 lpfc_sli_release_iocbq(phba, iocbqrsp);
659 list_add_tail(&iocbqrsp->list, lpfc_iocb_list);
660 return ret; 668 return ret;
661} 669}
662 670
@@ -818,9 +826,8 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
818 826
819 list_del_init(&iocb->list); 827 list_del_init(&iocb->list);
820 pring->txq_cnt--; 828 pring->txq_cnt--;
821 if (!iocb->iocb_cmpl) { 829 if (!iocb->iocb_cmpl)
822 list_add_tail(&iocb->list, lpfc_iocb_list); 830 lpfc_sli_release_iocbq(phba, iocb);
823 }
824 else { 831 else {
825 cmd->ulpStatus = IOSTAT_LOCAL_REJECT; 832 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
826 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; 833 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
@@ -834,8 +841,6 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
834 if (abtsiocb == NULL) 841 if (abtsiocb == NULL)
835 return FAILED; 842 return FAILED;
836 843
837 memset(abtsiocb, 0, sizeof (struct lpfc_iocbq));
838
839 /* 844 /*
840 * The scsi command was not in the txq. Check the txcmplq and if it is 845 * The scsi command was not in the txq. Check the txcmplq and if it is
841 * found, send an abort to the FW. 846 * found, send an abort to the FW.
@@ -861,7 +866,7 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
861 abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; 866 abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
862 if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == 867 if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) ==
863 IOCB_ERROR) { 868 IOCB_ERROR) {
864 list_add_tail(&abtsiocb->list, lpfc_iocb_list); 869 lpfc_sli_release_iocbq(phba, abtsiocb);
865 ret = IOCB_ERROR; 870 ret = IOCB_ERROR;
866 break; 871 break;
867 } 872 }
@@ -964,8 +969,6 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
964 if (iocbqrsp == NULL) 969 if (iocbqrsp == NULL)
965 goto out_free_scsi_buf; 970 goto out_free_scsi_buf;
966 971
967 memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq));
968
969 iocbq->iocb_flag |= LPFC_IO_POLL; 972 iocbq->iocb_flag |= LPFC_IO_POLL;
970 iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority; 973 iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;
971 974
@@ -1011,7 +1014,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
1011 phba->brd_no, cnt); 1014 phba->brd_no, cnt);
1012 } 1015 }
1013 1016
1014 list_add_tail(&iocbqrsp->list, lpfc_iocb_list); 1017 lpfc_sli_release_iocbq(phba, iocbqrsp);
1015 1018
1016out_free_scsi_buf: 1019out_free_scsi_buf:
1017 lpfc_printf_log(phba, KERN_ERR, LOG_FCP, 1020 lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
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 */
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 2d5b0670415c..5d8911de4faa 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -33,6 +33,9 @@ typedef enum _lpfc_ctx_cmd {
33struct lpfc_iocbq { 33struct lpfc_iocbq {
34 /* lpfc_iocbqs are used in double linked lists */ 34 /* lpfc_iocbqs are used in double linked lists */
35 struct list_head list; 35 struct list_head list;
36 uint16_t iotag; /* pre-assigned IO tag */
37 uint16_t rsvd1;
38
36 IOCB_t iocb; /* IOCB cmd */ 39 IOCB_t iocb; /* IOCB cmd */
37 uint8_t retry; /* retry counter for IOCB cmd - if needed */ 40 uint8_t retry; /* retry counter for IOCB cmd - if needed */
38 uint8_t iocb_flag; 41 uint8_t iocb_flag;
@@ -200,6 +203,11 @@ struct lpfc_sli {
200 cmd */ 203 cmd */
201 204
202 uint32_t *MBhostaddr; /* virtual address for mbox cmds */ 205 uint32_t *MBhostaddr; /* virtual address for mbox cmds */
206
207#define LPFC_IOCBQ_LOOKUP_INCREMENT 1024
208 struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */
209 size_t iocbq_lookup_len; /* current lengs of the array */
210 uint16_t last_iotag; /* last allocated IOTAG */
203}; 211};
204 212
205/* Given a pointer to the start of the ring, and the slot number of 213/* Given a pointer to the start of the ring, and the slot number of