rk30/rk2928 hdmi:
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / lpfc / lpfc_els.c
index e2c452467c8bdb4582fc0487905bcf08b02753ec..1725b81770e92b5a99fe24afa7661082f3cf68d2 100644 (file)
@@ -250,7 +250,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
                icmd->un.elsreq64.myID = vport->fc_myDID;
 
                /* For ELS_REQUEST64_CR, use the VPI by default */
-               icmd->ulpContext = vport->vpi + phba->vpi_base;
+               icmd->ulpContext = phba->vpi_ids[vport->vpi];
                icmd->ulpCt_h = 0;
                /* The CT field must be 0=INVALID_RPI for the ECHO cmd */
                if (elscmd == ELS_CMD_ECHO)
@@ -454,6 +454,7 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
                rc = -ENOMEM;
                goto fail_free_dmabuf;
        }
+
        mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!mboxq) {
                rc = -ENOMEM;
@@ -646,21 +647,15 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                }
                lpfc_cleanup_pending_mbox(vport);
 
-               if (phba->sli_rev == LPFC_SLI_REV4)
+               if (phba->sli_rev == LPFC_SLI_REV4) {
                        lpfc_sli4_unreg_all_rpis(vport);
-
-               if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
                        lpfc_mbx_unreg_vpi(vport);
                        spin_lock_irq(shost->host_lock);
                        vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
-                       spin_unlock_irq(shost->host_lock);
-               }
-               /*
-                * If VPI is unreged, driver need to do INIT_VPI
-                * before re-registering
-                */
-               if (phba->sli_rev == LPFC_SLI_REV4) {
-                       spin_lock_irq(shost->host_lock);
+                       /*
+                       * If VPI is unreged, driver need to do INIT_VPI
+                       * before re-registering
+                       */
                        vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
                        spin_unlock_irq(shost->host_lock);
                }
@@ -1095,11 +1090,14 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                        /* Set the fcfi to the fcfi we registered with */
                        elsiocb->iocb.ulpContext = phba->fcf.fcfi;
                }
-       } else if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
-               sp->cmn.request_multiple_Nport = 1;
-               /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */
-               icmd->ulpCt_h = 1;
-               icmd->ulpCt_l = 0;
+       } else {
+               if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
+                       sp->cmn.request_multiple_Nport = 1;
+                       /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */
+                       icmd->ulpCt_h = 1;
+                       icmd->ulpCt_l = 0;
+               } else
+                       sp->cmn.request_multiple_Nport = 0;
        }
 
        if (phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
@@ -3655,7 +3653,8 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
                }
 
                icmd = &elsiocb->iocb;
-               icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
+               icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
+               icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
                pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
                *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
                pcmd += sizeof(uint32_t);
@@ -3672,7 +3671,8 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
                        return 1;
 
                icmd = &elsiocb->iocb;
-               icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
+               icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
+               icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
                pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
 
                if (mbox)
@@ -3694,7 +3694,8 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
                        return 1;
 
                icmd = &elsiocb->iocb;
-               icmd->ulpContext = oldcmd->ulpContext; /* Xri */
+               icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
+               icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
                pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
 
                memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
@@ -3780,7 +3781,8 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
 
        icmd = &elsiocb->iocb;
        oldcmd = &oldiocb->iocb;
-       icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
+       icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
+       icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
 
        *((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT;
@@ -3852,7 +3854,8 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
 
        icmd = &elsiocb->iocb;
        oldcmd = &oldiocb->iocb;
-       icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
+       icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
+       icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
 
        /* Xmit ADISC ACC response tag <ulpIoTag> */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
@@ -3930,7 +3933,9 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
 
        icmd = &elsiocb->iocb;
        oldcmd = &oldiocb->iocb;
-       icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
+       icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
+       icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
+
        /* Xmit PRLI ACC response tag <ulpIoTag> */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                         "0131 Xmit PRLI ACC response tag x%x xri x%x, "
@@ -4034,7 +4039,9 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
 
        icmd = &elsiocb->iocb;
        oldcmd = &oldiocb->iocb;
-       icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
+       icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
+       icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
+
        /* Xmit RNID ACC response tag <ulpIoTag> */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                         "0132 Xmit RNID ACC response tag x%x xri x%x\n",
@@ -4162,7 +4169,9 @@ lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
        if (!elsiocb)
                return 1;
 
-       elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext;    /* Xri */
+       elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext;  /* Xri / rx_id */
+       elsiocb->iocb.unsli3.rcvsli3.ox_id = oldiocb->iocb.unsli3.rcvsli3.ox_id;
+
        /* Xmit ECHO ACC response tag <ulpIoTag> */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                         "2876 Xmit ECHO ACC response tag x%x xri x%x\n",
@@ -5053,13 +5062,15 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        uint8_t *pcmd;
        struct lpfc_iocbq *elsiocb;
        struct lpfc_nodelist *ndlp;
-       uint16_t xri;
+       uint16_t oxid;
+       uint16_t rxid;
        uint32_t cmdsize;
 
        mb = &pmb->u.mb;
 
        ndlp = (struct lpfc_nodelist *) pmb->context2;
-       xri = (uint16_t) ((unsigned long)(pmb->context1));
+       rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff);
+       oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff);
        pmb->context1 = NULL;
        pmb->context2 = NULL;
 
