diff options
| -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 e16025d76aa2..d527d05a607f 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 40c34a30a94a..7f427f9c4688 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 e931ae6e7464..08a0c00cfc30 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 59e244f04c32..27390aa0858b 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 b903d3b7b730..c34d3cf4f19c 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 b53ed3abc6c9..508710001ed6 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 9f1b85bed5a7..b7a9f970f565 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; |
