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_scsi.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_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 27 |
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 | ||
1016 | out_free_scsi_buf: | 1019 | out_free_scsi_buf: |
1017 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1020 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |