diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 240 |
1 files changed, 150 insertions, 90 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 23a27592388c..e0e4d8d18244 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -293,7 +293,9 @@ lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm) | |||
293 | } | 293 | } |
294 | bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released); | 294 | bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released); |
295 | bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT); | 295 | bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT); |
296 | bf_set(lpfc_eqcq_doorbell_eqid, &doorbell, q->queue_id); | 296 | bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell, |
297 | (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT)); | ||
298 | bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id); | ||
297 | writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); | 299 | writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); |
298 | /* PCI read to flush PCI pipeline on re-arming for INTx mode */ | 300 | /* PCI read to flush PCI pipeline on re-arming for INTx mode */ |
299 | if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM)) | 301 | if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM)) |
@@ -372,7 +374,9 @@ lpfc_sli4_cq_release(struct lpfc_queue *q, bool arm) | |||
372 | bf_set(lpfc_eqcq_doorbell_arm, &doorbell, 1); | 374 | bf_set(lpfc_eqcq_doorbell_arm, &doorbell, 1); |
373 | bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released); | 375 | bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released); |
374 | bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_COMPLETION); | 376 | bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_COMPLETION); |
375 | bf_set(lpfc_eqcq_doorbell_cqid, &doorbell, q->queue_id); | 377 | bf_set(lpfc_eqcq_doorbell_cqid_hi, &doorbell, |
378 | (q->queue_id >> LPFC_CQID_HI_FIELD_SHIFT)); | ||
379 | bf_set(lpfc_eqcq_doorbell_cqid_lo, &doorbell, q->queue_id); | ||
376 | writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); | 380 | writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); |
377 | return released; | 381 | return released; |
378 | } | 382 | } |
@@ -554,81 +558,6 @@ __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | |||
554 | } | 558 | } |
555 | 559 | ||
556 | /** | 560 | /** |
557 | * __lpfc_set_rrq_active - set RRQ active bit in the ndlp's xri_bitmap. | ||
558 | * @phba: Pointer to HBA context object. | ||
559 | * @ndlp: nodelist pointer for this target. | ||
560 | * @xritag: xri used in this exchange. | ||
561 | * @rxid: Remote Exchange ID. | ||
562 | * @send_rrq: Flag used to determine if we should send rrq els cmd. | ||
563 | * | ||
564 | * This function is called with hbalock held. | ||
565 | * The active bit is set in the ndlp's active rrq xri_bitmap. Allocates an | ||
566 | * rrq struct and adds it to the active_rrq_list. | ||
567 | * | ||
568 | * returns 0 for rrq slot for this xri | ||
569 | * < 0 Were not able to get rrq mem or invalid parameter. | ||
570 | **/ | ||
571 | static int | ||
572 | __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | ||
573 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) | ||
574 | { | ||
575 | struct lpfc_node_rrq *rrq; | ||
576 | int empty; | ||
577 | uint32_t did = 0; | ||
578 | |||
579 | |||
580 | if (!ndlp) | ||
581 | return -EINVAL; | ||
582 | |||
583 | if (!phba->cfg_enable_rrq) | ||
584 | return -EINVAL; | ||
585 | |||
586 | if (phba->pport->load_flag & FC_UNLOADING) { | ||
587 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | ||
588 | goto out; | ||
589 | } | ||
590 | did = ndlp->nlp_DID; | ||
591 | |||
592 | /* | ||
593 | * set the active bit even if there is no mem available. | ||
594 | */ | ||
595 | if (NLP_CHK_FREE_REQ(ndlp)) | ||
596 | goto out; | ||
597 | |||
598 | if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING)) | ||
599 | goto out; | ||
600 | |||
601 | if (test_and_set_bit(xritag, ndlp->active_rrqs.xri_bitmap)) | ||
602 | goto out; | ||
603 | |||
604 | rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); | ||
605 | if (rrq) { | ||
606 | rrq->send_rrq = send_rrq; | ||
607 | rrq->xritag = xritag; | ||
608 | rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1); | ||
609 | rrq->ndlp = ndlp; | ||
610 | rrq->nlp_DID = ndlp->nlp_DID; | ||
611 | rrq->vport = ndlp->vport; | ||
612 | rrq->rxid = rxid; | ||
613 | empty = list_empty(&phba->active_rrq_list); | ||
614 | rrq->send_rrq = send_rrq; | ||
615 | list_add_tail(&rrq->list, &phba->active_rrq_list); | ||
616 | if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) { | ||
617 | phba->hba_flag |= HBA_RRQ_ACTIVE; | ||
618 | if (empty) | ||
619 | lpfc_worker_wake_up(phba); | ||
620 | } | ||
621 | return 0; | ||
622 | } | ||
623 | out: | ||
624 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
625 | "2921 Can't set rrq active xri:0x%x rxid:0x%x" | ||
626 | " DID:0x%x Send:%d\n", | ||
627 | xritag, rxid, did, send_rrq); | ||
628 | return -EINVAL; | ||
629 | } | ||
630 | |||
631 | /** | ||
632 | * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. | 561 | * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. |
633 | * @phba: Pointer to HBA context object. | 562 | * @phba: Pointer to HBA context object. |
634 | * @xritag: xri used in this exchange. | 563 | * @xritag: xri used in this exchange. |
@@ -856,15 +785,68 @@ lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
856 | **/ | 785 | **/ |
857 | int | 786 | int |
858 | lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | 787 | lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, |
859 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) | 788 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) |
860 | { | 789 | { |
861 | int ret; | ||
862 | unsigned long iflags; | 790 | unsigned long iflags; |
791 | struct lpfc_node_rrq *rrq; | ||
792 | int empty; | ||
793 | |||
794 | if (!ndlp) | ||
795 | return -EINVAL; | ||
796 | |||
797 | if (!phba->cfg_enable_rrq) | ||
798 | return -EINVAL; | ||
863 | 799 | ||
864 | spin_lock_irqsave(&phba->hbalock, iflags); | 800 | spin_lock_irqsave(&phba->hbalock, iflags); |
865 | ret = __lpfc_set_rrq_active(phba, ndlp, xritag, rxid, send_rrq); | 801 | if (phba->pport->load_flag & FC_UNLOADING) { |
802 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | ||
803 | goto out; | ||
804 | } | ||
805 | |||
806 | /* | ||
807 | * set the active bit even if there is no mem available. | ||
808 | */ | ||
809 | if (NLP_CHK_FREE_REQ(ndlp)) | ||
810 | goto out; | ||
811 | |||
812 | if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING)) | ||
813 | goto out; | ||
814 | |||
815 | if (test_and_set_bit(xritag, ndlp->active_rrqs.xri_bitmap)) | ||
816 | goto out; | ||
817 | |||
866 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 818 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
867 | return ret; | 819 | rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); |
820 | if (!rrq) { | ||
821 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
822 | "3155 Unable to allocate RRQ xri:0x%x rxid:0x%x" | ||
823 | " DID:0x%x Send:%d\n", | ||
824 | xritag, rxid, ndlp->nlp_DID, send_rrq); | ||
825 | return -EINVAL; | ||
826 | } | ||
827 | rrq->send_rrq = send_rrq; | ||
828 | rrq->xritag = xritag; | ||
829 | rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1); | ||
830 | rrq->ndlp = ndlp; | ||
831 | rrq->nlp_DID = ndlp->nlp_DID; | ||
832 | rrq->vport = ndlp->vport; | ||
833 | rrq->rxid = rxid; | ||
834 | rrq->send_rrq = send_rrq; | ||
835 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
836 | empty = list_empty(&phba->active_rrq_list); | ||
837 | list_add_tail(&rrq->list, &phba->active_rrq_list); | ||
838 | phba->hba_flag |= HBA_RRQ_ACTIVE; | ||
839 | if (empty) | ||
840 | lpfc_worker_wake_up(phba); | ||
841 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
842 | return 0; | ||
843 | out: | ||
844 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
845 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
846 | "2921 Can't set rrq active xri:0x%x rxid:0x%x" | ||
847 | " DID:0x%x Send:%d\n", | ||
848 | xritag, rxid, ndlp->nlp_DID, send_rrq); | ||
849 | return -EINVAL; | ||
868 | } | 850 | } |
869 | 851 | ||
870 | /** | 852 | /** |
@@ -5596,6 +5578,8 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) | |||
5596 | for (i = 0; i < count; i++) | 5578 | for (i = 0; i < count; i++) |
5597 | phba->sli4_hba.rpi_ids[i] = base + i; | 5579 | phba->sli4_hba.rpi_ids[i] = base + i; |
5598 | 5580 | ||
5581 | lpfc_sli4_node_prep(phba); | ||
5582 | |||
5599 | /* VPIs. */ | 5583 | /* VPIs. */ |
5600 | count = phba->sli4_hba.max_cfg_param.max_vpi; | 5584 | count = phba->sli4_hba.max_cfg_param.max_vpi; |
5601 | base = phba->sli4_hba.max_cfg_param.vpi_base; | 5585 | base = phba->sli4_hba.max_cfg_param.vpi_base; |
@@ -7555,6 +7539,8 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | |||
7555 | 7539 | ||
7556 | sgl = (struct sli4_sge *)sglq->sgl; | 7540 | sgl = (struct sli4_sge *)sglq->sgl; |
7557 | icmd = &piocbq->iocb; | 7541 | icmd = &piocbq->iocb; |
7542 | if (icmd->ulpCommand == CMD_XMIT_BLS_RSP64_CX) | ||
7543 | return sglq->sli4_xritag; | ||
7558 | if (icmd->un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) { | 7544 | if (icmd->un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) { |
7559 | numBdes = icmd->un.genreq64.bdl.bdeSize / | 7545 | numBdes = icmd->un.genreq64.bdl.bdeSize / |
7560 | sizeof(struct ulp_bde64); | 7546 | sizeof(struct ulp_bde64); |
@@ -7756,6 +7742,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
7756 | if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { | 7742 | if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { |
7757 | if (pcmd && (*pcmd == ELS_CMD_FLOGI || | 7743 | if (pcmd && (*pcmd == ELS_CMD_FLOGI || |
7758 | *pcmd == ELS_CMD_SCR || | 7744 | *pcmd == ELS_CMD_SCR || |
7745 | *pcmd == ELS_CMD_FDISC || | ||
7759 | *pcmd == ELS_CMD_PLOGI)) { | 7746 | *pcmd == ELS_CMD_PLOGI)) { |
7760 | bf_set(els_req64_sp, &wqe->els_req, 1); | 7747 | bf_set(els_req64_sp, &wqe->els_req, 1); |
7761 | bf_set(els_req64_sid, &wqe->els_req, | 7748 | bf_set(els_req64_sid, &wqe->els_req, |
@@ -7763,7 +7750,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
7763 | bf_set(wqe_ct, &wqe->els_req.wqe_com, 1); | 7750 | bf_set(wqe_ct, &wqe->els_req.wqe_com, 1); |
7764 | bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, | 7751 | bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, |
7765 | phba->vpi_ids[phba->pport->vpi]); | 7752 | phba->vpi_ids[phba->pport->vpi]); |
7766 | } else if (iocbq->context1) { | 7753 | } else if (pcmd && iocbq->context1) { |
7767 | bf_set(wqe_ct, &wqe->els_req.wqe_com, 0); | 7754 | bf_set(wqe_ct, &wqe->els_req.wqe_com, 0); |
7768 | bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, | 7755 | bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, |
7769 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); | 7756 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); |
@@ -7830,12 +7817,16 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
7830 | bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS); | 7817 | bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS); |
7831 | /* Always open the exchange */ | 7818 | /* Always open the exchange */ |
7832 | bf_set(wqe_xc, &wqe->fcp_iwrite.wqe_com, 0); | 7819 | bf_set(wqe_xc, &wqe->fcp_iwrite.wqe_com, 0); |
7833 | bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1); | ||
7834 | bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE); | 7820 | bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE); |
7835 | bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com, | 7821 | bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com, |
7836 | LPFC_WQE_LENLOC_WORD4); | 7822 | LPFC_WQE_LENLOC_WORD4); |
7837 | bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0); | 7823 | bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0); |
7838 | bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU); | 7824 | bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU); |
7825 | if (iocbq->iocb_flag & LPFC_IO_DIF) { | ||
7826 | iocbq->iocb_flag &= ~LPFC_IO_DIF; | ||
7827 | bf_set(wqe_dif, &wqe->generic.wqe_com, 1); | ||
7828 | } | ||
7829 | bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1); | ||
7839 | break; | 7830 | break; |
7840 | case CMD_FCP_IREAD64_CR: | 7831 | case CMD_FCP_IREAD64_CR: |
7841 | /* word3 iocb=iotag wqe=payload_offset_len */ | 7832 | /* word3 iocb=iotag wqe=payload_offset_len */ |
@@ -7849,12 +7840,16 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
7849 | bf_set(wqe_lnk, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpXS); | 7840 | bf_set(wqe_lnk, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpXS); |
7850 | /* Always open the exchange */ | 7841 | /* Always open the exchange */ |
7851 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); | 7842 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); |
7852 | bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1); | ||
7853 | bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ); | 7843 | bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ); |
7854 | bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com, | 7844 | bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com, |
7855 | LPFC_WQE_LENLOC_WORD4); | 7845 | LPFC_WQE_LENLOC_WORD4); |
7856 | bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0); | 7846 | bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0); |
7857 | bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU); | 7847 | bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU); |
7848 | if (iocbq->iocb_flag & LPFC_IO_DIF) { | ||
7849 | iocbq->iocb_flag &= ~LPFC_IO_DIF; | ||
7850 | bf_set(wqe_dif, &wqe->generic.wqe_com, 1); | ||
7851 | } | ||
7852 | bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1); | ||
7858 | break; | 7853 | break; |
7859 | case CMD_FCP_ICMND64_CR: | 7854 | case CMD_FCP_ICMND64_CR: |
7860 | /* word3 iocb=IO_TAG wqe=reserved */ | 7855 | /* word3 iocb=IO_TAG wqe=reserved */ |
@@ -7982,6 +7977,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
7982 | xritag = 0; | 7977 | xritag = 0; |
7983 | break; | 7978 | break; |
7984 | case CMD_XMIT_BLS_RSP64_CX: | 7979 | case CMD_XMIT_BLS_RSP64_CX: |
7980 | ndlp = (struct lpfc_nodelist *)iocbq->context1; | ||
7985 | /* As BLS ABTS RSP WQE is very different from other WQEs, | 7981 | /* As BLS ABTS RSP WQE is very different from other WQEs, |
7986 | * we re-construct this WQE here based on information in | 7982 | * we re-construct this WQE here based on information in |
7987 | * iocbq from scratch. | 7983 | * iocbq from scratch. |
@@ -8008,8 +8004,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
8008 | } | 8004 | } |
8009 | bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff); | 8005 | bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff); |
8010 | bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1); | 8006 | bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1); |
8007 | |||
8008 | /* Use CT=VPI */ | ||
8009 | bf_set(wqe_els_did, &wqe->xmit_bls_rsp.wqe_dest, | ||
8010 | ndlp->nlp_DID); | ||
8011 | bf_set(xmit_bls_rsp64_temprpi, &wqe->xmit_bls_rsp, | ||
8012 | iocbq->iocb.ulpContext); | ||
8013 | bf_set(wqe_ct, &wqe->xmit_bls_rsp.wqe_com, 1); | ||
8011 | bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com, | 8014 | bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com, |
8012 | iocbq->iocb.ulpContext); | 8015 | phba->vpi_ids[phba->pport->vpi]); |
8013 | bf_set(wqe_qosd, &wqe->xmit_bls_rsp.wqe_com, 1); | 8016 | bf_set(wqe_qosd, &wqe->xmit_bls_rsp.wqe_com, 1); |
8014 | bf_set(wqe_lenloc, &wqe->xmit_bls_rsp.wqe_com, | 8017 | bf_set(wqe_lenloc, &wqe->xmit_bls_rsp.wqe_com, |
8015 | LPFC_WQE_LENLOC_NONE); | 8018 | LPFC_WQE_LENLOC_NONE); |
@@ -8073,8 +8076,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
8073 | 8076 | ||
8074 | if (piocb->sli4_xritag == NO_XRI) { | 8077 | if (piocb->sli4_xritag == NO_XRI) { |
8075 | if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || | 8078 | if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || |
8076 | piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN || | 8079 | piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN) |
8077 | piocb->iocb.ulpCommand == CMD_XMIT_BLS_RSP64_CX) | ||
8078 | sglq = NULL; | 8080 | sglq = NULL; |
8079 | else { | 8081 | else { |
8080 | if (pring->txq_cnt) { | 8082 | if (pring->txq_cnt) { |
@@ -8384,10 +8386,13 @@ lpfc_sli4_abts_err_handler(struct lpfc_hba *phba, | |||
8384 | { | 8386 | { |
8385 | struct lpfc_vport *vport; | 8387 | struct lpfc_vport *vport; |
8386 | 8388 | ||
8387 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) | 8389 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
8388 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 8390 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
8389 | "3115 Node Context not found, driver " | 8391 | "3115 Node Context not found, driver " |
8390 | "ignoring abts err event\n"); | 8392 | "ignoring abts err event\n"); |
8393 | return; | ||
8394 | } | ||
8395 | |||
8391 | vport = ndlp->vport; | 8396 | vport = ndlp->vport; |
8392 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | 8397 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, |
8393 | "3116 Port generated FCP XRI ABORT event on " | 8398 | "3116 Port generated FCP XRI ABORT event on " |
@@ -10653,12 +10658,14 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba, | |||
10653 | struct lpfc_wcqe_complete *wcqe) | 10658 | struct lpfc_wcqe_complete *wcqe) |
10654 | { | 10659 | { |
10655 | unsigned long iflags; | 10660 | unsigned long iflags; |
10661 | uint32_t status; | ||
10656 | size_t offset = offsetof(struct lpfc_iocbq, iocb); | 10662 | size_t offset = offsetof(struct lpfc_iocbq, iocb); |
10657 | 10663 | ||
10658 | memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset, | 10664 | memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset, |
10659 | sizeof(struct lpfc_iocbq) - offset); | 10665 | sizeof(struct lpfc_iocbq) - offset); |
10660 | /* Map WCQE parameters into irspiocb parameters */ | 10666 | /* Map WCQE parameters into irspiocb parameters */ |
10661 | pIocbIn->iocb.ulpStatus = bf_get(lpfc_wcqe_c_status, wcqe); | 10667 | status = bf_get(lpfc_wcqe_c_status, wcqe); |
10668 | pIocbIn->iocb.ulpStatus = (status & LPFC_IOCB_STATUS_MASK); | ||
10662 | if (pIocbOut->iocb_flag & LPFC_IO_FCP) | 10669 | if (pIocbOut->iocb_flag & LPFC_IO_FCP) |
10663 | if (pIocbIn->iocb.ulpStatus == IOSTAT_FCP_RSP_ERROR) | 10670 | if (pIocbIn->iocb.ulpStatus == IOSTAT_FCP_RSP_ERROR) |
10664 | pIocbIn->iocb.un.fcpi.fcpi_parm = | 10671 | pIocbIn->iocb.un.fcpi.fcpi_parm = |
@@ -10671,6 +10678,44 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba, | |||
10671 | pIocbIn->iocb.un.genreq64.bdl.bdeSize = wcqe->total_data_placed; | 10678 | pIocbIn->iocb.un.genreq64.bdl.bdeSize = wcqe->total_data_placed; |
10672 | } | 10679 | } |
10673 | 10680 | ||
10681 | /* Convert BG errors for completion status */ | ||
10682 | if (status == CQE_STATUS_DI_ERROR) { | ||
10683 | pIocbIn->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; | ||
10684 | |||
10685 | if (bf_get(lpfc_wcqe_c_bg_edir, wcqe)) | ||
10686 | pIocbIn->iocb.un.ulpWord[4] = IOERR_RX_DMA_FAILED; | ||
10687 | else | ||
10688 | pIocbIn->iocb.un.ulpWord[4] = IOERR_TX_DMA_FAILED; | ||
10689 | |||
10690 | pIocbIn->iocb.unsli3.sli3_bg.bgstat = 0; | ||
10691 | if (bf_get(lpfc_wcqe_c_bg_ge, wcqe)) /* Guard Check failed */ | ||
10692 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10693 | BGS_GUARD_ERR_MASK; | ||
10694 | if (bf_get(lpfc_wcqe_c_bg_ae, wcqe)) /* App Tag Check failed */ | ||
10695 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10696 | BGS_APPTAG_ERR_MASK; | ||
10697 | if (bf_get(lpfc_wcqe_c_bg_re, wcqe)) /* Ref Tag Check failed */ | ||
10698 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10699 | BGS_REFTAG_ERR_MASK; | ||
10700 | |||
10701 | /* Check to see if there was any good data before the error */ | ||
10702 | if (bf_get(lpfc_wcqe_c_bg_tdpv, wcqe)) { | ||
10703 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10704 | BGS_HI_WATER_MARK_PRESENT_MASK; | ||
10705 | pIocbIn->iocb.unsli3.sli3_bg.bghm = | ||
10706 | wcqe->total_data_placed; | ||
10707 | } | ||
10708 | |||
10709 | /* | ||
10710 | * Set ALL the error bits to indicate we don't know what | ||
10711 | * type of error it is. | ||
10712 | */ | ||
10713 | if (!pIocbIn->iocb.unsli3.sli3_bg.bgstat) | ||
10714 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10715 | (BGS_REFTAG_ERR_MASK | BGS_APPTAG_ERR_MASK | | ||
10716 | BGS_GUARD_ERR_MASK); | ||
10717 | } | ||
10718 | |||
10674 | /* Pick up HBA exchange busy condition */ | 10719 | /* Pick up HBA exchange busy condition */ |
10675 | if (bf_get(lpfc_wcqe_c_xb, wcqe)) { | 10720 | if (bf_get(lpfc_wcqe_c_xb, wcqe)) { |
10676 | spin_lock_irqsave(&phba->hbalock, iflags); | 10721 | spin_lock_irqsave(&phba->hbalock, iflags); |
@@ -14042,6 +14087,13 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba, | |||
14042 | { | 14087 | { |
14043 | if (cmd_iocbq) | 14088 | if (cmd_iocbq) |
14044 | lpfc_sli_release_iocbq(phba, cmd_iocbq); | 14089 | lpfc_sli_release_iocbq(phba, cmd_iocbq); |
14090 | |||
14091 | /* Failure means BLS ABORT RSP did not get delivered to remote node*/ | ||
14092 | if (rsp_iocbq && rsp_iocbq->iocb.ulpStatus) | ||
14093 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
14094 | "3154 BLS ABORT RSP failed, data: x%x/x%x\n", | ||
14095 | rsp_iocbq->iocb.ulpStatus, | ||
14096 | rsp_iocbq->iocb.un.ulpWord[4]); | ||
14045 | } | 14097 | } |
14046 | 14098 | ||
14047 | /** | 14099 | /** |
@@ -14748,7 +14800,8 @@ lpfc_sli4_remove_rpis(struct lpfc_hba *phba) | |||
14748 | * provided rpi via a bitmask. | 14800 | * provided rpi via a bitmask. |
14749 | **/ | 14801 | **/ |
14750 | int | 14802 | int |
14751 | lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp) | 14803 | lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp, |
14804 | void (*cmpl)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *arg) | ||
14752 | { | 14805 | { |
14753 | LPFC_MBOXQ_t *mboxq; | 14806 | LPFC_MBOXQ_t *mboxq; |
14754 | struct lpfc_hba *phba = ndlp->phba; | 14807 | struct lpfc_hba *phba = ndlp->phba; |
@@ -14761,6 +14814,13 @@ lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp) | |||
14761 | 14814 | ||
14762 | /* Post all rpi memory regions to the port. */ | 14815 | /* Post all rpi memory regions to the port. */ |
14763 | lpfc_resume_rpi(mboxq, ndlp); | 14816 | lpfc_resume_rpi(mboxq, ndlp); |
14817 | if (cmpl) { | ||
14818 | mboxq->mbox_cmpl = cmpl; | ||
14819 | mboxq->context1 = arg; | ||
14820 | mboxq->context2 = ndlp; | ||
14821 | } else | ||
14822 | mboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | ||
14823 | mboxq->vport = ndlp->vport; | ||
14764 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | 14824 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); |
14765 | if (rc == MBX_NOT_FINISHED) { | 14825 | if (rc == MBX_NOT_FINISHED) { |
14766 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 14826 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |