aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.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_scsi.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_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c27
1 files changed, 15 insertions, 12 deletions
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,