diff options
author | James Smart <james.smart@emulex.com> | 2010-02-26 14:14:23 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-03-03 08:39:18 -0500 |
commit | 0f65ff680f90281d49ee864965f06774eba9657d (patch) | |
tree | c12332bc872aaf2616b94b38cfb5d76a510b1272 /drivers | |
parent | e40a02c12581f710877da372b5d7e15b68a1c5c3 (diff) |
[SCSI] lpfc 8.3.10: Update SLI interface areas
- Clear LPFC_DRIVER_ABORTED on FCP command completion.
- Clear exchange busy flag when I/O is aborted and found on aborted list.
- Free sglq when XRI_ABORTED event is processed before release of IOCB.
- Only process iocb as aborted when LPFC_DRIVER_ABORTED is set.
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 23 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 7 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 35 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 128 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 7 |
8 files changed, 141 insertions, 63 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index ce0599dcc814..4d45e6939783 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -509,7 +509,6 @@ struct lpfc_hba { | |||
509 | int (*lpfc_hba_down_link) | 509 | int (*lpfc_hba_down_link) |
510 | (struct lpfc_hba *); | 510 | (struct lpfc_hba *); |
511 | 511 | ||
512 | |||
513 | /* SLI4 specific HBA data structure */ | 512 | /* SLI4 specific HBA data structure */ |
514 | struct lpfc_sli4_hba sli4_hba; | 513 | struct lpfc_sli4_hba sli4_hba; |
515 | 514 | ||
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 6f0fb51eb461..e7f548281b94 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -385,7 +385,7 @@ void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t); | |||
385 | int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); | 385 | int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); |
386 | void lpfc_start_fdiscs(struct lpfc_hba *phba); | 386 | void lpfc_start_fdiscs(struct lpfc_hba *phba); |
387 | struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t); | 387 | struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t); |
388 | 388 | struct lpfc_sglq *__lpfc_get_active_sglq(struct lpfc_hba *, uint16_t); | |
389 | #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) | 389 | #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) |
390 | #define HBA_EVENT_RSCN 5 | 390 | #define HBA_EVENT_RSCN 5 |
391 | #define HBA_EVENT_LINK_UP 2 | 391 | #define HBA_EVENT_LINK_UP 2 |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 4623323da577..6a2135a0d03a 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -6234,7 +6234,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
6234 | lpfc_mbx_unreg_vpi(vport); | 6234 | lpfc_mbx_unreg_vpi(vport); |
6235 | spin_lock_irq(shost->host_lock); | 6235 | spin_lock_irq(shost->host_lock); |
6236 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 6236 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
6237 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | 6237 | if (phba->sli_rev == LPFC_SLI_REV4) |
6238 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | ||
6238 | spin_unlock_irq(shost->host_lock); | 6239 | spin_unlock_irq(shost->host_lock); |
6239 | } | 6240 | } |
6240 | 6241 | ||
@@ -6812,21 +6813,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, | |||
6812 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; | 6813 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; |
6813 | unsigned long iflag = 0; | 6814 | unsigned long iflag = 0; |
6814 | 6815 | ||
6815 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag); | 6816 | spin_lock_irqsave(&phba->hbalock, iflag); |
6817 | spin_lock(&phba->sli4_hba.abts_sgl_list_lock); | ||
6816 | list_for_each_entry_safe(sglq_entry, sglq_next, | 6818 | list_for_each_entry_safe(sglq_entry, sglq_next, |
6817 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { | 6819 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { |
6818 | if (sglq_entry->sli4_xritag == xri) { | 6820 | if (sglq_entry->sli4_xritag == xri) { |
6819 | list_del(&sglq_entry->list); | 6821 | list_del(&sglq_entry->list); |
6820 | spin_unlock_irqrestore( | ||
6821 | &phba->sli4_hba.abts_sgl_list_lock, | ||
6822 | iflag); | ||
6823 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
6824 | |||
6825 | list_add_tail(&sglq_entry->list, | 6822 | list_add_tail(&sglq_entry->list, |
6826 | &phba->sli4_hba.lpfc_sgl_list); | 6823 | &phba->sli4_hba.lpfc_sgl_list); |
6824 | sglq_entry->state = SGL_FREED; | ||
6825 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); | ||
6827 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 6826 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
6828 | return; | 6827 | return; |
6829 | } | 6828 | } |
6830 | } | 6829 | } |
6831 | spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag); | 6830 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); |
6831 | sglq_entry = __lpfc_get_active_sglq(phba, xri); | ||
6832 | if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) { | ||
6833 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
6834 | return; | ||
6835 | } | ||
6836 | sglq_entry->state = SGL_XRI_ABORTED; | ||
6837 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
6838 | return; | ||
6832 | } | 6839 | } |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 437ddc92ebea..b7889c53fe23 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -822,6 +822,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) | |||
822 | LIST_HEAD(aborts); | 822 | LIST_HEAD(aborts); |
823 | int ret; | 823 | int ret; |
824 | unsigned long iflag = 0; | 824 | unsigned long iflag = 0; |
825 | struct lpfc_sglq *sglq_entry = NULL; | ||
826 | |||
825 | ret = lpfc_hba_down_post_s3(phba); | 827 | ret = lpfc_hba_down_post_s3(phba); |
826 | if (ret) | 828 | if (ret) |
827 | return ret; | 829 | return ret; |
@@ -837,6 +839,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) | |||
837 | * list. | 839 | * list. |
838 | */ | 840 | */ |
839 | spin_lock(&phba->sli4_hba.abts_sgl_list_lock); | 841 | spin_lock(&phba->sli4_hba.abts_sgl_list_lock); |
842 | list_for_each_entry(sglq_entry, | ||
843 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) | ||
844 | sglq_entry->state = SGL_FREED; | ||
845 | |||
840 | list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list, | 846 | list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list, |
841 | &phba->sli4_hba.lpfc_sgl_list); | 847 | &phba->sli4_hba.lpfc_sgl_list); |
842 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); | 848 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); |
@@ -4412,6 +4418,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba) | |||
4412 | 4418 | ||
4413 | /* The list order is used by later block SGL registraton */ | 4419 | /* The list order is used by later block SGL registraton */ |
4414 | spin_lock_irq(&phba->hbalock); | 4420 | spin_lock_irq(&phba->hbalock); |
4421 | sglq_entry->state = SGL_FREED; | ||
4415 | list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); | 4422 | list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); |
4416 | phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry; | 4423 | phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry; |
4417 | phba->sli4_hba.total_sglq_bufs++; | 4424 | phba->sli4_hba.total_sglq_bufs++; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 889a7b9ec92b..a4881f26ab1b 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -620,23 +620,40 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, | |||
620 | uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); | 620 | uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); |
621 | struct lpfc_scsi_buf *psb, *next_psb; | 621 | struct lpfc_scsi_buf *psb, *next_psb; |
622 | unsigned long iflag = 0; | 622 | unsigned long iflag = 0; |
623 | struct lpfc_iocbq *iocbq; | ||
624 | int i; | ||
623 | 625 | ||
624 | spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag); | 626 | spin_lock_irqsave(&phba->hbalock, iflag); |
627 | spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock); | ||
625 | list_for_each_entry_safe(psb, next_psb, | 628 | list_for_each_entry_safe(psb, next_psb, |
626 | &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) { | 629 | &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) { |
627 | if (psb->cur_iocbq.sli4_xritag == xri) { | 630 | if (psb->cur_iocbq.sli4_xritag == xri) { |
628 | list_del(&psb->list); | 631 | list_del(&psb->list); |
629 | psb->exch_busy = 0; | 632 | psb->exch_busy = 0; |
630 | psb->status = IOSTAT_SUCCESS; | 633 | psb->status = IOSTAT_SUCCESS; |
631 | spin_unlock_irqrestore( | 634 | spin_unlock( |
632 | &phba->sli4_hba.abts_scsi_buf_list_lock, | 635 | &phba->sli4_hba.abts_scsi_buf_list_lock); |
633 | iflag); | 636 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
634 | lpfc_release_scsi_buf_s4(phba, psb); | 637 | lpfc_release_scsi_buf_s4(phba, psb); |
635 | return; | 638 | return; |
636 | } | 639 | } |
637 | } | 640 | } |
638 | spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock, | 641 | spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock); |
639 | iflag); | 642 | for (i = 1; i <= phba->sli.last_iotag; i++) { |
643 | iocbq = phba->sli.iocbq_lookup[i]; | ||
644 | |||
645 | if (!(iocbq->iocb_flag & LPFC_IO_FCP) || | ||
646 | (iocbq->iocb_flag & LPFC_IO_LIBDFC)) | ||
647 | continue; | ||
648 | if (iocbq->sli4_xritag != xri) | ||
649 | continue; | ||
650 | psb = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq); | ||
651 | psb->exch_busy = 0; | ||
652 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
653 | return; | ||
654 | |||
655 | } | ||
656 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
640 | } | 657 | } |
641 | 658 | ||
642 | /** | 659 | /** |
@@ -1006,6 +1023,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
1006 | struct scatterlist *sgel = NULL; | 1023 | struct scatterlist *sgel = NULL; |
1007 | struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; | 1024 | struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; |
1008 | struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl; | 1025 | struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl; |
1026 | struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq; | ||
1009 | IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; | 1027 | IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; |
1010 | struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde; | 1028 | struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde; |
1011 | dma_addr_t physaddr; | 1029 | dma_addr_t physaddr; |
@@ -1056,6 +1074,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
1056 | physaddr = sg_dma_address(sgel); | 1074 | physaddr = sg_dma_address(sgel); |
1057 | if (phba->sli_rev == 3 && | 1075 | if (phba->sli_rev == 3 && |
1058 | !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && | 1076 | !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && |
1077 | !(iocbq->iocb_flag & DSS_SECURITY_OP) && | ||
1059 | nseg <= LPFC_EXT_DATA_BDE_COUNT) { | 1078 | nseg <= LPFC_EXT_DATA_BDE_COUNT) { |
1060 | data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; | 1079 | data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; |
1061 | data_bde->tus.f.bdeSize = sg_dma_len(sgel); | 1080 | data_bde->tus.f.bdeSize = sg_dma_len(sgel); |
@@ -1082,7 +1101,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
1082 | * explicitly reinitialized since all iocb memory resources are reused. | 1101 | * explicitly reinitialized since all iocb memory resources are reused. |
1083 | */ | 1102 | */ |
1084 | if (phba->sli_rev == 3 && | 1103 | if (phba->sli_rev == 3 && |
1085 | !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) { | 1104 | !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && |
1105 | !(iocbq->iocb_flag & DSS_SECURITY_OP)) { | ||
1086 | if (num_bde > LPFC_EXT_DATA_BDE_COUNT) { | 1106 | if (num_bde > LPFC_EXT_DATA_BDE_COUNT) { |
1087 | /* | 1107 | /* |
1088 | * The extended IOCB format can only fit 3 BDE or a BPL. | 1108 | * The extended IOCB format can only fit 3 BDE or a BPL. |
@@ -1107,6 +1127,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
1107 | } else { | 1127 | } else { |
1108 | iocb_cmd->un.fcpi64.bdl.bdeSize = | 1128 | iocb_cmd->un.fcpi64.bdl.bdeSize = |
1109 | ((num_bde + 2) * sizeof(struct ulp_bde64)); | 1129 | ((num_bde + 2) * sizeof(struct ulp_bde64)); |
1130 | iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1); | ||
1110 | } | 1131 | } |
1111 | fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); | 1132 | fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); |
1112 | 1133 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 49bed3e8c95d..9feeaff47a52 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -494,7 +494,7 @@ __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | |||
494 | * | 494 | * |
495 | * Returns sglq ponter = success, NULL = Failure. | 495 | * Returns sglq ponter = success, NULL = Failure. |
496 | **/ | 496 | **/ |
497 | static struct lpfc_sglq * | 497 | struct lpfc_sglq * |
498 | __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | 498 | __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) |
499 | { | 499 | { |
500 | uint16_t adj_xri; | 500 | uint16_t adj_xri; |
@@ -526,6 +526,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba) | |||
526 | return NULL; | 526 | return NULL; |
527 | adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base; | 527 | adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base; |
528 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; | 528 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; |
529 | sglq->state = SGL_ALLOCATED; | ||
529 | return sglq; | 530 | return sglq; |
530 | } | 531 | } |
531 | 532 | ||
@@ -580,15 +581,18 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | |||
580 | else | 581 | else |
581 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); | 582 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); |
582 | if (sglq) { | 583 | if (sglq) { |
583 | if (iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) { | 584 | if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) && |
585 | (sglq->state != SGL_XRI_ABORTED)) { | ||
584 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, | 586 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, |
585 | iflag); | 587 | iflag); |
586 | list_add(&sglq->list, | 588 | list_add(&sglq->list, |
587 | &phba->sli4_hba.lpfc_abts_els_sgl_list); | 589 | &phba->sli4_hba.lpfc_abts_els_sgl_list); |
588 | spin_unlock_irqrestore( | 590 | spin_unlock_irqrestore( |
589 | &phba->sli4_hba.abts_sgl_list_lock, iflag); | 591 | &phba->sli4_hba.abts_sgl_list_lock, iflag); |
590 | } else | 592 | } else { |
593 | sglq->state = SGL_FREED; | ||
591 | list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); | 594 | list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); |
595 | } | ||
592 | } | 596 | } |
593 | 597 | ||
594 | 598 | ||
@@ -2258,41 +2262,56 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2258 | spin_unlock_irqrestore(&phba->hbalock, | 2262 | spin_unlock_irqrestore(&phba->hbalock, |
2259 | iflag); | 2263 | iflag); |
2260 | } | 2264 | } |
2261 | if ((phba->sli_rev == LPFC_SLI_REV4) && | 2265 | if (phba->sli_rev == LPFC_SLI_REV4) { |
2262 | (saveq->iocb_flag & LPFC_EXCHANGE_BUSY)) { | 2266 | if (saveq->iocb_flag & |
2263 | /* Set cmdiocb flag for the exchange | 2267 | LPFC_EXCHANGE_BUSY) { |
2264 | * busy so sgl (xri) will not be | 2268 | /* Set cmdiocb flag for the |
2265 | * released until the abort xri is | 2269 | * exchange busy so sgl (xri) |
2266 | * received from hba, clear the | 2270 | * will not be released until |
2267 | * LPFC_DRIVER_ABORTED bit in case | 2271 | * the abort xri is received |
2268 | * it was driver initiated abort. | 2272 | * from hba. |
2269 | */ | 2273 | */ |
2270 | spin_lock_irqsave(&phba->hbalock, | 2274 | spin_lock_irqsave( |
2271 | iflag); | 2275 | &phba->hbalock, iflag); |
2272 | cmdiocbp->iocb_flag &= | 2276 | cmdiocbp->iocb_flag |= |
2273 | ~LPFC_DRIVER_ABORTED; | 2277 | LPFC_EXCHANGE_BUSY; |
2274 | cmdiocbp->iocb_flag |= | 2278 | spin_unlock_irqrestore( |
2275 | LPFC_EXCHANGE_BUSY; | 2279 | &phba->hbalock, iflag); |
2276 | spin_unlock_irqrestore(&phba->hbalock, | 2280 | } |
2277 | iflag); | 2281 | if (cmdiocbp->iocb_flag & |
2278 | cmdiocbp->iocb.ulpStatus = | 2282 | LPFC_DRIVER_ABORTED) { |
2279 | IOSTAT_LOCAL_REJECT; | 2283 | /* |
2280 | cmdiocbp->iocb.un.ulpWord[4] = | 2284 | * Clear LPFC_DRIVER_ABORTED |
2281 | IOERR_ABORT_REQUESTED; | 2285 | * bit in case it was driver |
2282 | /* | 2286 | * initiated abort. |
2283 | * For SLI4, irsiocb contains NO_XRI | 2287 | */ |
2284 | * in sli_xritag, it shall not affect | 2288 | spin_lock_irqsave( |
2285 | * releasing sgl (xri) process. | 2289 | &phba->hbalock, iflag); |
2286 | */ | 2290 | cmdiocbp->iocb_flag &= |
2287 | saveq->iocb.ulpStatus = | 2291 | ~LPFC_DRIVER_ABORTED; |
2288 | IOSTAT_LOCAL_REJECT; | 2292 | spin_unlock_irqrestore( |
2289 | saveq->iocb.un.ulpWord[4] = | 2293 | &phba->hbalock, iflag); |
2290 | IOERR_SLI_ABORTED; | 2294 | cmdiocbp->iocb.ulpStatus = |
2291 | spin_lock_irqsave(&phba->hbalock, | 2295 | IOSTAT_LOCAL_REJECT; |
2292 | iflag); | 2296 | cmdiocbp->iocb.un.ulpWord[4] = |
2293 | saveq->iocb_flag |= LPFC_DELAY_MEM_FREE; | 2297 | IOERR_ABORT_REQUESTED; |
2294 | spin_unlock_irqrestore(&phba->hbalock, | 2298 | /* |
2295 | iflag); | 2299 | * For SLI4, irsiocb contains |
2300 | * NO_XRI in sli_xritag, it | ||
2301 | * shall not affect releasing | ||
2302 | * sgl (xri) process. | ||
2303 | */ | ||
2304 | saveq->iocb.ulpStatus = | ||
2305 | IOSTAT_LOCAL_REJECT; | ||
2306 | saveq->iocb.un.ulpWord[4] = | ||
2307 | IOERR_SLI_ABORTED; | ||
2308 | spin_lock_irqsave( | ||
2309 | &phba->hbalock, iflag); | ||
2310 | saveq->iocb_flag |= | ||
2311 | LPFC_DELAY_MEM_FREE; | ||
2312 | spin_unlock_irqrestore( | ||
2313 | &phba->hbalock, iflag); | ||
2314 | } | ||
2296 | } | 2315 | } |
2297 | } | 2316 | } |
2298 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | 2317 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); |
@@ -2515,14 +2534,16 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, | |||
2515 | 2534 | ||
2516 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, | 2535 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, |
2517 | &rspiocbq); | 2536 | &rspiocbq); |
2518 | if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { | 2537 | if (unlikely(!cmdiocbq)) |
2519 | spin_unlock_irqrestore(&phba->hbalock, | 2538 | break; |
2520 | iflag); | 2539 | if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) |
2521 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, | 2540 | cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED; |
2522 | &rspiocbq); | 2541 | if (cmdiocbq->iocb_cmpl) { |
2523 | spin_lock_irqsave(&phba->hbalock, | 2542 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
2524 | iflag); | 2543 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, |
2525 | } | 2544 | &rspiocbq); |
2545 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
2546 | } | ||
2526 | break; | 2547 | break; |
2527 | case LPFC_UNSOL_IOCB: | 2548 | case LPFC_UNSOL_IOCB: |
2528 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 2549 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
@@ -7451,6 +7472,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, | |||
7451 | { | 7472 | { |
7452 | wait_queue_head_t *pdone_q; | 7473 | wait_queue_head_t *pdone_q; |
7453 | unsigned long iflags; | 7474 | unsigned long iflags; |
7475 | struct lpfc_scsi_buf *lpfc_cmd; | ||
7454 | 7476 | ||
7455 | spin_lock_irqsave(&phba->hbalock, iflags); | 7477 | spin_lock_irqsave(&phba->hbalock, iflags); |
7456 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; | 7478 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; |
@@ -7458,6 +7480,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, | |||
7458 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, | 7480 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, |
7459 | &rspiocbq->iocb, sizeof(IOCB_t)); | 7481 | &rspiocbq->iocb, sizeof(IOCB_t)); |
7460 | 7482 | ||
7483 | /* Set the exchange busy flag for task management commands */ | ||
7484 | if ((cmdiocbq->iocb_flag & LPFC_IO_FCP) && | ||
7485 | !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) { | ||
7486 | lpfc_cmd = container_of(cmdiocbq, struct lpfc_scsi_buf, | ||
7487 | cur_iocbq); | ||
7488 | lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY; | ||
7489 | } | ||
7490 | |||
7461 | pdone_q = cmdiocbq->context_un.wait_queue; | 7491 | pdone_q = cmdiocbq->context_un.wait_queue; |
7462 | if (pdone_q) | 7492 | if (pdone_q) |
7463 | wake_up(pdone_q); | 7493 | wake_up(pdone_q); |
@@ -9076,6 +9106,12 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, | |||
9076 | /* Fake the irspiocb and copy necessary response information */ | 9106 | /* Fake the irspiocb and copy necessary response information */ |
9077 | lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe); | 9107 | lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe); |
9078 | 9108 | ||
9109 | if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) { | ||
9110 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
9111 | cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED; | ||
9112 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
9113 | } | ||
9114 | |||
9079 | /* Pass the cmd_iocb and the rsp state to the upper layer */ | 9115 | /* Pass the cmd_iocb and the rsp state to the upper layer */ |
9080 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq); | 9116 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq); |
9081 | } | 9117 | } |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index dfcf5437d1f5..b4a639c47616 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -62,6 +62,7 @@ struct lpfc_iocbq { | |||
62 | #define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */ | 62 | #define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */ |
63 | #define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */ | 63 | #define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */ |
64 | #define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */ | 64 | #define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */ |
65 | #define DSS_SECURITY_OP 0x100 /* security IO */ | ||
65 | 66 | ||
66 | #define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */ | 67 | #define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */ |
67 | #define LPFC_FIP_ELS_ID_SHIFT 14 | 68 | #define LPFC_FIP_ELS_ID_SHIFT 14 |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 86308836600f..04fd7829cf39 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -431,11 +431,18 @@ enum lpfc_sge_type { | |||
431 | SCSI_BUFF_TYPE | 431 | SCSI_BUFF_TYPE |
432 | }; | 432 | }; |
433 | 433 | ||
434 | enum lpfc_sgl_state { | ||
435 | SGL_FREED, | ||
436 | SGL_ALLOCATED, | ||
437 | SGL_XRI_ABORTED | ||
438 | }; | ||
439 | |||
434 | struct lpfc_sglq { | 440 | struct lpfc_sglq { |
435 | /* lpfc_sglqs are used in double linked lists */ | 441 | /* lpfc_sglqs are used in double linked lists */ |
436 | struct list_head list; | 442 | struct list_head list; |
437 | struct list_head clist; | 443 | struct list_head clist; |
438 | enum lpfc_sge_type buff_type; /* is this a scsi sgl */ | 444 | enum lpfc_sge_type buff_type; /* is this a scsi sgl */ |
445 | enum lpfc_sgl_state state; | ||
439 | uint16_t iotag; /* pre-assigned IO tag */ | 446 | uint16_t iotag; /* pre-assigned IO tag */ |
440 | uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ | 447 | uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ |
441 | struct sli4_sge *sgl; /* pre-assigned SGL */ | 448 | struct sli4_sge *sgl; /* pre-assigned SGL */ |