aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-02-26 14:14:23 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-03-03 08:39:18 -0500
commit0f65ff680f90281d49ee864965f06774eba9657d (patch)
treec12332bc872aaf2616b94b38cfb5d76a510b1272
parente40a02c12581f710877da372b5d7e15b68a1c5c3 (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>
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c23
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c35
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c128
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h7
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);
385int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); 385int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
386void lpfc_start_fdiscs(struct lpfc_hba *phba); 386void lpfc_start_fdiscs(struct lpfc_hba *phba);
387struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t); 387struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t);
388 388struct 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 **/
497static struct lpfc_sglq * 497struct 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
434enum lpfc_sgl_state {
435 SGL_FREED,
436 SGL_ALLOCATED,
437 SGL_XRI_ABORTED
438};
439
434struct lpfc_sglq { 440struct 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 */