Commit 604a3e30 authored by James Bottomley's avatar James Bottomley

[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: default avatarJames Smart <James.Smart@emulex.com>

Rejections fixed up and
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 21568f53
...@@ -143,6 +143,8 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); ...@@ -143,6 +143,8 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
int lpfc_mem_alloc(struct lpfc_hba *); int lpfc_mem_alloc(struct lpfc_hba *);
void lpfc_mem_free(struct lpfc_hba *); void lpfc_mem_free(struct lpfc_hba *);
void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
int lpfc_sli_hba_setup(struct lpfc_hba *); int lpfc_sli_hba_setup(struct lpfc_hba *);
int lpfc_sli_hba_down(struct lpfc_hba *); int lpfc_sli_hba_down(struct lpfc_hba *);
int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
......
...@@ -235,7 +235,6 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, ...@@ -235,7 +235,6 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
if (geniocb == NULL) if (geniocb == NULL)
return 1; return 1;
memset(geniocb, 0, sizeof (struct lpfc_iocbq));
icmd = &geniocb->iocb; icmd = &geniocb->iocb;
icmd->un.genreq64.bdl.ulpIoTag32 = 0; icmd->un.genreq64.bdl.ulpIoTag32 = 0;
...@@ -279,7 +278,7 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, ...@@ -279,7 +278,7 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) { if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) {
list_add_tail(&geniocb->list, lpfc_iocb_list); lpfc_sli_release_iocbq(phba, geniocb);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return 1; return 1;
} }
...@@ -487,7 +486,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -487,7 +486,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
kfree(inp); kfree(inp);
kfree(bmp); kfree(bmp);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return; return;
} }
...@@ -526,7 +525,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -526,7 +525,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
kfree(inp); kfree(inp);
kfree(bmp); kfree(bmp);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return; return;
} }
...@@ -735,7 +734,7 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, ...@@ -735,7 +734,7 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
kfree(inp); kfree(inp);
kfree(bmp); kfree(bmp);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list); lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return; return;
} }
......
...@@ -122,7 +122,6 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, ...@@ -122,7 +122,6 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
if (elsiocb == NULL) if (elsiocb == NULL)
return NULL; return NULL;
memset(elsiocb, 0, sizeof (struct lpfc_iocbq));
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
/* fill in BDEs for command */ /* fill in BDEs for command */
...@@ -133,7 +132,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, ...@@ -133,7 +132,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
if (pcmd) if (pcmd)
kfree(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; return NULL;
} }
...@@ -150,7 +151,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, ...@@ -150,7 +151,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
kfree(prsp); kfree(prsp);
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
kfree(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; return NULL;
} }
INIT_LIST_HEAD(&prsp->list); INIT_LIST_HEAD(&prsp->list);
...@@ -164,7 +167,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, ...@@ -164,7 +167,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
&pbuflist->phys); &pbuflist->phys);
if (pbuflist == 0 || pbuflist->virt == 0) { 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, pcmd->virt, pcmd->phys);
lpfc_mbuf_free(phba, prsp->virt, prsp->phys); lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
kfree(pcmd); kfree(pcmd);
...@@ -596,10 +601,8 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba) ...@@ -596,10 +601,8 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba)
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb); (iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
} else { } else
list_add_tail(&iocb->list, lpfc_sli_release_iocbq(phba, iocb);
&phba->lpfc_iocb_list);
}
} }
} }
} }
...@@ -1713,7 +1716,7 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb) ...@@ -1713,7 +1716,7 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb)
kfree(buf_ptr); kfree(buf_ptr);
} }
spin_lock_irq(phba->host->host_lock); 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); spin_unlock_irq(phba->host->host_lock);
return 0; return 0;
} }
...@@ -2929,9 +2932,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) ...@@ -2929,9 +2932,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
(piocb->iocb_cmpl) (phba, piocb, piocb); (piocb->iocb_cmpl) (phba, piocb, piocb);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
} else { } else
list_add_tail(&piocb->list, &phba->lpfc_iocb_list); lpfc_sli_release_iocbq(phba, piocb);
}
} }
if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) { if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
phba->els_tmofunc.expires = jiffies + HZ * timeout; phba->els_tmofunc.expires = jiffies + HZ * timeout;
...@@ -2996,7 +2998,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) ...@@ -2996,7 +2998,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
} }
else 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) { list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
...@@ -3033,7 +3035,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) ...@@ -3033,7 +3035,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
} }
else else
list_add_tail(&piocb->list, &phba->lpfc_iocb_list); lpfc_sli_release_iocbq(phba, piocb);
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return; return;
......
...@@ -1445,10 +1445,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1445,10 +1445,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
iocb, iocb); iocb, iocb);
spin_lock_irq(phba->host-> spin_lock_irq(phba->host->
host_lock); host_lock);
} else { } else
list_add_tail(&iocb->list, lpfc_sli_release_iocbq(phba,
&phba->lpfc_iocb_list); iocb);
}
} }
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
......
...@@ -886,7 +886,6 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, ...@@ -886,7 +886,6 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
pring->missbufcnt = cnt; pring->missbufcnt = cnt;
return cnt; return cnt;
} }
memset(iocb, 0, sizeof (struct lpfc_iocbq));
icmd = &iocb->iocb; icmd = &iocb->iocb;
/* 2 buffers can be posted per command */ /* 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,7 +898,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
if (mp1) if (mp1)
kfree(mp1); kfree(mp1);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
list_add_tail(&iocb->list, lpfc_iocb_list); lpfc_sli_release_iocbq(phba, iocb);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
pring->missbufcnt = cnt; pring->missbufcnt = cnt;
return cnt; return cnt;
...@@ -918,7 +917,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, ...@@ -918,7 +917,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
lpfc_mbuf_free(phba, mp1->virt, mp1->phys); lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
kfree(mp1); kfree(mp1);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
list_add_tail(&iocb->list, lpfc_iocb_list); lpfc_sli_release_iocbq(phba, iocb);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
pring->missbufcnt = cnt; pring->missbufcnt = cnt;
return cnt; return cnt;
...@@ -955,7 +954,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, ...@@ -955,7 +954,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
kfree(mp2); kfree(mp2);
cnt++; cnt++;
} }
list_add_tail(&iocb->list, lpfc_iocb_list); lpfc_sli_release_iocbq(phba, iocb);
pring->missbufcnt = cnt; pring->missbufcnt = cnt;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return cnt; return cnt;
...@@ -1328,6 +1327,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -1328,6 +1327,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
unsigned long bar0map_len, bar2map_len; unsigned long bar0map_len, bar2map_len;
int error = -ENODEV, retval; int error = -ENODEV, retval;
int i; int i;
uint16_t iotag;
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
goto out; goto out;
...@@ -1452,6 +1452,15 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -1452,6 +1452,15 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
} }
memset(iocbq_entry, 0, sizeof(struct lpfc_iocbq)); memset(iocbq_entry, 0, sizeof(struct lpfc_iocbq));
iotag = lpfc_sli_next_iotag(phba, iocbq_entry);
if (iotag == 0) {
kfree (iocbq_entry);
printk(KERN_ERR "%s: failed to allocate IOTAG. "
"Unloading driver.\n",
__FUNCTION__);
error = -ENOMEM;
goto out_free_iocbq;
}
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
list_add(&iocbq_entry->list, &phba->lpfc_iocb_list); list_add(&iocbq_entry->list, &phba->lpfc_iocb_list);
phba->total_iocbq_bufs++; phba->total_iocbq_bufs++;
......
...@@ -187,10 +187,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -187,10 +187,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb); (iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
} else { } else
list_add_tail(&iocb->list, lpfc_sli_release_iocbq(phba, iocb);
&phba->lpfc_iocb_list);
}
break; break;
} }
} }
...@@ -232,10 +230,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -232,10 +230,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb); (iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
} else { } else
list_add_tail(&iocb->list, lpfc_sli_release_iocbq(phba, iocb);
&phba->lpfc_iocb_list);
}
break; break;
} }
} }
......
...@@ -56,6 +56,7 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) ...@@ -56,6 +56,7 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
struct ulp_bde64 *bpl; struct ulp_bde64 *bpl;
IOCB_t *iocb; IOCB_t *iocb;
dma_addr_t pdma_phys; dma_addr_t pdma_phys;
uint16_t iotag;
psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL);
if (!psb) if (!psb)
...@@ -79,6 +80,15 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) ...@@ -79,6 +80,15 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
/* Initialize virtual ptrs to dma_buf region. */ /* Initialize virtual ptrs to dma_buf region. */
memset(psb->data, 0, phba->cfg_sg_dma_buf_size); memset(psb->data, 0, phba->cfg_sg_dma_buf_size);
/* Allocate iotag for psb->cur_iocbq. */
iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq);
if (iotag == 0) {
pci_pool_free(phba->lpfc_scsi_dma_buf_pool,
psb->data, psb->dma_handle);
kfree (psb);
return NULL;
}
psb->fcp_cmnd = psb->data; psb->fcp_cmnd = psb->data;
psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd); psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd);
psb->fcp_bpl = psb->data + sizeof(struct fcp_cmnd) + 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,7 +636,6 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list); list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list);
if (!iocbqrsp) if (!iocbqrsp)
return FAILED; return FAILED;
memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq));
iocbq->iocb_flag |= LPFC_IO_POLL; iocbq->iocb_flag |= LPFC_IO_POLL;
ret = lpfc_sli_issue_iocb_wait_high_priority(phba, 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,8 +664,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
lpfc_cmd->pCmd->device->id, lpfc_cmd->pCmd->device->id,
lpfc_cmd->pCmd->device->lun, 0, LPFC_CTX_TGT); lpfc_cmd->pCmd->device->lun, 0, LPFC_CTX_TGT);
/* Return response IOCB to free list. */ lpfc_sli_release_iocbq(phba, iocbqrsp);
list_add_tail(&iocbqrsp->list, lpfc_iocb_list);
return ret; return ret;
} }
...@@ -818,9 +826,8 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd) ...@@ -818,9 +826,8 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
list_del_init(&iocb->list); list_del_init(&iocb->list);
pring->txq_cnt--; pring->txq_cnt--;
if (!iocb->iocb_cmpl) { if (!iocb->iocb_cmpl)
list_add_tail(&iocb->list, lpfc_iocb_list); lpfc_sli_release_iocbq(phba, iocb);
}
else { else {
cmd->ulpStatus = IOSTAT_LOCAL_REJECT; cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
...@@ -834,8 +841,6 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd) ...@@ -834,8 +841,6 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
if (abtsiocb == NULL) if (abtsiocb == NULL)
return FAILED; return FAILED;
memset(abtsiocb, 0, sizeof (struct lpfc_iocbq));
/* /*
* The scsi command was not in the txq. Check the txcmplq and if it is * The scsi command was not in the txq. Check the txcmplq and if it is
* found, send an abort to the FW. * found, send an abort to the FW.
...@@ -861,7 +866,7 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd) ...@@ -861,7 +866,7 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) ==
IOCB_ERROR) { IOCB_ERROR) {
list_add_tail(&abtsiocb->list, lpfc_iocb_list); lpfc_sli_release_iocbq(phba, abtsiocb);
ret = IOCB_ERROR; ret = IOCB_ERROR;
break; break;
} }
...@@ -964,8 +969,6 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) ...@@ -964,8 +969,6 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
if (iocbqrsp == NULL) if (iocbqrsp == NULL)
goto out_free_scsi_buf; goto out_free_scsi_buf;
memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq));
iocbq->iocb_flag |= LPFC_IO_POLL; iocbq->iocb_flag |= LPFC_IO_POLL;
iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority; iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;
...@@ -1011,7 +1014,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) ...@@ -1011,7 +1014,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
phba->brd_no, cnt); phba->brd_no, cnt);
} }
list_add_tail(&iocbqrsp->list, lpfc_iocb_list); lpfc_sli_release_iocbq(phba, iocbqrsp);
out_free_scsi_buf: out_free_scsi_buf:
lpfc_printf_log(phba, KERN_ERR, LOG_FCP, lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
......
This diff is collapsed.
...@@ -33,6 +33,9 @@ typedef enum _lpfc_ctx_cmd { ...@@ -33,6 +33,9 @@ typedef enum _lpfc_ctx_cmd {
struct lpfc_iocbq { struct lpfc_iocbq {
/* lpfc_iocbqs are used in double linked lists */ /* lpfc_iocbqs are used in double linked lists */
struct list_head list; struct list_head list;
uint16_t iotag; /* pre-assigned IO tag */
uint16_t rsvd1;
IOCB_t iocb; /* IOCB cmd */ IOCB_t iocb; /* IOCB cmd */
uint8_t retry; /* retry counter for IOCB cmd - if needed */ uint8_t retry; /* retry counter for IOCB cmd - if needed */
uint8_t iocb_flag; uint8_t iocb_flag;
...@@ -200,6 +203,11 @@ struct lpfc_sli { ...@@ -200,6 +203,11 @@ struct lpfc_sli {
cmd */ cmd */
uint32_t *MBhostaddr; /* virtual address for mbox cmds */ uint32_t *MBhostaddr; /* virtual address for mbox cmds */
#define LPFC_IOCBQ_LOOKUP_INCREMENT 1024
struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */
size_t iocbq_lookup_len; /* current lengs of the array */
uint16_t last_iotag; /* last allocated IOTAG */
}; };
/* Given a pointer to the start of the ring, and the slot number of /* Given a pointer to the start of the ring, and the slot number of
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment