📄 lpfc_ct.c
字号:
struct lpfc_dmabuf *outp; struct lpfc_nodelist *ndlp; struct lpfc_sli_ct_request *CTrsp; psli = &phba->sli; /* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; inp = (struct lpfc_dmabuf *) cmdiocb->context1; outp = (struct lpfc_dmabuf *) cmdiocb->context2; bmp = (struct lpfc_dmabuf *) cmdiocb->context3; irsp = &rspiocb->iocb; if (irsp->ulpStatus) { if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) || (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) { goto out; } /* Check for retry */ if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { phba->fc_ns_retry++; /* CT command is being retried */ ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, NameServer_DID); if (ndlp) { if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { goto out; } } } } else { /* Good status, continue checking */ CTrsp = (struct lpfc_sli_ct_request *) outp->virt; if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { lpfc_ns_rsp(phba, outp, (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); } else if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { /* NameServer Rsp Error */ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, "%d:0240 NameServer Rsp Error " "Data: x%x x%x x%x x%x\n", phba->brd_no, CTrsp->CommandResponse.bits.CmdRsp, (uint32_t) CTrsp->ReasonCode, (uint32_t) CTrsp->Explanation, phba->fc_flag); } else { /* NameServer Rsp Error */ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, "%d:0241 NameServer Rsp Error " "Data: x%x x%x x%x x%x\n", phba->brd_no, CTrsp->CommandResponse.bits.CmdRsp, (uint32_t) CTrsp->ReasonCode, (uint32_t) CTrsp->Explanation, phba->fc_flag); } } /* Link up / RSCN discovery */ lpfc_disc_start(phba);out: lpfc_free_ct_rsp(phba, outp); lpfc_mbuf_free(phba, inp->virt, inp->phys); lpfc_mbuf_free(phba, bmp->virt, bmp->phys); kfree(inp); kfree(bmp); spin_lock_irq(phba->host->host_lock); lpfc_sli_release_iocbq(phba, cmdiocb); spin_unlock_irq(phba->host->host_lock); return;}static voidlpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb){ struct lpfc_sli *psli; struct lpfc_dmabuf *bmp; struct lpfc_dmabuf *inp; struct lpfc_dmabuf *outp; IOCB_t *irsp; struct lpfc_sli_ct_request *CTrsp; psli = &phba->sli; /* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; inp = (struct lpfc_dmabuf *) cmdiocb->context1; outp = (struct lpfc_dmabuf *) cmdiocb->context2; bmp = (struct lpfc_dmabuf *) cmdiocb->context3; irsp = &rspiocb->iocb; CTrsp = (struct lpfc_sli_ct_request *) outp->virt; /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, "%d:0209 RFT request completes ulpStatus x%x " "CmdRsp x%x\n", phba->brd_no, irsp->ulpStatus, CTrsp->CommandResponse.bits.CmdRsp); lpfc_free_ct_rsp(phba, outp); lpfc_mbuf_free(phba, inp->virt, inp->phys); lpfc_mbuf_free(phba, bmp->virt, bmp->phys); kfree(inp); kfree(bmp); spin_lock_irq(phba->host->host_lock); lpfc_sli_release_iocbq(phba, cmdiocb); spin_unlock_irq(phba->host->host_lock); return;}static voidlpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb){ lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); return;}static voidlpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb){ lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); return;}voidlpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp){ char fwrev[16]; lpfc_decode_firmware_rev(phba, fwrev, 0); if (phba->Port[0]) { sprintf(symbp, "Emulex %s Port %s FV%s DV%s", phba->ModelName, phba->Port, fwrev, lpfc_release_version); } else { sprintf(symbp, "Emulex %s FV%s DV%s", phba->ModelName, fwrev, lpfc_release_version); }}/* * lpfc_ns_cmd * Description: * Issue Cmd to NameServer * SLI_CTNS_GID_FT * LI_CTNS_RFT_ID */intlpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode){ struct lpfc_dmabuf *mp, *bmp; struct lpfc_sli_ct_request *CtReq; struct ulp_bde64 *bpl; void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, struct lpfc_iocbq *) = NULL; uint32_t rsp_size = 1024; /* fill in BDEs for command */ /* Allocate buffer for command payload */ mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); if (!mp) goto ns_cmd_exit; INIT_LIST_HEAD(&mp->list); mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys)); if (!mp->virt) goto ns_cmd_free_mp; /* Allocate buffer for Buffer ptr list */ bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); if (!bmp) goto ns_cmd_free_mpvirt; INIT_LIST_HEAD(&bmp->list); bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys)); if (!bmp->virt) goto ns_cmd_free_bmp; /* NameServer Req */ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, "%d:0236 NameServer Req Data: x%x x%x x%x\n", phba->brd_no, cmdcode, phba->fc_flag, phba->fc_rscn_id_cnt); bpl = (struct ulp_bde64 *) bmp->virt; memset(bpl, 0, sizeof(struct ulp_bde64)); bpl->addrHigh = le32_to_cpu( putPaddrHigh(mp->phys) ); bpl->addrLow = le32_to_cpu( putPaddrLow(mp->phys) ); bpl->tus.f.bdeFlags = 0; if (cmdcode == SLI_CTNS_GID_FT) bpl->tus.f.bdeSize = GID_REQUEST_SZ; else if (cmdcode == SLI_CTNS_RFT_ID) bpl->tus.f.bdeSize = RFT_REQUEST_SZ; else if (cmdcode == SLI_CTNS_RNN_ID) bpl->tus.f.bdeSize = RNN_REQUEST_SZ; else if (cmdcode == SLI_CTNS_RSNN_NN) bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; else bpl->tus.f.bdeSize = 0; bpl->tus.w = le32_to_cpu(bpl->tus.w); CtReq = (struct lpfc_sli_ct_request *) mp->virt; memset(CtReq, 0, sizeof (struct lpfc_sli_ct_request)); CtReq->RevisionId.bits.Revision = SLI_CT_REVISION; CtReq->RevisionId.bits.InId = 0; CtReq->FsType = SLI_CT_DIRECTORY_SERVICE; CtReq->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER; CtReq->CommandResponse.bits.Size = 0; switch (cmdcode) { case SLI_CTNS_GID_FT: CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_CTNS_GID_FT); CtReq->un.gid.Fc4Type = SLI_CTPT_FCP; if (phba->hba_state < LPFC_HBA_READY) phba->hba_state = LPFC_NS_QRY; lpfc_set_disctmo(phba); cmpl = lpfc_cmpl_ct_cmd_gid_ft; rsp_size = FC_MAX_NS_RSP; break; case SLI_CTNS_RFT_ID: CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_CTNS_RFT_ID); CtReq->un.rft.PortId = be32_to_cpu(phba->fc_myDID); CtReq->un.rft.fcpReg = 1; cmpl = lpfc_cmpl_ct_cmd_rft_id; break; case SLI_CTNS_RNN_ID: CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_CTNS_RNN_ID); CtReq->un.rnn.PortId = be32_to_cpu(phba->fc_myDID); memcpy(CtReq->un.rnn.wwnn, &phba->fc_nodename, sizeof (struct lpfc_name)); cmpl = lpfc_cmpl_ct_cmd_rnn_id; break; case SLI_CTNS_RSNN_NN: CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_CTNS_RSNN_NN); memcpy(CtReq->un.rsnn.wwnn, &phba->fc_nodename, sizeof (struct lpfc_name)); lpfc_get_hba_sym_node_name(phba, CtReq->un.rsnn.symbname); CtReq->un.rsnn.len = strlen(CtReq->un.rsnn.symbname); cmpl = lpfc_cmpl_ct_cmd_rsnn_nn; break; } if (!lpfc_ct_cmd(phba, mp, bmp, ndlp, cmpl, rsp_size)) /* On success, The cmpl function will free the buffers */ return 0; lpfc_mbuf_free(phba, bmp->virt, bmp->phys);ns_cmd_free_bmp: kfree(bmp);ns_cmd_free_mpvirt: lpfc_mbuf_free(phba, mp->virt, mp->phys);ns_cmd_free_mp: kfree(mp);ns_cmd_exit: return 1;}static voidlpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb){ struct lpfc_dmabuf *bmp = cmdiocb->context3; struct lpfc_dmabuf *inp = cmdiocb->context1; struct lpfc_dmabuf *outp = cmdiocb->context2; struct lpfc_sli_ct_request *CTrsp = outp->virt; struct lpfc_sli_ct_request *CTcmd = inp->virt; struct lpfc_nodelist *ndlp; uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { /* FDMI rsp failed */ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, "%d:0220 FDMI rsp failed Data: x%x\n", phba->brd_no, be16_to_cpu(fdmi_cmd)); } switch (be16_to_cpu(fdmi_cmd)) { case SLI_MGMT_RHBA: lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RPA); break; case SLI_MGMT_RPA: break; case SLI_MGMT_DHBA: lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DPRT); break; case SLI_MGMT_DPRT: lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RHBA); break; } lpfc_free_ct_rsp(phba, outp); lpfc_mbuf_free(phba, inp->virt, inp->phys); lpfc_mbuf_free(phba, bmp->virt, bmp->phys); kfree(inp); kfree(bmp); spin_lock_irq(phba->host->host_lock); lpfc_sli_release_iocbq(phba, cmdiocb); spin_unlock_irq(phba->host->host_lock); return;}intlpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode){ struct lpfc_dmabuf *mp, *bmp; struct lpfc_sli_ct_request *CtReq; struct ulp_bde64 *bpl; uint32_t size; REG_HBA *rh; PORT_ENTRY *pe; REG_PORT_ATTRIBUTE *pab; ATTRIBUTE_BLOCK *ab; ATTRIBUTE_ENTRY *ae; void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, struct lpfc_iocbq *); /* fill in BDEs for command */ /* Allocate buffer for command payload */ mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); if (!mp) goto fdmi_cmd_exit; mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys)); if (!mp->virt) goto fdmi_cmd_free_mp; /* Allocate buffer for Buffer ptr list */ bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); if (!bmp) goto fdmi_cmd_free_mpvirt; bmp->virt = lpfc_mbuf_alloc(phba, 0, &(bmp->phys)); if (!bmp->virt) goto fdmi_cmd_free_bmp; INIT_LIST_HEAD(&mp->list); INIT_LIST_HEAD(&bmp->list); /* FDMI request */ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, "%d:0218 FDMI Request Data: x%x x%x x%x\n", phba->brd_no, phba->fc_flag, phba->hba_state, cmdcode); CtReq = (struct lpfc_sli_ct_request *) mp->virt; memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request)); CtReq->RevisionId.bits.Revision = SLI_CT_REVISION; CtReq->RevisionId.bits.InId = 0; CtReq->FsType = SLI_CT_MANAGEMENT_SERVICE; CtReq->FsSubType = SLI_CT_FDMI_Subtypes; size = 0; switch (cmdcode) { case SLI_MGMT_RHBA: { lpfc_vpd_t *vp = &phba->vpd; uint32_t i, j, incr; int len; CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_MGMT_RHBA); CtReq->CommandResponse.bits.Size = 0; rh = (REG_HBA *) & CtReq->un.PortID; memcpy(&rh->hi.PortName, &phba->fc_sparam.portName, sizeof (struct lpfc_name)); /* One entry (port) per adapter */ rh->rpl.EntryCnt = be32_to_cpu(1); memcpy(&rh->rpl.pe, &phba->fc_sparam.portName, sizeof (struct lpfc_name)); /* point to the HBA attribute block */ size = 2 * sizeof (struct lpfc_name) + FOURBYTES; ab = (ATTRIBUTE_BLOCK *) ((uint8_t *) rh + size); ab->EntryCnt = 0; /* Point to the beginning of the first HBA attribute entry */ /* #1 HBA attribute entry */ size += FOURBYTES; ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); ae->ad.bits.AttrType = be16_to_cpu(NODE_NAME);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -