--- zzzz-none-000/linux-3.10.107/drivers/scsi/lpfc/lpfc_ct.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/scsi/lpfc/lpfc_ct.c 2021-02-04 17:41:59.000000000 +0000 @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2010 Emulex. All rights reserved. * + * Copyright (C) 2004-2015 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -55,6 +55,7 @@ #define HBA_PORTSPEED_10GBIT 0x0004 /* 10 GBit/sec */ #define HBA_PORTSPEED_8GBIT 0x0010 /* 8 GBit/sec */ #define HBA_PORTSPEED_16GBIT 0x0020 /* 16 GBit/sec */ +#define HBA_PORTSPEED_32GBIT 0x0040 /* 32 GBit/sec */ #define HBA_PORTSPEED_UNKNOWN 0x0800 /* Unknown */ #define FOURBYTES 4 @@ -280,7 +281,7 @@ buf_ptr = (struct lpfc_dmabuf *) ctiocb->context3; lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); kfree(buf_ptr); - ctiocb->context1 = NULL; + ctiocb->context3 = NULL; } lpfc_sli_release_iocbq(phba, ctiocb); return 0; @@ -555,7 +556,7 @@ } } } - if (CTentry & (be32_to_cpu(SLI_CT_LAST_ENTRY))) + if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY))) goto nsout1; Cnt -= sizeof (uint32_t); } @@ -575,7 +576,6 @@ struct lpfc_vport *vport = cmdiocb->vport; struct Scsi_Host *shost = lpfc_shost_from_vport(vport); IOCB_t *irsp; - struct lpfc_dmabuf *bmp; struct lpfc_dmabuf *outp; struct lpfc_sli_ct_request *CTrsp; struct lpfc_nodelist *ndlp; @@ -588,7 +588,6 @@ cmdiocb->context_un.rsp_iocb = rspiocb; outp = (struct lpfc_dmabuf *) cmdiocb->context2; - bmp = (struct lpfc_dmabuf *) cmdiocb->context3; irsp = &rspiocb->iocb; lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, @@ -641,7 +640,7 @@ /* 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)) { + cpu_to_be16(SLI_CT_RESPONSE_FS_ACC)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0208 NameServer Rsp Data: x%x\n", vport->fc_flag); @@ -895,7 +894,7 @@ if (irsp->ulpStatus) { lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, - "0268 NS cmd %x Error (%d %d)\n", + "0268 NS cmd x%x Error (x%x x%x)\n", cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]); if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && @@ -1074,11 +1073,48 @@ lpfc_decode_firmware_rev(vport->phba, fwrev, 0); - n = snprintf(symbol, size, "Emulex %s FV%s DV%s", - vport->phba->ModelName, fwrev, lpfc_release_version); + n = snprintf(symbol, size, "Emulex %s", vport->phba->ModelName); + + if (size < n) + return n; + n += snprintf(symbol + n, size - n, " FV%s", fwrev); + + if (size < n) + return n; + n += snprintf(symbol + n, size - n, " DV%s", lpfc_release_version); + + if (size < n) + return n; + n += snprintf(symbol + n, size - n, " HN:%s", init_utsname()->nodename); + + /* Note :- OS name is "Linux" */ + if (size < n) + return n; + n += snprintf(symbol + n, size - n, " OS:%s", init_utsname()->sysname); + return n; } +static uint32_t +lpfc_find_map_node(struct lpfc_vport *vport) +{ + struct lpfc_nodelist *ndlp, *next_ndlp; + struct Scsi_Host *shost; + uint32_t cnt = 0; + + shost = lpfc_shost_from_vport(vport); + spin_lock_irq(shost->host_lock); + list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { + if (ndlp->nlp_type & NLP_FABRIC) + continue; + if ((ndlp->nlp_state == NLP_STE_MAPPED_NODE) || + (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE)) + cnt++; + } + spin_unlock_irq(shost->host_lock); + return cnt; +} + /* * lpfc_ns_cmd * Description: @@ -1177,7 +1213,7 @@ switch (cmdcode) { case SLI_CTNS_GID_FT: CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_CTNS_GID_FT); + cpu_to_be16(SLI_CTNS_GID_FT); CtReq->un.gid.Fc4Type = SLI_CTPT_FCP; if (vport->port_state < LPFC_NS_QRY) vport->port_state = LPFC_NS_QRY; @@ -1188,7 +1224,7 @@ case SLI_CTNS_GFF_ID: CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_CTNS_GFF_ID); + cpu_to_be16(SLI_CTNS_GFF_ID); CtReq->un.gff.PortId = cpu_to_be32(context); cmpl = lpfc_cmpl_ct_cmd_gff_id; break; @@ -1196,7 +1232,7 @@ case SLI_CTNS_RFT_ID: vport->ct_flags &= ~FC_CT_RFT_ID; CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_CTNS_RFT_ID); + cpu_to_be16(SLI_CTNS_RFT_ID); CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID); CtReq->un.rft.fcpReg = 1; cmpl = lpfc_cmpl_ct_cmd_rft_id; @@ -1205,7 +1241,7 @@ case SLI_CTNS_RNN_ID: vport->ct_flags &= ~FC_CT_RNN_ID; CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_CTNS_RNN_ID); + cpu_to_be16(SLI_CTNS_RNN_ID); CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID); memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, sizeof (struct lpfc_name)); @@ -1215,7 +1251,7 @@ case SLI_CTNS_RSPN_ID: vport->ct_flags &= ~FC_CT_RSPN_ID; CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_CTNS_RSPN_ID); + cpu_to_be16(SLI_CTNS_RSPN_ID); CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID); size = sizeof(CtReq->un.rspn.symbname); CtReq->un.rspn.len = @@ -1226,7 +1262,7 @@ case SLI_CTNS_RSNN_NN: vport->ct_flags &= ~FC_CT_RSNN_NN; CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_CTNS_RSNN_NN); + cpu_to_be16(SLI_CTNS_RSNN_NN); memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, sizeof (struct lpfc_name)); size = sizeof(CtReq->un.rsnn.symbname); @@ -1238,14 +1274,14 @@ case SLI_CTNS_DA_ID: /* Implement DA_ID Nameserver request */ CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_CTNS_DA_ID); + cpu_to_be16(SLI_CTNS_DA_ID); CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID); cmpl = lpfc_cmpl_ct_cmd_da_id; break; case SLI_CTNS_RFF_ID: vport->ct_flags &= ~FC_CT_RFF_ID; CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_CTNS_RFF_ID); + cpu_to_be16(SLI_CTNS_RFF_ID); CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID); CtReq->un.rff.fbits = FC4_FEATURE_INIT; CtReq->un.rff.type_code = FC_TYPE_FCP; @@ -1299,7 +1335,6 @@ uint32_t latt; latt = lpfc_els_chk_latt(vport); - lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, "FDMI cmpl: status:x%x/x%x latt:%d", irsp->ulpStatus, irsp->un.ulpWord[4], latt); @@ -1310,29 +1345,49 @@ "ulpStatus: x%x, rid x%x\n", be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus, irsp->un.ulpWord[4]); - lpfc_ct_free_iocb(phba, cmdiocb); - return; + goto fail_out; } ndlp = lpfc_findnode_did(vport, FDMI_DID); if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) goto fail_out; - if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { + if (fdmi_rsp == cpu_to_be16(SLI_CT_RESPONSE_FS_RJT)) { /* FDMI rsp failed */ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0220 FDMI rsp failed Data: x%x\n", be16_to_cpu(fdmi_cmd)); } +fail_out: + lpfc_ct_free_iocb(phba, cmdiocb); +} + +static void +lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + struct lpfc_iocbq *rspiocb) +{ + struct lpfc_vport *vport = cmdiocb->vport; + struct lpfc_dmabuf *inp = cmdiocb->context1; + struct lpfc_sli_ct_request *CTcmd = inp->virt; + uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; + struct lpfc_nodelist *ndlp; + + lpfc_cmpl_ct_cmd_fdmi(phba, cmdiocb, rspiocb); + + ndlp = lpfc_findnode_did(vport, FDMI_DID); + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) + return; + + /* + * Need to cycle thru FDMI registration for discovery + * DHBA -> DPRT -> RHBA -> RPA + */ switch (be16_to_cpu(fdmi_cmd)) { case SLI_MGMT_RHBA: lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA); break; - case SLI_MGMT_RPA: - break; - case SLI_MGMT_DHBA: lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT); break; @@ -1341,12 +1396,9 @@ lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA); break; } - -fail_out: - lpfc_ct_free_iocb(phba, cmdiocb); - return; } + int lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) { @@ -1355,18 +1407,28 @@ 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; + uint32_t rsp_size; + struct lpfc_fdmi_reg_hba *rh; + struct lpfc_fdmi_port_entry *pe; + struct lpfc_fdmi_reg_portattr *pab = NULL; + struct lpfc_fdmi_attr_block *ab = NULL; + struct lpfc_fdmi_attr_entry *ae; + struct lpfc_fdmi_attr_def *ad; void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, struct lpfc_iocbq *); + if (ndlp == NULL) { + ndlp = lpfc_findnode_did(vport, FDMI_DID); + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) + return 0; + cmpl = lpfc_cmpl_ct_cmd_fdmi; /* cmd interface */ + } else { + cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */ + } /* fill in BDEs for command */ /* Allocate buffer for command payload */ - mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); + mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (!mp) goto fdmi_cmd_exit; @@ -1375,7 +1437,7 @@ goto fdmi_cmd_free_mp; /* Allocate buffer for Buffer ptr list */ - bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); + bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (!bmp) goto fdmi_cmd_free_mpvirt; @@ -1390,204 +1452,330 @@ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0218 FDMI Request Data: x%x x%x x%x\n", vport->fc_flag, vport->port_state, cmdcode); - CtReq = (struct lpfc_sli_ct_request *) mp->virt; + CtReq = (struct lpfc_sli_ct_request *)mp->virt; + /* First populate the CT_IU preamble */ 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; + + CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(cmdcode); + rsp_size = LPFC_BPL_SIZE; size = 0; + /* Next fill in the specific FDMI cmd information */ switch (cmdcode) { + case SLI_MGMT_RHAT: case SLI_MGMT_RHBA: { lpfc_vpd_t *vp = &phba->vpd; uint32_t i, j, incr; - int len; + int len = 0; - CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_MGMT_RHBA); - CtReq->CommandResponse.bits.Size = 0; - rh = (REG_HBA *) & CtReq->un.PortID; + rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID; + /* HBA Identifier */ memcpy(&rh->hi.PortName, &vport->fc_sparam.portName, - sizeof (struct lpfc_name)); - /* One entry (port) per adapter */ - rh->rpl.EntryCnt = be32_to_cpu(1); - memcpy(&rh->rpl.pe, &vport->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); + sizeof(struct lpfc_name)); + + if (cmdcode == SLI_MGMT_RHBA) { + /* Registered Port List */ + /* One entry (port) per adapter */ + rh->rpl.EntryCnt = cpu_to_be32(1); + memcpy(&rh->rpl.pe, &vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + + /* point to the HBA attribute block */ + size = 2 * sizeof(struct lpfc_name) + + FOURBYTES; + } else { + size = sizeof(struct lpfc_name); + } + ab = (struct lpfc_fdmi_attr_block *) + ((uint8_t *)rh + size); ab->EntryCnt = 0; + size += FOURBYTES; - /* Point to the beginning of the first HBA attribute - entry */ + /* + * Point to beginning of 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); - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES - + sizeof (struct lpfc_name)); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + ad->AttrType = cpu_to_be16(RHBA_NODENAME); + ad->AttrLen = cpu_to_be16(FOURBYTES + + sizeof(struct lpfc_name)); memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, - sizeof (struct lpfc_name)); + sizeof(struct lpfc_name)); ab->EntryCnt++; - size += FOURBYTES + sizeof (struct lpfc_name); + size += FOURBYTES + sizeof(struct lpfc_name); + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #2 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(MANUFACTURER); - strcpy(ae->un.Manufacturer, "Emulex Corporation"); - len = strlen(ae->un.Manufacturer); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.Manufacturer)); + ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER); + strncpy(ae->un.Manufacturer, "Emulex Corporation", + sizeof(ae->un.Manufacturer)); + len = strnlen(ae->un.Manufacturer, + sizeof(ae->un.Manufacturer)); len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len); + ad->AttrLen = cpu_to_be16(FOURBYTES + len); ab->EntryCnt++; size += FOURBYTES + len; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #3 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(SERIAL_NUMBER); - strcpy(ae->un.SerialNumber, phba->SerialNumber); - len = strlen(ae->un.SerialNumber); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.SerialNumber)); + ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER); + strncpy(ae->un.SerialNumber, phba->SerialNumber, + sizeof(ae->un.SerialNumber)); + len = strnlen(ae->un.SerialNumber, + sizeof(ae->un.SerialNumber)); len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len); + ad->AttrLen = cpu_to_be16(FOURBYTES + len); ab->EntryCnt++; size += FOURBYTES + len; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #4 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(MODEL); - strcpy(ae->un.Model, phba->ModelName); - len = strlen(ae->un.Model); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.Model)); + ad->AttrType = cpu_to_be16(RHBA_MODEL); + strncpy(ae->un.Model, phba->ModelName, + sizeof(ae->un.Model)); + len = strnlen(ae->un.Model, sizeof(ae->un.Model)); len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len); + ad->AttrLen = cpu_to_be16(FOURBYTES + len); ab->EntryCnt++; size += FOURBYTES + len; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #5 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(MODEL_DESCRIPTION); - strcpy(ae->un.ModelDescription, phba->ModelDesc); - len = strlen(ae->un.ModelDescription); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.ModelDescription)); + ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION); + strncpy(ae->un.ModelDescription, phba->ModelDesc, + sizeof(ae->un.ModelDescription)); + len = strnlen(ae->un.ModelDescription, + sizeof(ae->un.ModelDescription)); len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len); + ad->AttrLen = cpu_to_be16(FOURBYTES + len); ab->EntryCnt++; size += FOURBYTES + len; + if ((size + 8) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #6 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(HARDWARE_VERSION); - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 8); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, 8); + ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION); + ad->AttrLen = cpu_to_be16(FOURBYTES + 8); /* Convert JEDEC ID to ascii for hardware version */ incr = vp->rev.biuRev; for (i = 0; i < 8; i++) { j = (incr & 0xf); if (j <= 9) ae->un.HardwareVersion[7 - i] = - (char)((uint8_t) 0x30 + - (uint8_t) j); + (char)((uint8_t)0x30 + + (uint8_t)j); else ae->un.HardwareVersion[7 - i] = - (char)((uint8_t) 0x61 + - (uint8_t) (j - 10)); + (char)((uint8_t)0x61 + + (uint8_t)(j - 10)); incr = (incr >> 4); } ab->EntryCnt++; size += FOURBYTES + 8; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #7 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(DRIVER_VERSION); - strcpy(ae->un.DriverVersion, lpfc_release_version); - len = strlen(ae->un.DriverVersion); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.DriverVersion)); + ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION); + strncpy(ae->un.DriverVersion, lpfc_release_version, + sizeof(ae->un.DriverVersion)); + len = strnlen(ae->un.DriverVersion, + sizeof(ae->un.DriverVersion)); len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len); + ad->AttrLen = cpu_to_be16(FOURBYTES + len); ab->EntryCnt++; size += FOURBYTES + len; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #8 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(OPTION_ROM_VERSION); - strcpy(ae->un.OptionROMVersion, phba->OptionROMVersion); - len = strlen(ae->un.OptionROMVersion); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.OptionROMVersion)); + ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION); + strncpy(ae->un.OptionROMVersion, phba->OptionROMVersion, + sizeof(ae->un.OptionROMVersion)); + len = strnlen(ae->un.OptionROMVersion, + sizeof(ae->un.OptionROMVersion)); len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len); + ad->AttrLen = cpu_to_be16(FOURBYTES + len); ab->EntryCnt++; size += FOURBYTES + len; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #9 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(FIRMWARE_VERSION); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.FirmwareVersion)); + ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION); lpfc_decode_firmware_rev(phba, ae->un.FirmwareVersion, 1); - len = strlen(ae->un.FirmwareVersion); + len = strnlen(ae->un.FirmwareVersion, + sizeof(ae->un.FirmwareVersion)); len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len); + ad->AttrLen = cpu_to_be16(FOURBYTES + len); ab->EntryCnt++; size += FOURBYTES + len; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #10 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION); - sprintf(ae->un.OsNameVersion, "%s %s %s", - init_utsname()->sysname, - init_utsname()->release, - init_utsname()->version); - len = strlen(ae->un.OsNameVersion); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.OsNameVersion)); + ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION); + snprintf(ae->un.OsNameVersion, + sizeof(ae->un.OsNameVersion), + "%s %s %s", + init_utsname()->sysname, + init_utsname()->release, + init_utsname()->version); + len = strnlen(ae->un.OsNameVersion, + sizeof(ae->un.OsNameVersion)); len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len); + ad->AttrLen = cpu_to_be16(FOURBYTES + len); ab->EntryCnt++; size += FOURBYTES + len; + if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; /* #11 HBA attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); - ae->ad.bits.AttrType = be16_to_cpu(MAX_CT_PAYLOAD_LEN); - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); - ae->un.MaxCTPayloadLen = (65 * 4096); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ad->AttrType = + cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN); + ad->AttrLen = cpu_to_be16(FOURBYTES + 4); + ae->un.MaxCTPayloadLen = cpu_to_be32(LPFC_MAX_CT_SIZE); ab->EntryCnt++; size += FOURBYTES + 4; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; + + /* + * Currently switches don't seem to support the + * following extended HBA attributes. + */ + if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB)) + goto hba_out; - ab->EntryCnt = be32_to_cpu(ab->EntryCnt); + /* #12 HBA attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.NodeSymName)); + ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME); + len = lpfc_vport_symbolic_node_name(vport, + ae->un.NodeSymName, sizeof(ae->un.NodeSymName)); + len += (len & 3) ? (4 - (len & 3)) : 4; + ad->AttrLen = cpu_to_be16(FOURBYTES + len); + ab->EntryCnt++; + size += FOURBYTES + len; +hba_out: + ab->EntryCnt = cpu_to_be32(ab->EntryCnt); /* Total size */ size = GID_REQUEST_SZ - 4 + size; } break; + case SLI_MGMT_RPRT: case SLI_MGMT_RPA: { - lpfc_vpd_t *vp; struct serv_parm *hsp; - int len; - - vp = &phba->vpd; + int len = 0; - CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_MGMT_RPA); - CtReq->CommandResponse.bits.Size = 0; - pab = (REG_PORT_ATTRIBUTE *) & CtReq->un.PortID; - size = sizeof (struct lpfc_name) + FOURBYTES; - memcpy((uint8_t *) & pab->PortName, - (uint8_t *) & vport->fc_sparam.portName, - sizeof (struct lpfc_name)); + if (cmdcode == SLI_MGMT_RPRT) { + rh = (struct lpfc_fdmi_reg_hba *) + &CtReq->un.PortID; + /* HBA Identifier */ + memcpy(&rh->hi.PortName, + &vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + pab = (struct lpfc_fdmi_reg_portattr *) + &rh->rpl.EntryCnt; + } else + pab = (struct lpfc_fdmi_reg_portattr *) + &CtReq->un.PortID; + size = sizeof(struct lpfc_name) + FOURBYTES; + memcpy((uint8_t *)&pab->PortName, + (uint8_t *)&vport->fc_sparam.portName, + sizeof(struct lpfc_name)); pab->ab.EntryCnt = 0; /* #1 Port attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); - ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_FC4_TYPES); - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 32); - ae->un.SupportFC4Types[2] = 1; - ae->un.SupportFC4Types[7] = 1; + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.FC4Types)); + ad->AttrType = + cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); + ad->AttrLen = cpu_to_be16(FOURBYTES + 32); + ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */ + ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */ + ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */ pab->ab.EntryCnt++; size += FOURBYTES + 32; /* #2 Port attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); - ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED); - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); - + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); + ad->AttrLen = cpu_to_be16(FOURBYTES + 4); ae->un.SupportSpeed = 0; + if (phba->lmt & LMT_32Gb) + ae->un.SupportSpeed |= HBA_PORTSPEED_32GBIT; if (phba->lmt & LMT_16Gb) ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT; if (phba->lmt & LMT_10Gb) @@ -1600,15 +1788,19 @@ ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT; if (phba->lmt & LMT_1Gb) ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT; + ae->un.SupportSpeed = + cpu_to_be32(ae->un.SupportSpeed); pab->ab.EntryCnt++; size += FOURBYTES + 4; /* #3 Port attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); - ae->ad.bits.AttrType = be16_to_cpu(PORT_SPEED); - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); - switch(phba->fc_linkspeed) { + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED); + ad->AttrLen = cpu_to_be16(FOURBYTES + 4); + switch (phba->fc_linkspeed) { case LPFC_LINK_SPEED_1GHZ: ae->un.PortSpeed = HBA_PORTSPEED_1GBIT; break; @@ -1627,97 +1819,280 @@ case LPFC_LINK_SPEED_16GHZ: ae->un.PortSpeed = HBA_PORTSPEED_16GBIT; break; + case LPFC_LINK_SPEED_32GHZ: + ae->un.PortSpeed = HBA_PORTSPEED_32GBIT; + break; default: ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN; break; } + ae->un.PortSpeed = cpu_to_be32(ae->un.PortSpeed); pab->ab.EntryCnt++; size += FOURBYTES + 4; /* #4 Port attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); - ae->ad.bits.AttrType = be16_to_cpu(MAX_FRAME_SIZE); - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); - hsp = (struct serv_parm *) & vport->fc_sparam; + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE); + ad->AttrLen = cpu_to_be16(FOURBYTES + 4); + hsp = (struct serv_parm *)&vport->fc_sparam; ae->un.MaxFrameSize = - (((uint32_t) hsp->cmn. - bbRcvSizeMsb) << 8) | (uint32_t) hsp->cmn. + (((uint32_t)hsp->cmn. + bbRcvSizeMsb) << 8) | (uint32_t)hsp->cmn. bbRcvSizeLsb; + ae->un.MaxFrameSize = + cpu_to_be32(ae->un.MaxFrameSize); pab->ab.EntryCnt++; size += FOURBYTES + 4; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; /* #5 Port attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); - ae->ad.bits.AttrType = be16_to_cpu(OS_DEVICE_NAME); - strcpy((char *)ae->un.OsDeviceName, LPFC_DRIVER_NAME); - len = strlen((char *)ae->un.OsDeviceName); + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.OsDeviceName)); + ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME); + strncpy((char *)ae->un.OsDeviceName, LPFC_DRIVER_NAME, + sizeof(ae->un.OsDeviceName)); + len = strnlen((char *)ae->un.OsDeviceName, + sizeof(ae->un.OsDeviceName)); len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len); + ad->AttrLen = cpu_to_be16(FOURBYTES + len); pab->ab.EntryCnt++; size += FOURBYTES + len; + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + + /* #6 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.HostName)); + snprintf(ae->un.HostName, sizeof(ae->un.HostName), "%s", + init_utsname()->nodename); + ad->AttrType = cpu_to_be16(RPRT_HOST_NAME); + len = strnlen(ae->un.HostName, + sizeof(ae->un.HostName)); + len += (len & 3) ? (4 - (len & 3)) : 4; + ad->AttrLen = + cpu_to_be16(FOURBYTES + len); + pab->ab.EntryCnt++; + size += FOURBYTES + len; + if ((size + sizeof(struct lpfc_name)) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; - if (vport->cfg_fdmi_on == 2) { - /* #6 Port attribute entry */ - ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + - size); - ae->ad.bits.AttrType = be16_to_cpu(HOST_NAME); - sprintf(ae->un.HostName, "%s", - init_utsname()->nodename); - len = strlen(ae->un.HostName); - len += (len & 3) ? (4 - (len & 3)) : 4; - ae->ad.bits.AttrLen = - be16_to_cpu(FOURBYTES + len); - pab->ab.EntryCnt++; - size += FOURBYTES + len; - } + /* + * Currently switches don't seem to support the + * following extended Port attributes. + */ + if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB)) + goto port_out; + + /* #7 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + ad->AttrType = cpu_to_be16(RPRT_NODENAME); + ad->AttrLen = cpu_to_be16(FOURBYTES + + sizeof(struct lpfc_name)); + memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, + sizeof(struct lpfc_name)); + pab->ab.EntryCnt++; + size += FOURBYTES + sizeof(struct lpfc_name); + if ((size + sizeof(struct lpfc_name)) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + + /* #8 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + ad->AttrType = cpu_to_be16(RPRT_PORTNAME); + ad->AttrLen = cpu_to_be16(FOURBYTES + + sizeof(struct lpfc_name)); + memcpy(&ae->un.PortName, &vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + pab->ab.EntryCnt++; + size += FOURBYTES + sizeof(struct lpfc_name); + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + + /* #9 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.NodeSymName)); + ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME); + len = lpfc_vport_symbolic_port_name(vport, + ae->un.NodeSymName, sizeof(ae->un.NodeSymName)); + len += (len & 3) ? (4 - (len & 3)) : 4; + ad->AttrLen = cpu_to_be16(FOURBYTES + len); + pab->ab.EntryCnt++; + size += FOURBYTES + len; + if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; - pab->ab.EntryCnt = be32_to_cpu(pab->ab.EntryCnt); + /* #10 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE); + ae->un.PortState = 0; + ad->AttrLen = cpu_to_be16(FOURBYTES + 4); + pab->ab.EntryCnt++; + size += FOURBYTES + 4; + if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + + /* #11 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS); + ae->un.SupportClass = + cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); + ad->AttrLen = cpu_to_be16(FOURBYTES + 4); + pab->ab.EntryCnt++; + size += FOURBYTES + 4; + if ((size + sizeof(struct lpfc_name)) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + + /* #12 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(struct lpfc_name)); + ad->AttrType = cpu_to_be16(RPRT_FABRICNAME); + ad->AttrLen = cpu_to_be16(FOURBYTES + + sizeof(struct lpfc_name)); + memcpy(&ae->un.FabricName, &vport->fabric_nodename, + sizeof(struct lpfc_name)); + pab->ab.EntryCnt++; + size += FOURBYTES + sizeof(struct lpfc_name); + if ((size + LPFC_FDMI_MAX_AE_SIZE) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + + /* #13 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + memset(ae, 0, sizeof(ae->un.FC4Types)); + ad->AttrType = + cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); + ad->AttrLen = cpu_to_be16(FOURBYTES + 32); + ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */ + ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */ + ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */ + pab->ab.EntryCnt++; + size += FOURBYTES + 32; + if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + + /* #257 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ad->AttrType = cpu_to_be16(RPRT_PORT_STATE); + ae->un.PortState = 0; + ad->AttrLen = cpu_to_be16(FOURBYTES + 4); + pab->ab.EntryCnt++; + size += FOURBYTES + 4; + if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + + /* #258 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ad->AttrType = cpu_to_be16(RPRT_DISC_PORT); + ae->un.PortState = lpfc_find_map_node(vport); + ae->un.PortState = cpu_to_be32(ae->un.PortState); + ad->AttrLen = cpu_to_be16(FOURBYTES + 4); + pab->ab.EntryCnt++; + size += FOURBYTES + 4; + if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + + /* #259 Port attribute entry */ + ad = (struct lpfc_fdmi_attr_def *) + ((uint8_t *)pab + size); + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ad->AttrType = cpu_to_be16(RPRT_PORT_ID); + ae->un.PortId = cpu_to_be32(vport->fc_myDID); + ad->AttrLen = cpu_to_be16(FOURBYTES + 4); + pab->ab.EntryCnt++; + size += FOURBYTES + 4; +port_out: + pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt); /* Total size */ size = GID_REQUEST_SZ - 4 + size; } break; + case SLI_MGMT_GHAT: + case SLI_MGMT_GRPL: + rsp_size = FC_MAX_NS_RSP; case SLI_MGMT_DHBA: - CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_MGMT_DHBA); - CtReq->CommandResponse.bits.Size = 0; - pe = (PORT_ENTRY *) & CtReq->un.PortID; - memcpy((uint8_t *) & pe->PortName, - (uint8_t *) & vport->fc_sparam.portName, - sizeof (struct lpfc_name)); - size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); + case SLI_MGMT_DHAT: + pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID; + memcpy((uint8_t *)&pe->PortName, + (uint8_t *)&vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name); break; + case SLI_MGMT_GPAT: + case SLI_MGMT_GPAS: + rsp_size = FC_MAX_NS_RSP; case SLI_MGMT_DPRT: - CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_MGMT_DPRT); - CtReq->CommandResponse.bits.Size = 0; - pe = (PORT_ENTRY *) & CtReq->un.PortID; - memcpy((uint8_t *) & pe->PortName, - (uint8_t *) & vport->fc_sparam.portName, - sizeof (struct lpfc_name)); - size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); + case SLI_MGMT_DPA: + pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID; + memcpy((uint8_t *)&pe->PortName, + (uint8_t *)&vport->fc_sparam.portName, + sizeof(struct lpfc_name)); + size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name); break; - } - - bpl = (struct ulp_bde64 *) bmp->virt; - bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) ); - bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) ); + case SLI_MGMT_GRHL: + size = GID_REQUEST_SZ - 4; + break; + default: + lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY, + "0298 FDMI cmdcode x%x not supported\n", + cmdcode); + goto fdmi_cmd_free_bmpvirt; + } + CtReq->CommandResponse.bits.Size = cpu_to_be16(rsp_size); + + bpl = (struct ulp_bde64 *)bmp->virt; + bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys)); + bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys)); bpl->tus.f.bdeFlags = 0; bpl->tus.f.bdeSize = size; - bpl->tus.w = le32_to_cpu(bpl->tus.w); - cmpl = lpfc_cmpl_ct_cmd_fdmi; - - /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count + /* + * The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count * to hold ndlp reference for the corresponding callback function. */ - if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0)) + if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, 0)) return 0; - /* Decrement ndlp reference count to release ndlp reference held + /* + * Decrement ndlp reference count to release ndlp reference held * for the failed command's callback function. */ lpfc_nlp_put(ndlp); +fdmi_cmd_free_bmpvirt: lpfc_mbuf_free(phba, bmp->virt, bmp->phys); fdmi_cmd_free_bmp: kfree(bmp);