diff options
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 251 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 103 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.h | 1 |
7 files changed, 155 insertions, 217 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index e16025d76aa..d527d05a607 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -143,6 +143,7 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); | |||
143 | int lpfc_mem_alloc(struct lpfc_hba *); | 143 | int lpfc_mem_alloc(struct lpfc_hba *); |
144 | void lpfc_mem_free(struct lpfc_hba *); | 144 | void lpfc_mem_free(struct lpfc_hba *); |
145 | 145 | ||
146 | struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); | ||
146 | void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | 147 | void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); |
147 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | 148 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); |
148 | int lpfc_sli_hba_setup(struct lpfc_hba *); | 149 | int lpfc_sli_hba_setup(struct lpfc_hba *); |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 40c34a30a94..7f427f9c468 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -224,13 +224,12 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, | |||
224 | 224 | ||
225 | struct lpfc_sli *psli = &phba->sli; | 225 | struct lpfc_sli *psli = &phba->sli; |
226 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; | 226 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; |
227 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | ||
228 | IOCB_t *icmd; | 227 | IOCB_t *icmd; |
229 | struct lpfc_iocbq *geniocb = NULL; | 228 | struct lpfc_iocbq *geniocb; |
230 | 229 | ||
231 | /* Allocate buffer for command iocb */ | 230 | /* Allocate buffer for command iocb */ |
232 | spin_lock_irq(phba->host->host_lock); | 231 | spin_lock_irq(phba->host->host_lock); |
233 | list_remove_head(lpfc_iocb_list, geniocb, struct lpfc_iocbq, list); | 232 | geniocb = lpfc_sli_get_iocbq(phba); |
234 | spin_unlock_irq(phba->host->host_lock); | 233 | spin_unlock_irq(phba->host->host_lock); |
235 | 234 | ||
236 | if (geniocb == NULL) | 235 | if (geniocb == NULL) |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index e931ae6e746..08a0c00cfc3 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -102,9 +102,8 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, | |||
102 | uint16_t cmdSize, | 102 | uint16_t cmdSize, |
103 | uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd) | 103 | uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd) |
104 | { | 104 | { |
105 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | ||
106 | struct lpfc_sli_ring *pring; | 105 | struct lpfc_sli_ring *pring; |
107 | struct lpfc_iocbq *elsiocb = NULL; | 106 | struct lpfc_iocbq *elsiocb; |
108 | struct lpfc_dmabuf *pcmd, *prsp, *pbuflist; | 107 | struct lpfc_dmabuf *pcmd, *prsp, *pbuflist; |
109 | struct ulp_bde64 *bpl; | 108 | struct ulp_bde64 *bpl; |
110 | IOCB_t *icmd; | 109 | IOCB_t *icmd; |
@@ -114,10 +113,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, | |||
114 | if (phba->hba_state < LPFC_LINK_UP) | 113 | if (phba->hba_state < LPFC_LINK_UP) |
115 | return NULL; | 114 | return NULL; |
116 | 115 | ||
117 | |||
118 | /* Allocate buffer for command iocb */ | 116 | /* Allocate buffer for command iocb */ |
119 | spin_lock_irq(phba->host->host_lock); | 117 | spin_lock_irq(phba->host->host_lock); |
120 | list_remove_head(lpfc_iocb_list, elsiocb, struct lpfc_iocbq, list); | 118 | elsiocb = lpfc_sli_get_iocbq(phba); |
121 | spin_unlock_irq(phba->host->host_lock); | 119 | spin_unlock_irq(phba->host->host_lock); |
122 | 120 | ||
123 | if (elsiocb == NULL) | 121 | if (elsiocb == NULL) |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 59e244f04c3..27390aa0858 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -870,8 +870,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
870 | int type) | 870 | int type) |
871 | { | 871 | { |
872 | IOCB_t *icmd; | 872 | IOCB_t *icmd; |
873 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | 873 | struct lpfc_iocbq *iocb; |
874 | struct lpfc_iocbq *iocb = NULL; | ||
875 | struct lpfc_dmabuf *mp1, *mp2; | 874 | struct lpfc_dmabuf *mp1, *mp2; |
876 | 875 | ||
877 | cnt += pring->missbufcnt; | 876 | cnt += pring->missbufcnt; |
@@ -880,7 +879,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
880 | while (cnt > 0) { | 879 | while (cnt > 0) { |
881 | /* Allocate buffer for command iocb */ | 880 | /* Allocate buffer for command iocb */ |
882 | spin_lock_irq(phba->host->host_lock); | 881 | spin_lock_irq(phba->host->host_lock); |
883 | list_remove_head(lpfc_iocb_list, iocb, struct lpfc_iocbq, list); | 882 | iocb = lpfc_sli_get_iocbq(phba); |
884 | spin_unlock_irq(phba->host->host_lock); | 883 | spin_unlock_irq(phba->host->host_lock); |
885 | if (iocb == NULL) { | 884 | if (iocb == NULL) { |
886 | pring->missbufcnt = cnt; | 885 | pring->missbufcnt = cnt; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index b903d3b7b73..c34d3cf4f19 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -50,7 +50,7 @@ | |||
50 | * and the BPL BDE is setup in the IOCB. | 50 | * and the BPL BDE is setup in the IOCB. |
51 | */ | 51 | */ |
52 | static struct lpfc_scsi_buf * | 52 | static struct lpfc_scsi_buf * |
53 | lpfc_get_scsi_buf(struct lpfc_hba * phba) | 53 | lpfc_new_scsi_buf(struct lpfc_hba * phba) |
54 | { | 54 | { |
55 | struct lpfc_scsi_buf *psb; | 55 | struct lpfc_scsi_buf *psb; |
56 | struct ulp_bde64 *bpl; | 56 | struct ulp_bde64 *bpl; |
@@ -88,6 +88,7 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) | |||
88 | kfree (psb); | 88 | kfree (psb); |
89 | return NULL; | 89 | return NULL; |
90 | } | 90 | } |
91 | psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP; | ||
91 | 92 | ||
92 | psb->fcp_cmnd = psb->data; | 93 | psb->fcp_cmnd = psb->data; |
93 | psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd); | 94 | psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd); |
@@ -135,11 +136,19 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) | |||
135 | return psb; | 136 | return psb; |
136 | } | 137 | } |
137 | 138 | ||
138 | static void | 139 | struct lpfc_scsi_buf* |
139 | lpfc_free_scsi_buf(struct lpfc_scsi_buf * psb) | 140 | lpfc_sli_get_scsi_buf(struct lpfc_hba * phba) |
140 | { | 141 | { |
141 | struct lpfc_hba *phba = psb->scsi_hba; | 142 | struct lpfc_scsi_buf * lpfc_cmd = NULL; |
143 | struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; | ||
144 | |||
145 | list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); | ||
146 | return lpfc_cmd; | ||
147 | } | ||
142 | 148 | ||
149 | static void | ||
150 | lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) | ||
151 | { | ||
143 | /* | 152 | /* |
144 | * There are only two special cases to consider. (1) the scsi command | 153 | * There are only two special cases to consider. (1) the scsi command |
145 | * requested scatter-gather usage or (2) the scsi command allocated | 154 | * requested scatter-gather usage or (2) the scsi command allocated |
@@ -157,6 +166,7 @@ lpfc_free_scsi_buf(struct lpfc_scsi_buf * psb) | |||
157 | } | 166 | } |
158 | } | 167 | } |
159 | 168 | ||
169 | psb->pCmd = NULL; | ||
160 | list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list); | 170 | list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list); |
161 | } | 171 | } |
162 | 172 | ||
@@ -431,12 +441,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
431 | *lp, *(lp + 3), cmd->retries, cmd->resid); | 441 | *lp, *(lp + 3), cmd->retries, cmd->resid); |
432 | } | 442 | } |
433 | 443 | ||
444 | cmd->scsi_done(cmd); | ||
445 | |||
434 | spin_lock_irqsave(phba->host->host_lock, iflag); | 446 | spin_lock_irqsave(phba->host->host_lock, iflag); |
435 | lpfc_free_scsi_buf(lpfc_cmd); | 447 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
436 | cmd->host_scribble = NULL; | ||
437 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 448 | spin_unlock_irqrestore(phba->host->host_lock, iflag); |
438 | |||
439 | cmd->scsi_done(cmd); | ||
440 | } | 449 | } |
441 | 450 | ||
442 | static void | 451 | static void |
@@ -623,8 +632,7 @@ static int | |||
623 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) | 632 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) |
624 | { | 633 | { |
625 | struct lpfc_iocbq *iocbq; | 634 | struct lpfc_iocbq *iocbq; |
626 | struct lpfc_iocbq *iocbqrsp = NULL; | 635 | struct lpfc_iocbq *iocbqrsp; |
627 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | ||
628 | int ret; | 636 | int ret; |
629 | 637 | ||
630 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); | 638 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); |
@@ -633,7 +641,8 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) | |||
633 | 641 | ||
634 | lpfc_cmd->scsi_hba = phba; | 642 | lpfc_cmd->scsi_hba = phba; |
635 | iocbq = &lpfc_cmd->cur_iocbq; | 643 | iocbq = &lpfc_cmd->cur_iocbq; |
636 | list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list); | 644 | iocbqrsp = lpfc_sli_get_iocbq(phba); |
645 | |||
637 | if (!iocbqrsp) | 646 | if (!iocbqrsp) |
638 | return FAILED; | 647 | return FAILED; |
639 | 648 | ||
@@ -652,44 +661,10 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) | |||
652 | lpfc_cmd->status = IOSTAT_DRIVER_REJECT; | 661 | lpfc_cmd->status = IOSTAT_DRIVER_REJECT; |
653 | } | 662 | } |
654 | 663 | ||
655 | /* | ||
656 | * All outstanding txcmplq I/Os should have been aborted by the target. | ||
657 | * Unfortunately, some targets do not abide by this forcing the driver | ||
658 | * to double check. | ||
659 | */ | ||
660 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], | ||
661 | lpfc_cmd->pCmd->device->id, | ||
662 | lpfc_cmd->pCmd->device->lun, 0, LPFC_CTX_TGT); | ||
663 | |||
664 | lpfc_sli_release_iocbq(phba, iocbqrsp); | 664 | lpfc_sli_release_iocbq(phba, iocbqrsp); |
665 | return ret; | 665 | return ret; |
666 | } | 666 | } |
667 | 667 | ||
668 | static void | ||
669 | lpfc_scsi_cmd_iocb_cleanup (struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | ||
670 | struct lpfc_iocbq *pIocbOut) | ||
671 | { | ||
672 | unsigned long iflag; | ||
673 | struct lpfc_scsi_buf *lpfc_cmd = | ||
674 | (struct lpfc_scsi_buf *) pIocbIn->context1; | ||
675 | |||
676 | spin_lock_irqsave(phba->host->host_lock, iflag); | ||
677 | lpfc_free_scsi_buf(lpfc_cmd); | ||
678 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | ||
679 | } | ||
680 | |||
681 | static void | ||
682 | lpfc_scsi_cmd_iocb_cmpl_aborted(struct lpfc_hba *phba, | ||
683 | struct lpfc_iocbq *pIocbIn, | ||
684 | struct lpfc_iocbq *pIocbOut) | ||
685 | { | ||
686 | struct scsi_cmnd *ml_cmd = | ||
687 | ((struct lpfc_scsi_buf *) pIocbIn->context1)->pCmd; | ||
688 | |||
689 | lpfc_scsi_cmd_iocb_cleanup (phba, pIocbIn, pIocbOut); | ||
690 | ml_cmd->host_scribble = NULL; | ||
691 | } | ||
692 | |||
693 | const char * | 668 | const char * |
694 | lpfc_info(struct Scsi_Host *host) | 669 | lpfc_info(struct Scsi_Host *host) |
695 | { | 670 | { |
@@ -726,9 +701,8 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
726 | struct lpfc_sli *psli = &phba->sli; | 701 | struct lpfc_sli *psli = &phba->sli; |
727 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; | 702 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; |
728 | struct lpfc_nodelist *ndlp = rdata->pnode; | 703 | struct lpfc_nodelist *ndlp = rdata->pnode; |
729 | struct lpfc_scsi_buf *lpfc_cmd = NULL; | 704 | struct lpfc_scsi_buf *lpfc_cmd; |
730 | struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); | 705 | struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); |
731 | struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; | ||
732 | int err; | 706 | int err; |
733 | 707 | ||
734 | err = fc_remote_port_chkready(rport); | 708 | err = fc_remote_port_chkready(rport); |
@@ -745,8 +719,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
745 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); | 719 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); |
746 | goto out_fail_command; | 720 | goto out_fail_command; |
747 | } | 721 | } |
748 | 722 | lpfc_cmd = lpfc_sli_get_scsi_buf (phba); | |
749 | list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); | ||
750 | if (lpfc_cmd == NULL) { | 723 | if (lpfc_cmd == NULL) { |
751 | printk(KERN_WARNING "%s: No buffer available - list empty, " | 724 | printk(KERN_WARNING "%s: No buffer available - list empty, " |
752 | "total count %d\n", __FUNCTION__, phba->total_scsi_bufs); | 725 | "total count %d\n", __FUNCTION__, phba->total_scsi_bufs); |
@@ -776,7 +749,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
776 | return 0; | 749 | return 0; |
777 | 750 | ||
778 | out_host_busy_free_buf: | 751 | out_host_busy_free_buf: |
779 | lpfc_free_scsi_buf(lpfc_cmd); | 752 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
780 | cmnd->host_scribble = NULL; | 753 | cmnd->host_scribble = NULL; |
781 | out_host_busy: | 754 | out_host_busy: |
782 | return SCSI_MLQUEUE_HOST_BUSY; | 755 | return SCSI_MLQUEUE_HOST_BUSY; |
@@ -792,116 +765,92 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
792 | struct lpfc_hba *phba = | 765 | struct lpfc_hba *phba = |
793 | (struct lpfc_hba *)cmnd->device->host->hostdata[0]; | 766 | (struct lpfc_hba *)cmnd->device->host->hostdata[0]; |
794 | struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring]; | 767 | struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring]; |
795 | struct lpfc_iocbq *iocb, *next_iocb; | 768 | struct lpfc_iocbq *iocb; |
796 | struct lpfc_iocbq *abtsiocb = NULL; | 769 | struct lpfc_iocbq *abtsiocb; |
797 | struct lpfc_scsi_buf *lpfc_cmd; | 770 | struct lpfc_scsi_buf *lpfc_cmd; |
798 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | ||
799 | IOCB_t *cmd, *icmd; | 771 | IOCB_t *cmd, *icmd; |
800 | unsigned long snum; | ||
801 | unsigned int id, lun; | ||
802 | unsigned int loop_count = 0; | 772 | unsigned int loop_count = 0; |
803 | int ret = IOCB_SUCCESS; | 773 | int ret = SUCCESS; |
804 | 774 | ||
805 | /* | ||
806 | * If the host_scribble data area is NULL, then the driver has already | ||
807 | * completed this command, but the midlayer did not see the completion | ||
808 | * before the eh fired. Just return SUCCESS. | ||
809 | */ | ||
810 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | ||
811 | if (!lpfc_cmd) | ||
812 | return SUCCESS; | ||
813 | 775 | ||
814 | /* save these now since lpfc_cmd can be freed */ | 776 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
815 | id = lpfc_cmd->pCmd->device->id; | 777 | BUG_ON(!lpfc_cmd); |
816 | lun = lpfc_cmd->pCmd->device->lun; | ||
817 | snum = lpfc_cmd->pCmd->serial_number; | ||
818 | 778 | ||
819 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { | 779 | /* |
820 | cmd = &iocb->iocb; | 780 | * If pCmd field of the corresponding lpfc_scsi_buf structure |
821 | if (iocb->context1 != lpfc_cmd) | 781 | * points to a different SCSI command, then the driver has |
822 | continue; | 782 | * already completed this command, but the midlayer did not |
783 | * see the completion before the eh fired. Just return | ||
784 | * SUCCESS. | ||
785 | */ | ||
786 | iocb = &lpfc_cmd->cur_iocbq; | ||
787 | if (lpfc_cmd->pCmd != cmnd) | ||
788 | goto out; | ||
823 | 789 | ||
824 | list_del_init(&iocb->list); | 790 | BUG_ON(iocb->context1 != lpfc_cmd); |
825 | pring->txq_cnt--; | ||
826 | if (!iocb->iocb_cmpl) | ||
827 | lpfc_sli_release_iocbq(phba, iocb); | ||
828 | else { | ||
829 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
830 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
831 | lpfc_scsi_cmd_iocb_cmpl_aborted(phba, iocb, iocb); | ||
832 | } | ||
833 | 791 | ||
792 | abtsiocb = lpfc_sli_get_iocbq(phba); | ||
793 | if (abtsiocb == NULL) { | ||
794 | ret = FAILED; | ||
834 | goto out; | 795 | goto out; |
835 | } | 796 | } |
836 | 797 | ||
837 | list_remove_head(lpfc_iocb_list, abtsiocb, struct lpfc_iocbq, list); | ||
838 | if (abtsiocb == NULL) | ||
839 | return FAILED; | ||
840 | |||
841 | /* | 798 | /* |
842 | * The scsi command was not in the txq. Check the txcmplq and if it is | 799 | * The scsi command can not be in txq and it is in flight because the |
843 | * found, send an abort to the FW. | 800 | * pCmd is still pointig at the SCSI command we have to abort. There |
801 | * is no need to search the txcmplq. Just send an abort to the FW. | ||
844 | */ | 802 | */ |
845 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { | ||
846 | if (iocb->context1 != lpfc_cmd) | ||
847 | continue; | ||
848 | 803 | ||
849 | iocb->iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl_aborted; | 804 | cmd = &iocb->iocb; |
850 | cmd = &iocb->iocb; | 805 | icmd = &abtsiocb->iocb; |
851 | icmd = &abtsiocb->iocb; | 806 | icmd->un.acxri.abortType = ABORT_TYPE_ABTS; |
852 | icmd->un.acxri.abortType = ABORT_TYPE_ABTS; | 807 | icmd->un.acxri.abortContextTag = cmd->ulpContext; |
853 | icmd->un.acxri.abortContextTag = cmd->ulpContext; | 808 | icmd->un.acxri.abortIoTag = cmd->ulpIoTag; |
854 | icmd->un.acxri.abortIoTag = cmd->ulpIoTag; | ||
855 | |||
856 | icmd->ulpLe = 1; | ||
857 | icmd->ulpClass = cmd->ulpClass; | ||
858 | if (phba->hba_state >= LPFC_LINK_UP) | ||
859 | icmd->ulpCommand = CMD_ABORT_XRI_CN; | ||
860 | else | ||
861 | icmd->ulpCommand = CMD_CLOSE_XRI_CN; | ||
862 | 809 | ||
863 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; | 810 | icmd->ulpLe = 1; |
864 | if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == | 811 | icmd->ulpClass = cmd->ulpClass; |
865 | IOCB_ERROR) { | 812 | if (phba->hba_state >= LPFC_LINK_UP) |
866 | lpfc_sli_release_iocbq(phba, abtsiocb); | 813 | icmd->ulpCommand = CMD_ABORT_XRI_CN; |
867 | ret = IOCB_ERROR; | 814 | else |
868 | break; | 815 | icmd->ulpCommand = CMD_CLOSE_XRI_CN; |
869 | } | ||
870 | 816 | ||
871 | /* Wait for abort to complete */ | 817 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; |
872 | while (cmnd->host_scribble) | 818 | if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == IOCB_ERROR) { |
873 | { | 819 | lpfc_sli_release_iocbq(phba, abtsiocb); |
874 | spin_unlock_irq(phba->host->host_lock); | 820 | ret = FAILED; |
875 | set_current_state(TASK_UNINTERRUPTIBLE); | 821 | goto out; |
876 | schedule_timeout(LPFC_ABORT_WAIT*HZ); | 822 | } |
877 | spin_lock_irq(phba->host->host_lock); | ||
878 | if (++loop_count | ||
879 | > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT) | ||
880 | break; | ||
881 | } | ||
882 | 823 | ||
883 | if(cmnd->host_scribble) { | 824 | /* Wait for abort to complete */ |
884 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 825 | while (lpfc_cmd->pCmd == cmnd) |
885 | "%d:0748 abort handler timed " | 826 | { |
886 | "out waiting for abort to " | 827 | spin_unlock_irq(phba->host->host_lock); |
887 | "complete. Data: " | 828 | set_current_state(TASK_UNINTERRUPTIBLE); |
888 | "x%x x%x x%x x%lx\n", | 829 | schedule_timeout(LPFC_ABORT_WAIT*HZ); |
889 | phba->brd_no, ret, id, lun, snum); | 830 | spin_lock_irq(phba->host->host_lock); |
890 | cmnd->host_scribble = NULL; | 831 | if (++loop_count |
891 | iocb->iocb_cmpl = lpfc_scsi_cmd_iocb_cleanup; | 832 | > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT) |
892 | ret = IOCB_ERROR; | 833 | break; |
893 | } | 834 | } |
894 | 835 | ||
895 | break; | 836 | if (lpfc_cmd->pCmd == cmnd) { |
837 | ret = FAILED; | ||
838 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | ||
839 | "%d:0748 abort handler timed out waiting for " | ||
840 | "abort to complete: ret %#x, ID %d, LUN %d, " | ||
841 | "snum %#lx\n", | ||
842 | phba->brd_no, ret, cmnd->device->id, | ||
843 | cmnd->device->lun, cmnd->serial_number); | ||
896 | } | 844 | } |
897 | 845 | ||
898 | out: | 846 | out: |
899 | lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, | 847 | lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, |
900 | "%d:0749 SCSI layer issued abort device " | 848 | "%d:0749 SCSI layer issued abort device: ret %#x, " |
901 | "Data: x%x x%x x%x x%lx\n", | 849 | "ID %d, LUN %d, snum %#lx\n", |
902 | phba->brd_no, ret, id, lun, snum); | 850 | phba->brd_no, ret, cmnd->device->id, |
851 | cmnd->device->lun, cmnd->serial_number); | ||
903 | 852 | ||
904 | return ret == IOCB_SUCCESS ? SUCCESS : FAILED; | 853 | return ret; |
905 | } | 854 | } |
906 | 855 | ||
907 | static int | 856 | static int |
@@ -919,10 +868,8 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
919 | { | 868 | { |
920 | struct Scsi_Host *shost = cmnd->device->host; | 869 | struct Scsi_Host *shost = cmnd->device->host; |
921 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; | 870 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; |
922 | struct lpfc_scsi_buf *lpfc_cmd = NULL; | 871 | struct lpfc_scsi_buf *lpfc_cmd; |
923 | struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; | 872 | struct lpfc_iocbq *iocbq, *iocbqrsp; |
924 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | ||
925 | struct lpfc_iocbq *iocbq, *iocbqrsp = NULL; | ||
926 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; | 873 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; |
927 | struct lpfc_nodelist *pnode = rdata->pnode; | 874 | struct lpfc_nodelist *pnode = rdata->pnode; |
928 | int ret = FAILED; | 875 | int ret = FAILED; |
@@ -946,7 +893,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
946 | break; | 893 | break; |
947 | } | 894 | } |
948 | 895 | ||
949 | list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); | 896 | lpfc_cmd = lpfc_sli_get_scsi_buf (phba); |
950 | if (lpfc_cmd == NULL) | 897 | if (lpfc_cmd == NULL) |
951 | goto out; | 898 | goto out; |
952 | 899 | ||
@@ -961,7 +908,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
961 | iocbq = &lpfc_cmd->cur_iocbq; | 908 | iocbq = &lpfc_cmd->cur_iocbq; |
962 | 909 | ||
963 | /* get a buffer for this IOCB command response */ | 910 | /* get a buffer for this IOCB command response */ |
964 | list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list); | 911 | iocbqrsp = lpfc_sli_get_iocbq(phba); |
965 | if (iocbqrsp == NULL) | 912 | if (iocbqrsp == NULL) |
966 | goto out_free_scsi_buf; | 913 | goto out_free_scsi_buf; |
967 | 914 | ||
@@ -1002,9 +949,10 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
1002 | } | 949 | } |
1003 | 950 | ||
1004 | if (cnt) { | 951 | if (cnt) { |
1005 | lpfc_printf_log(phba, KERN_INFO, LOG_FCP, | 952 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1006 | "%d:0719 LUN Reset I/O flush failure: cnt x%x\n", | 953 | "%d:0719 LUN Reset I/O flush failure: cnt x%x\n", |
1007 | phba->brd_no, cnt); | 954 | phba->brd_no, cnt); |
955 | ret = FAILED; | ||
1008 | } | 956 | } |
1009 | 957 | ||
1010 | lpfc_sli_release_iocbq(phba, iocbqrsp); | 958 | lpfc_sli_release_iocbq(phba, iocbqrsp); |
@@ -1016,7 +964,7 @@ out_free_scsi_buf: | |||
1016 | phba->brd_no, lpfc_cmd->pCmd->device->id, | 964 | phba->brd_no, lpfc_cmd->pCmd->device->id, |
1017 | lpfc_cmd->pCmd->device->lun, ret, lpfc_cmd->status, | 965 | lpfc_cmd->pCmd->device->lun, ret, lpfc_cmd->status, |
1018 | lpfc_cmd->result); | 966 | lpfc_cmd->result); |
1019 | lpfc_free_scsi_buf(lpfc_cmd); | 967 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
1020 | out: | 968 | out: |
1021 | return ret; | 969 | return ret; |
1022 | } | 970 | } |
@@ -1044,10 +992,9 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1044 | int ret = FAILED, i, err_count = 0; | 992 | int ret = FAILED, i, err_count = 0; |
1045 | int cnt, loopcnt; | 993 | int cnt, loopcnt; |
1046 | unsigned int midlayer_id = 0; | 994 | unsigned int midlayer_id = 0; |
1047 | struct lpfc_scsi_buf * lpfc_cmd = NULL; | 995 | struct lpfc_scsi_buf * lpfc_cmd; |
1048 | struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; | ||
1049 | 996 | ||
1050 | list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); | 997 | lpfc_cmd = lpfc_sli_get_scsi_buf (phba); |
1051 | if (lpfc_cmd == NULL) | 998 | if (lpfc_cmd == NULL) |
1052 | goto out; | 999 | goto out; |
1053 | 1000 | ||
@@ -1111,10 +1058,12 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1111 | phba->brd_no, cnt, i); | 1058 | phba->brd_no, cnt, i); |
1112 | } | 1059 | } |
1113 | 1060 | ||
1114 | if (!err_count) | 1061 | if (cnt == 0) |
1115 | ret = SUCCESS; | 1062 | ret = SUCCESS; |
1063 | else | ||
1064 | ret = FAILED; | ||
1116 | 1065 | ||
1117 | lpfc_free_scsi_buf(lpfc_cmd); | 1066 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
1118 | lpfc_printf_log(phba, | 1067 | lpfc_printf_log(phba, |
1119 | KERN_ERR, | 1068 | KERN_ERR, |
1120 | LOG_FCP, | 1069 | LOG_FCP, |
@@ -1174,7 +1123,7 @@ lpfc_slave_alloc(struct scsi_device *sdev) | |||
1174 | } | 1123 | } |
1175 | 1124 | ||
1176 | for (i = 0; i < num_to_alloc; i++) { | 1125 | for (i = 0; i < num_to_alloc; i++) { |
1177 | scsi_buf = lpfc_get_scsi_buf(phba); | 1126 | scsi_buf = lpfc_new_scsi_buf(phba); |
1178 | if (!scsi_buf) { | 1127 | if (!scsi_buf) { |
1179 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1128 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1180 | "%d:0706 Failed to allocate command " | 1129 | "%d:0706 Failed to allocate command " |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index b53ed3abc6c..508710001ed 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -65,6 +65,16 @@ typedef enum _lpfc_iocb_type { | |||
65 | LPFC_ABORT_IOCB | 65 | LPFC_ABORT_IOCB |
66 | } lpfc_iocb_type; | 66 | } lpfc_iocb_type; |
67 | 67 | ||
68 | struct lpfc_iocbq * | ||
69 | lpfc_sli_get_iocbq(struct lpfc_hba * phba) | ||
70 | { | ||
71 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | ||
72 | struct lpfc_iocbq * iocbq = NULL; | ||
73 | |||
74 | list_remove_head(lpfc_iocb_list, iocbq, struct lpfc_iocbq, list); | ||
75 | return iocbq; | ||
76 | } | ||
77 | |||
68 | void | 78 | void |
69 | lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) | 79 | lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) |
70 | { | 80 | { |
@@ -1055,7 +1065,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1055 | struct lpfc_iocbq *next_iocb; | 1065 | struct lpfc_iocbq *next_iocb; |
1056 | struct lpfc_iocbq *cmdiocbp; | 1066 | struct lpfc_iocbq *cmdiocbp; |
1057 | struct lpfc_iocbq *saveq; | 1067 | struct lpfc_iocbq *saveq; |
1058 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | ||
1059 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno]; | 1068 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno]; |
1060 | uint8_t iocb_cmd_type; | 1069 | uint8_t iocb_cmd_type; |
1061 | lpfc_iocb_type type; | 1070 | lpfc_iocb_type type; |
@@ -1097,7 +1106,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1097 | } | 1106 | } |
1098 | 1107 | ||
1099 | rmb(); | 1108 | rmb(); |
1100 | lpfc_iocb_list = &phba->lpfc_iocb_list; | ||
1101 | while (pring->rspidx != portRspPut) { | 1109 | while (pring->rspidx != portRspPut) { |
1102 | /* | 1110 | /* |
1103 | * Build a completion list and call the appropriate handler. | 1111 | * Build a completion list and call the appropriate handler. |
@@ -1113,8 +1121,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1113 | * received. | 1121 | * received. |
1114 | */ | 1122 | */ |
1115 | entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx); | 1123 | entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx); |
1116 | list_remove_head(lpfc_iocb_list, rspiocbp, struct lpfc_iocbq, | 1124 | rspiocbp = lpfc_sli_get_iocbq(phba); |
1117 | list); | ||
1118 | if (rspiocbp == NULL) { | 1125 | if (rspiocbp == NULL) { |
1119 | printk(KERN_ERR "%s: out of buffers! Failing " | 1126 | printk(KERN_ERR "%s: out of buffers! Failing " |
1120 | "completion.\n", __FUNCTION__); | 1127 | "completion.\n", __FUNCTION__); |
@@ -2407,13 +2414,12 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba, | |||
2407 | struct lpfc_sli_ring * pring, | 2414 | struct lpfc_sli_ring * pring, |
2408 | struct lpfc_iocbq * cmdiocb) | 2415 | struct lpfc_iocbq * cmdiocb) |
2409 | { | 2416 | { |
2410 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | 2417 | struct lpfc_iocbq *abtsiocbp; |
2411 | struct lpfc_iocbq *abtsiocbp = NULL; | ||
2412 | IOCB_t *icmd = NULL; | 2418 | IOCB_t *icmd = NULL; |
2413 | IOCB_t *iabt = NULL; | 2419 | IOCB_t *iabt = NULL; |
2414 | 2420 | ||
2415 | /* issue ABTS for this IOCB based on iotag */ | 2421 | /* issue ABTS for this IOCB based on iotag */ |
2416 | list_remove_head(lpfc_iocb_list, abtsiocbp, struct lpfc_iocbq, list); | 2422 | abtsiocbp = lpfc_sli_get_iocbq(phba); |
2417 | if (abtsiocbp == NULL) | 2423 | if (abtsiocbp == NULL) |
2418 | return 0; | 2424 | return 0; |
2419 | 2425 | ||
@@ -2454,28 +2460,37 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba, | |||
2454 | } | 2460 | } |
2455 | 2461 | ||
2456 | static int | 2462 | static int |
2457 | lpfc_sli_validate_iocb_cmd(struct lpfc_scsi_buf *lpfc_cmd, uint16_t tgt_id, | 2463 | lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id, |
2458 | uint64_t lun_id, struct lpfc_iocbq *iocb, | 2464 | uint64_t lun_id, uint32_t ctx, |
2459 | uint32_t ctx, lpfc_ctx_cmd ctx_cmd) | 2465 | lpfc_ctx_cmd ctx_cmd) |
2460 | { | 2466 | { |
2467 | struct lpfc_scsi_buf *lpfc_cmd; | ||
2468 | struct scsi_cmnd *cmnd; | ||
2461 | int rc = 1; | 2469 | int rc = 1; |
2462 | 2470 | ||
2463 | if (lpfc_cmd == NULL) | 2471 | if (!(iocbq->iocb_flag & LPFC_IO_FCP)) |
2472 | return rc; | ||
2473 | |||
2474 | lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq); | ||
2475 | cmnd = lpfc_cmd->pCmd; | ||
2476 | |||
2477 | if (cmnd == NULL) | ||
2464 | return rc; | 2478 | return rc; |
2465 | 2479 | ||
2466 | switch (ctx_cmd) { | 2480 | switch (ctx_cmd) { |
2467 | case LPFC_CTX_LUN: | 2481 | case LPFC_CTX_LUN: |
2468 | if ((lpfc_cmd->pCmd->device->id == tgt_id) && | 2482 | if ((cmnd->device->id == tgt_id) && |
2469 | (lpfc_cmd->pCmd->device->lun == lun_id)) | 2483 | (cmnd->device->lun == lun_id)) |
2470 | rc = 0; | 2484 | rc = 0; |
2471 | break; | 2485 | break; |
2472 | case LPFC_CTX_TGT: | 2486 | case LPFC_CTX_TGT: |
2473 | if (lpfc_cmd->pCmd->device->id == tgt_id) | 2487 | if (cmnd->device->id == tgt_id) |
2474 | rc = 0; | 2488 | rc = 0; |
2475 | break; | 2489 | break; |
2476 | case LPFC_CTX_CTX: | 2490 | case LPFC_CTX_CTX: |
2477 | if (iocb->iocb.ulpContext == ctx) | 2491 | if (iocbq->iocb.ulpContext == ctx) |
2478 | rc = 0; | 2492 | rc = 0; |
2493 | break; | ||
2479 | case LPFC_CTX_HOST: | 2494 | case LPFC_CTX_HOST: |
2480 | rc = 0; | 2495 | rc = 0; |
2481 | break; | 2496 | break; |
@@ -2492,30 +2507,17 @@ int | |||
2492 | lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 2507 | lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
2493 | uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd) | 2508 | uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd) |
2494 | { | 2509 | { |
2495 | struct lpfc_iocbq *iocb, *next_iocb; | 2510 | struct lpfc_iocbq *iocbq; |
2496 | IOCB_t *cmd = NULL; | 2511 | int sum, i; |
2497 | struct lpfc_scsi_buf *lpfc_cmd; | ||
2498 | int sum = 0, ret_val = 0; | ||
2499 | 2512 | ||
2500 | /* Next check the txcmplq */ | 2513 | for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) { |
2501 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { | 2514 | iocbq = phba->sli.iocbq_lookup[i]; |
2502 | cmd = &iocb->iocb; | ||
2503 | |||
2504 | /* Must be a FCP command */ | ||
2505 | if ((cmd->ulpCommand != CMD_FCP_ICMND64_CR) && | ||
2506 | (cmd->ulpCommand != CMD_FCP_IWRITE64_CR) && | ||
2507 | (cmd->ulpCommand != CMD_FCP_IREAD64_CR)) { | ||
2508 | continue; | ||
2509 | } | ||
2510 | 2515 | ||
2511 | /* context1 MUST be a struct lpfc_scsi_buf */ | 2516 | if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id, |
2512 | lpfc_cmd = (struct lpfc_scsi_buf *) (iocb->context1); | 2517 | 0, ctx_cmd) == 0) |
2513 | ret_val = lpfc_sli_validate_iocb_cmd(lpfc_cmd, tgt_id, lun_id, | 2518 | sum++; |
2514 | NULL, 0, ctx_cmd); | ||
2515 | if (ret_val != 0) | ||
2516 | continue; | ||
2517 | sum++; | ||
2518 | } | 2519 | } |
2520 | |||
2519 | return sum; | 2521 | return sum; |
2520 | } | 2522 | } |
2521 | 2523 | ||
@@ -2534,38 +2536,27 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2534 | uint16_t tgt_id, uint64_t lun_id, uint32_t ctx, | 2536 | uint16_t tgt_id, uint64_t lun_id, uint32_t ctx, |
2535 | lpfc_ctx_cmd abort_cmd) | 2537 | lpfc_ctx_cmd abort_cmd) |
2536 | { | 2538 | { |
2537 | struct lpfc_iocbq *iocb, *next_iocb; | 2539 | struct lpfc_iocbq *iocbq; |
2538 | struct lpfc_iocbq *abtsiocb = NULL; | 2540 | struct lpfc_iocbq *abtsiocb; |
2539 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | ||
2540 | IOCB_t *cmd = NULL; | 2541 | IOCB_t *cmd = NULL; |
2541 | struct lpfc_scsi_buf *lpfc_cmd; | ||
2542 | int errcnt = 0, ret_val = 0; | 2542 | int errcnt = 0, ret_val = 0; |
2543 | int i; | ||
2543 | 2544 | ||
2544 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { | 2545 | for (i = 1; i <= phba->sli.last_iotag; i++) { |
2545 | cmd = &iocb->iocb; | 2546 | iocbq = phba->sli.iocbq_lookup[i]; |
2546 | |||
2547 | /* Must be a FCP command */ | ||
2548 | if ((cmd->ulpCommand != CMD_FCP_ICMND64_CR) && | ||
2549 | (cmd->ulpCommand != CMD_FCP_IWRITE64_CR) && | ||
2550 | (cmd->ulpCommand != CMD_FCP_IREAD64_CR)) { | ||
2551 | continue; | ||
2552 | } | ||
2553 | 2547 | ||
2554 | /* context1 MUST be a struct lpfc_scsi_buf */ | 2548 | if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id, |
2555 | lpfc_cmd = (struct lpfc_scsi_buf *) (iocb->context1); | 2549 | 0, abort_cmd) != 0) |
2556 | ret_val = lpfc_sli_validate_iocb_cmd(lpfc_cmd, tgt_id, lun_id, | ||
2557 | iocb, ctx, abort_cmd); | ||
2558 | if (ret_val != 0) | ||
2559 | continue; | 2550 | continue; |
2560 | 2551 | ||
2561 | /* issue ABTS for this IOCB based on iotag */ | 2552 | /* issue ABTS for this IOCB based on iotag */ |
2562 | list_remove_head(lpfc_iocb_list, abtsiocb, struct lpfc_iocbq, | 2553 | abtsiocb = lpfc_sli_get_iocbq(phba); |
2563 | list); | ||
2564 | if (abtsiocb == NULL) { | 2554 | if (abtsiocb == NULL) { |
2565 | errcnt++; | 2555 | errcnt++; |
2566 | continue; | 2556 | continue; |
2567 | } | 2557 | } |
2568 | 2558 | ||
2559 | cmd = &iocbq->iocb; | ||
2569 | abtsiocb->iocb.un.acxri.abortType = ABORT_TYPE_ABTS; | 2560 | abtsiocb->iocb.un.acxri.abortType = ABORT_TYPE_ABTS; |
2570 | abtsiocb->iocb.un.acxri.abortContextTag = cmd->ulpContext; | 2561 | abtsiocb->iocb.un.acxri.abortContextTag = cmd->ulpContext; |
2571 | abtsiocb->iocb.un.acxri.abortIoTag = cmd->ulpIoTag; | 2562 | abtsiocb->iocb.un.acxri.abortIoTag = cmd->ulpIoTag; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 9f1b85bed5a..b7a9f970f56 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -41,6 +41,7 @@ struct lpfc_iocbq { | |||
41 | uint8_t iocb_flag; | 41 | uint8_t iocb_flag; |
42 | #define LPFC_IO_LIBDFC 1 /* libdfc iocb */ | 42 | #define LPFC_IO_LIBDFC 1 /* libdfc iocb */ |
43 | #define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */ | 43 | #define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */ |
44 | #define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */ | ||
44 | 45 | ||
45 | uint8_t abort_count; | 46 | uint8_t abort_count; |
46 | uint8_t rsvd2; | 47 | uint8_t rsvd2; |