@@ -5081,7 +5092,8 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                return;
 
        icmd = &elsiocb->iocb;
-       icmd->ulpContext = xri;
+       icmd->ulpContext = rxid;
+       icmd->unsli3.rcvsli3.ox_id = oxid;
 
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
        *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
@@ -5136,13 +5148,16 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        uint8_t *pcmd;
        struct lpfc_iocbq *elsiocb;
        struct lpfc_nodelist *ndlp;
-       uint16_t xri, status;
+       uint16_t status;
+       uint16_t oxid;
+       uint16_t rxid;
        uint32_t cmdsize;
 
        mb = &pmb->u.mb;
 
        ndlp = (struct lpfc_nodelist *) pmb->context2;
-       xri = (uint16_t) ((unsigned long)(pmb->context1));
+       rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff);
+       oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff);
        pmb->context1 = NULL;
        pmb->context2 = NULL;
 
@@ -5164,7 +5179,8 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                return;
 
        icmd = &elsiocb->iocb;
-       icmd->ulpContext = xri;
+       icmd->ulpContext = rxid;
+       icmd->unsli3.rcvsli3.ox_id = oxid;
 
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
        *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
@@ -5237,8 +5253,9 @@ lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
        if (mbox) {
                lpfc_read_lnk_stat(phba, mbox);
-               mbox->context1 =
-                   (void *)((unsigned long) cmdiocb->iocb.ulpContext);
+               mbox->context1 = (void *)((unsigned long)
+                       ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) |
+                       cmdiocb->iocb.ulpContext)); /* rx_id */
                mbox->context2 = lpfc_nlp_get(ndlp);
                mbox->vport = vport;
                mbox->mbox_cmpl = lpfc_els_rsp_rls_acc;
@@ -5313,7 +5330,8 @@ lpfc_els_rcv_rtv(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        pcmd += sizeof(uint32_t); /* Skip past command */
 
        /* use the command's xri in the response */
-       elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext;
+       elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext;  /* Xri / rx_id */
+       elsiocb->iocb.unsli3.rcvsli3.ox_id = cmdiocb->iocb.unsli3.rcvsli3.ox_id;
 
        rtv_rsp = (struct RTV_RSP *)pcmd;
 
@@ -5398,8 +5416,9 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
                mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
                if (mbox) {
                        lpfc_read_lnk_stat(phba, mbox);
-                       mbox->context1 =
-                           (void *)((unsigned long) cmdiocb->iocb.ulpContext);
+                       mbox->context1 = (void *)((unsigned long)
+                               ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) |
+                               cmdiocb->iocb.ulpContext)); /* rx_id */
                        mbox->context2 = lpfc_nlp_get(ndlp);
                        mbox->vport = vport;
                        mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
@@ -5553,7 +5572,8 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
 
        icmd = &elsiocb->iocb;
        oldcmd = &oldiocb->iocb;
-       icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
+       icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
+       icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
 
        pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
        *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
@@ -6585,10 +6605,30 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
 {
        struct lpfc_vport *vport;
        unsigned long flags;
+       int i = 0;
+
+       /* The physical ports are always vpi 0 - translate is unnecessary. */
+       if (vpi > 0) {
+               /*
+                * Translate the physical vpi to the logical vpi.  The
+                * vport stores the logical vpi.
+                */
+               for (i = 0; i < phba->max_vpi; i++) {
+                       if (vpi == phba->vpi_ids[i])
+                               break;
+               }
+
+               if (i >= phba->max_vpi) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
+                                        "2936 Could not find Vport mapped "
+                                        "to vpi %d\n", vpi);
+                       return NULL;
+               }
+       }
 
        spin_lock_irqsave(&phba->hbalock, flags);
        list_for_each_entry(vport, &phba->port_list, listentry) {
-               if (vport->vpi == vpi) {
+               if (vport->vpi == i) {
                        spin_unlock_irqrestore(&phba->hbalock, flags);
                        return vport;
                }
@@ -6641,8 +6681,9 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                        vport = phba->pport;
                else
                        vport = lpfc_find_vport_by_vpid(phba,
-                               icmd->unsli3.rcvsli3.vpi - phba->vpi_base);
+                                               icmd->unsli3.rcvsli3.vpi);
        }
+
        /* If there are no BDEs associated
         * with this IOCB, there is nothing to do.
         */
@@ -7222,7 +7263,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1;
                elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ;
                /* Set the ulpContext to the vpi */
-               elsiocb->iocb.ulpContext = vport->vpi + phba->vpi_base;
+               elsiocb->iocb.ulpContext = phba->vpi_ids[vport->vpi];
        } else {
                /* For FDISC, Let FDISC rsp set the NPortID for this VPI */
                icmd->ulpCt_h = 1;
@@ -7765,6 +7806,7 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
 {
        uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
        uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri);
+       uint16_t lxri = 0;
 
        struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
        unsigned long iflag = 0;
@@ -7793,7 +7835,12 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
                }
        }
        spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
-       sglq_entry = __lpfc_get_active_sglq(phba, xri);
+       lxri = lpfc_sli4_xri_inrange(phba, xri);
+       if (lxri == NO_XRI) {
+               spin_unlock_irqrestore(&phba->hbalock, iflag);
+               return;
+       }
+       sglq_entry = __lpfc_get_active_sglq(phba, lxri);
        if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
                spin_unlock_irqrestore(&phba->hbalock, iflag);
                return;