Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright(c) 2008 Intel Corporation. All rights reserved.
0004  *
0005  * Maintained at www.Open-FCoE.org
0006  */
0007 
0008 #ifndef _FC_ENCODE_H_
0009 #define _FC_ENCODE_H_
0010 #include <asm/unaligned.h>
0011 #include <linux/utsname.h>
0012 #include <scsi/fc/fc_ms.h>
0013 
0014 /*
0015  * F_CTL values for simple requests and responses.
0016  */
0017 #define FC_FCTL_REQ (FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT)
0018 #define FC_FCTL_RESP    (FC_FC_EX_CTX | FC_FC_LAST_SEQ | \
0019             FC_FC_END_SEQ | FC_FC_SEQ_INIT)
0020 
0021 struct fc_ns_rft {
0022     struct fc_ns_fid fid;   /* port ID object */
0023     struct fc_ns_fts fts;   /* FC4-types object */
0024 };
0025 
0026 struct fc_ct_req {
0027     struct fc_ct_hdr hdr;
0028     union {
0029         struct fc_ns_gid_ft gid;
0030         struct fc_ns_rn_id  rn;
0031         struct fc_ns_rft rft;
0032         struct fc_ns_rff_id rff;
0033         struct fc_ns_fid fid;
0034         struct fc_ns_rsnn snn;
0035         struct fc_ns_rspn spn;
0036         struct fc_fdmi_rhba rhba;
0037         struct fc_fdmi_rpa  rpa;
0038         struct fc_fdmi_dprt dprt;
0039         struct fc_fdmi_dhba dhba;
0040     } payload;
0041 };
0042 
0043 /**
0044  * fc_adisc_fill() - Fill in adisc request frame
0045  * @lport: local port.
0046  * @fp: fc frame where payload will be placed.
0047  */
0048 static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
0049 {
0050     struct fc_els_adisc *adisc;
0051 
0052     adisc = fc_frame_payload_get(fp, sizeof(*adisc));
0053     memset(adisc, 0, sizeof(*adisc));
0054     adisc->adisc_cmd = ELS_ADISC;
0055     put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
0056     put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
0057     hton24(adisc->adisc_port_id, lport->port_id);
0058 }
0059 
0060 /**
0061  * fc_ct_hdr_fill- fills ct header and reset ct payload
0062  * returns pointer to ct request.
0063  */
0064 static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
0065                            unsigned int op, size_t req_size,
0066                            enum fc_ct_fs_type fs_type,
0067                            u8 subtype)
0068 {
0069     struct fc_ct_req *ct;
0070     size_t ct_plen;
0071 
0072     ct_plen  = sizeof(struct fc_ct_hdr) + req_size;
0073     ct = fc_frame_payload_get(fp, ct_plen);
0074     memset(ct, 0, ct_plen);
0075     ct->hdr.ct_rev = FC_CT_REV;
0076     ct->hdr.ct_fs_type = fs_type;
0077     ct->hdr.ct_fs_subtype = subtype;
0078     ct->hdr.ct_cmd = htons((u16) op);
0079     return ct;
0080 }
0081 
0082 /**
0083  * fc_ct_ns_fill() - Fill in a name service request frame
0084  * @lport: local port.
0085  * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
0086  * @fp: frame to contain payload.
0087  * @op: CT opcode.
0088  * @r_ctl: pointer to FC header R_CTL.
0089  * @fh_type: pointer to FC-4 type.
0090  */
0091 static inline int fc_ct_ns_fill(struct fc_lport *lport,
0092               u32 fc_id, struct fc_frame *fp,
0093               unsigned int op, enum fc_rctl *r_ctl,
0094               enum fc_fh_type *fh_type)
0095 {
0096     struct fc_ct_req *ct;
0097     size_t len;
0098 
0099     switch (op) {
0100     case FC_NS_GPN_FT:
0101         ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft),
0102                     FC_FST_DIR, FC_NS_SUBTYPE);
0103         ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
0104         break;
0105 
0106     case FC_NS_GPN_ID:
0107         ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid),
0108                     FC_FST_DIR, FC_NS_SUBTYPE);
0109         ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
0110         hton24(ct->payload.fid.fp_fid, fc_id);
0111         break;
0112 
0113     case FC_NS_RFT_ID:
0114         ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft),
0115                     FC_FST_DIR, FC_NS_SUBTYPE);
0116         hton24(ct->payload.rft.fid.fp_fid, lport->port_id);
0117         ct->payload.rft.fts = lport->fcts;
0118         break;
0119 
0120     case FC_NS_RFF_ID:
0121         ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id),
0122                     FC_FST_DIR, FC_NS_SUBTYPE);
0123         hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id);
0124         ct->payload.rff.fr_type = FC_TYPE_FCP;
0125         if (lport->service_params & FCP_SPPF_INIT_FCN)
0126             ct->payload.rff.fr_feat = FCP_FEAT_INIT;
0127         if (lport->service_params & FCP_SPPF_TARG_FCN)
0128             ct->payload.rff.fr_feat |= FCP_FEAT_TARG;
0129         break;
0130 
0131     case FC_NS_RNN_ID:
0132         ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id),
0133                     FC_FST_DIR, FC_NS_SUBTYPE);
0134         hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id);
0135         put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
0136         break;
0137 
0138     case FC_NS_RSPN_ID:
0139         len = strnlen(fc_host_symbolic_name(lport->host), 255);
0140         ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len,
0141                     FC_FST_DIR, FC_NS_SUBTYPE);
0142         hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id);
0143         strncpy(ct->payload.spn.fr_name,
0144             fc_host_symbolic_name(lport->host), len);
0145         ct->payload.spn.fr_name_len = len;
0146         break;
0147 
0148     case FC_NS_RSNN_NN:
0149         len = strnlen(fc_host_symbolic_name(lport->host), 255);
0150         ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len,
0151                     FC_FST_DIR, FC_NS_SUBTYPE);
0152         put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
0153         strncpy(ct->payload.snn.fr_name,
0154             fc_host_symbolic_name(lport->host), len);
0155         ct->payload.snn.fr_name_len = len;
0156         break;
0157 
0158     default:
0159         return -EINVAL;
0160     }
0161     *r_ctl = FC_RCTL_DD_UNSOL_CTL;
0162     *fh_type = FC_TYPE_CT;
0163     return 0;
0164 }
0165 
0166 static inline void fc_ct_ms_fill_attr(struct fc_fdmi_attr_entry *entry,
0167                     const char *in, size_t len)
0168 {
0169     int copied;
0170 
0171     copied = strscpy(entry->value, in, len);
0172     if (copied > 0 && copied + 1 < len)
0173         memset(entry->value + copied + 1, 0, len - copied - 1);
0174 }
0175 
0176 /**
0177  * fc_ct_ms_fill() - Fill in a mgmt service request frame
0178  * @lport: local port.
0179  * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
0180  * @fp: frame to contain payload.
0181  * @op: CT opcode.
0182  * @r_ctl: pointer to FC header R_CTL.
0183  * @fh_type: pointer to FC-4 type.
0184  */
0185 static inline int fc_ct_ms_fill(struct fc_lport *lport,
0186               u32 fc_id, struct fc_frame *fp,
0187               unsigned int op, enum fc_rctl *r_ctl,
0188               enum fc_fh_type *fh_type)
0189 {
0190     struct fc_ct_req *ct;
0191     size_t len;
0192     struct fc_fdmi_attr_entry *entry;
0193     struct fs_fdmi_attrs *hba_attrs;
0194     int numattrs = 0;
0195     struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
0196 
0197     switch (op) {
0198     case FC_FDMI_RHBA:
0199         numattrs = 11;
0200         len = sizeof(struct fc_fdmi_rhba);
0201         len -= sizeof(struct fc_fdmi_attr_entry);
0202         len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
0203         len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
0204         len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
0205         len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
0206         len += FC_FDMI_HBA_ATTR_MODEL_LEN;
0207         len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
0208         len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
0209         len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
0210         len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
0211         len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
0212         len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
0213         len += FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN;
0214 
0215         if (fc_host->fdmi_version == FDMI_V2) {
0216             numattrs += 7;
0217             len += FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN;
0218             len += FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN;
0219             len += FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN;
0220             len += FC_FDMI_HBA_ATTR_FABRICNAME_LEN;
0221             len += FC_FDMI_HBA_ATTR_BIOSVERSION_LEN;
0222             len += FC_FDMI_HBA_ATTR_BIOSSTATE_LEN;
0223             len += FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN;
0224         }
0225 
0226         ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
0227                 FC_FDMI_SUBTYPE);
0228 
0229         /* HBA Identifier */
0230         put_unaligned_be64(lport->wwpn, &ct->payload.rhba.hbaid.id);
0231         /* Number of Ports - always 1 */
0232         put_unaligned_be32(1, &ct->payload.rhba.port.numport);
0233         /* Port Name */
0234         put_unaligned_be64(lport->wwpn,
0235                    &ct->payload.rhba.port.port[0].portname);
0236 
0237         /* HBA Attributes */
0238         put_unaligned_be32(numattrs,
0239                    &ct->payload.rhba.hba_attrs.numattrs);
0240         hba_attrs = &ct->payload.rhba.hba_attrs;
0241         entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
0242         /* NodeName*/
0243         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0244         len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
0245         put_unaligned_be16(FC_FDMI_HBA_ATTR_NODENAME,
0246                    &entry->type);
0247         put_unaligned_be16(len, &entry->len);
0248         put_unaligned_be64(lport->wwnn,
0249                    (__be64 *)&entry->value);
0250 
0251         /* Manufacturer */
0252         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0253                     FC_FDMI_HBA_ATTR_NODENAME_LEN);
0254         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0255         len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
0256         put_unaligned_be16(FC_FDMI_HBA_ATTR_MANUFACTURER,
0257                    &entry->type);
0258         put_unaligned_be16(len, &entry->len);
0259         fc_ct_ms_fill_attr(entry,
0260             fc_host_manufacturer(lport->host),
0261             FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
0262 
0263         /* SerialNumber */
0264         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0265                     FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
0266         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0267         len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
0268         put_unaligned_be16(FC_FDMI_HBA_ATTR_SERIALNUMBER,
0269                    &entry->type);
0270         put_unaligned_be16(len, &entry->len);
0271         fc_ct_ms_fill_attr(entry,
0272             fc_host_serial_number(lport->host),
0273             FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
0274 
0275         /* Model */
0276         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0277                     FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
0278         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0279         len += FC_FDMI_HBA_ATTR_MODEL_LEN;
0280         put_unaligned_be16(FC_FDMI_HBA_ATTR_MODEL,
0281                    &entry->type);
0282         put_unaligned_be16(len, &entry->len);
0283         fc_ct_ms_fill_attr(entry,
0284             fc_host_model(lport->host),
0285             FC_FDMI_HBA_ATTR_MODEL_LEN);
0286 
0287         /* Model Description */
0288         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0289                     FC_FDMI_HBA_ATTR_MODEL_LEN);
0290         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0291         len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
0292         put_unaligned_be16(FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
0293                    &entry->type);
0294         put_unaligned_be16(len, &entry->len);
0295         fc_ct_ms_fill_attr(entry,
0296             fc_host_model_description(lport->host),
0297             FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
0298 
0299         /* Hardware Version */
0300         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0301                     FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
0302         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0303         len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
0304         put_unaligned_be16(FC_FDMI_HBA_ATTR_HARDWAREVERSION,
0305                    &entry->type);
0306         put_unaligned_be16(len, &entry->len);
0307         fc_ct_ms_fill_attr(entry,
0308             fc_host_hardware_version(lport->host),
0309             FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
0310 
0311         /* Driver Version */
0312         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0313                     FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
0314         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0315         len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
0316         put_unaligned_be16(FC_FDMI_HBA_ATTR_DRIVERVERSION,
0317                    &entry->type);
0318         put_unaligned_be16(len, &entry->len);
0319         fc_ct_ms_fill_attr(entry,
0320             fc_host_driver_version(lport->host),
0321             FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
0322 
0323         /* OptionROM Version */
0324         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0325                     FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
0326         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0327         len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
0328         put_unaligned_be16(FC_FDMI_HBA_ATTR_OPTIONROMVERSION,
0329                    &entry->type);
0330         put_unaligned_be16(len, &entry->len);
0331         fc_ct_ms_fill_attr(entry,
0332             "unknown",
0333             FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
0334 
0335         /* Firmware Version */
0336         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0337                     FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
0338         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0339         len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
0340         put_unaligned_be16(FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
0341                    &entry->type);
0342         put_unaligned_be16(len, &entry->len);
0343         fc_ct_ms_fill_attr(entry,
0344             fc_host_firmware_version(lport->host),
0345             FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
0346 
0347         /* OS Name and Version */
0348         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0349                     FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
0350         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0351         len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
0352         put_unaligned_be16(FC_FDMI_HBA_ATTR_OSNAMEVERSION,
0353                    &entry->type);
0354         put_unaligned_be16(len, &entry->len);
0355         snprintf((char *)&entry->value,
0356             FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN,
0357             "%s v%s",
0358             init_utsname()->sysname,
0359             init_utsname()->release);
0360 
0361         /* Max CT payload */
0362         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0363                     FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN);
0364         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0365         len += FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN;
0366         put_unaligned_be16(FC_FDMI_HBA_ATTR_MAXCTPAYLOAD,
0367                 &entry->type);
0368         put_unaligned_be16(len, &entry->len);
0369         put_unaligned_be32(fc_host_max_ct_payload(lport->host),
0370                 &entry->value);
0371 
0372         if (fc_host->fdmi_version == FDMI_V2) {
0373             /* Node symbolic name */
0374             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0375                     FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN);
0376             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0377             len += FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN;
0378             put_unaligned_be16(FC_FDMI_HBA_ATTR_NODESYMBLNAME,
0379                     &entry->type);
0380             put_unaligned_be16(len, &entry->len);
0381             fc_ct_ms_fill_attr(entry,
0382                     fc_host_symbolic_name(lport->host),
0383                     FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN);
0384 
0385             /* Vendor specific info */
0386             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0387                     FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN);
0388             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0389             len += FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN;
0390             put_unaligned_be16(FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO,
0391                     &entry->type);
0392             put_unaligned_be16(len, &entry->len);
0393             put_unaligned_be32(0,
0394                     &entry->value);
0395 
0396             /* Number of ports */
0397             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0398                     FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN);
0399             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0400             len += FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN;
0401             put_unaligned_be16(FC_FDMI_HBA_ATTR_NUMBEROFPORTS,
0402                     &entry->type);
0403             put_unaligned_be16(len, &entry->len);
0404             put_unaligned_be32(fc_host_num_ports(lport->host),
0405                     &entry->value);
0406 
0407             /* Fabric name */
0408             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0409                     FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN);
0410             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0411             len += FC_FDMI_HBA_ATTR_FABRICNAME_LEN;
0412             put_unaligned_be16(FC_FDMI_HBA_ATTR_FABRICNAME,
0413                     &entry->type);
0414             put_unaligned_be16(len, &entry->len);
0415             put_unaligned_be64(fc_host_fabric_name(lport->host),
0416                     &entry->value);
0417 
0418             /* BIOS version */
0419             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0420                     FC_FDMI_HBA_ATTR_FABRICNAME_LEN);
0421             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0422             len += FC_FDMI_HBA_ATTR_BIOSVERSION_LEN;
0423             put_unaligned_be16(FC_FDMI_HBA_ATTR_BIOSVERSION,
0424                     &entry->type);
0425             put_unaligned_be16(len, &entry->len);
0426             fc_ct_ms_fill_attr(entry,
0427                     fc_host_bootbios_version(lport->host),
0428                     FC_FDMI_HBA_ATTR_BIOSVERSION_LEN);
0429 
0430             /* BIOS state */
0431             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0432                     FC_FDMI_HBA_ATTR_BIOSVERSION_LEN);
0433             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0434             len += FC_FDMI_HBA_ATTR_BIOSSTATE_LEN;
0435             put_unaligned_be16(FC_FDMI_HBA_ATTR_BIOSSTATE,
0436                     &entry->type);
0437             put_unaligned_be16(len, &entry->len);
0438             put_unaligned_be32(fc_host_bootbios_state(lport->host),
0439                     &entry->value);
0440 
0441             /* Vendor identifier  */
0442             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0443                     FC_FDMI_HBA_ATTR_BIOSSTATE_LEN);
0444             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0445             len += FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN;
0446             put_unaligned_be16(FC_FDMI_HBA_ATTR_VENDORIDENTIFIER,
0447                     &entry->type);
0448             put_unaligned_be16(len, &entry->len);
0449             fc_ct_ms_fill_attr(entry,
0450                     fc_host_vendor_identifier(lport->host),
0451                     FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN);
0452         }
0453 
0454         break;
0455     case FC_FDMI_RPA:
0456         numattrs = 6;
0457         len = sizeof(struct fc_fdmi_rpa);
0458         len -= sizeof(struct fc_fdmi_attr_entry);
0459         len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
0460         len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
0461         len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
0462         len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
0463         len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
0464         len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
0465         len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
0466 
0467 
0468         if (fc_host->fdmi_version == FDMI_V2) {
0469             numattrs += 10;
0470 
0471             len += FC_FDMI_PORT_ATTR_NODENAME_LEN;
0472             len += FC_FDMI_PORT_ATTR_PORTNAME_LEN;
0473             len += FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN;
0474             len += FC_FDMI_PORT_ATTR_PORTTYPE_LEN;
0475             len += FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN;
0476             len += FC_FDMI_PORT_ATTR_FABRICNAME_LEN;
0477             len += FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN;
0478             len += FC_FDMI_PORT_ATTR_PORTSTATE_LEN;
0479             len += FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN;
0480             len += FC_FDMI_PORT_ATTR_PORTID_LEN;
0481 
0482         }
0483 
0484         ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
0485                     FC_FDMI_SUBTYPE);
0486 
0487         /* Port Name */
0488         put_unaligned_be64(lport->wwpn,
0489                    &ct->payload.rpa.port.portname);
0490 
0491         /* Port Attributes */
0492         put_unaligned_be32(numattrs,
0493                    &ct->payload.rpa.hba_attrs.numattrs);
0494 
0495         hba_attrs = &ct->payload.rpa.hba_attrs;
0496         entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
0497 
0498         /* FC4 types */
0499         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0500         len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
0501         put_unaligned_be16(FC_FDMI_PORT_ATTR_FC4TYPES,
0502                    &entry->type);
0503         put_unaligned_be16(len, &entry->len);
0504         memcpy(&entry->value, fc_host_supported_fc4s(lport->host),
0505                FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
0506 
0507         /* Supported Speed */
0508         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0509                     FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
0510         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0511         len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
0512         put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
0513                    &entry->type);
0514         put_unaligned_be16(len, &entry->len);
0515 
0516         put_unaligned_be32(fc_host_supported_speeds(lport->host),
0517                    &entry->value);
0518 
0519         /* Current Port Speed */
0520         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0521                     FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
0522         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0523         len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
0524         put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
0525                    &entry->type);
0526         put_unaligned_be16(len, &entry->len);
0527         put_unaligned_be32(lport->link_speed,
0528                    &entry->value);
0529 
0530         /* Max Frame Size */
0531         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0532                     FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
0533         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0534         len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
0535         put_unaligned_be16(FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
0536                    &entry->type);
0537         put_unaligned_be16(len, &entry->len);
0538         put_unaligned_be32(fc_host_maxframe_size(lport->host),
0539                    &entry->value);
0540 
0541         /* OS Device Name */
0542         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0543                     FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN);
0544         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0545         len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
0546         put_unaligned_be16(FC_FDMI_PORT_ATTR_OSDEVICENAME,
0547                    &entry->type);
0548         put_unaligned_be16(len, &entry->len);
0549         /* Use the sysfs device name */
0550         fc_ct_ms_fill_attr(entry,
0551             dev_name(&lport->host->shost_gendev),
0552             strnlen(dev_name(&lport->host->shost_gendev),
0553                 FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
0554 
0555         /* Host Name */
0556         entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0557                     FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN);
0558         len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0559         len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
0560         put_unaligned_be16(FC_FDMI_PORT_ATTR_HOSTNAME,
0561                    &entry->type);
0562         put_unaligned_be16(len, &entry->len);
0563         if (strlen(fc_host_system_hostname(lport->host)))
0564             fc_ct_ms_fill_attr(entry,
0565                 fc_host_system_hostname(lport->host),
0566                 strnlen(fc_host_system_hostname(lport->host),
0567                     FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
0568         else
0569             fc_ct_ms_fill_attr(entry,
0570                 init_utsname()->nodename,
0571                 FC_FDMI_PORT_ATTR_HOSTNAME_LEN);
0572 
0573 
0574         if (fc_host->fdmi_version == FDMI_V2) {
0575 
0576             /* Node name */
0577             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0578                     FC_FDMI_PORT_ATTR_HOSTNAME_LEN);
0579             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0580             len += FC_FDMI_PORT_ATTR_NODENAME_LEN;
0581             put_unaligned_be16(FC_FDMI_PORT_ATTR_NODENAME,
0582                     &entry->type);
0583             put_unaligned_be16(len, &entry->len);
0584             put_unaligned_be64(fc_host_node_name(lport->host),
0585                     &entry->value);
0586 
0587             /* Port name  */
0588             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0589                     FC_FDMI_PORT_ATTR_NODENAME_LEN);
0590             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0591             len += FC_FDMI_PORT_ATTR_PORTNAME_LEN;
0592             put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTNAME,
0593                     &entry->type);
0594             put_unaligned_be16(len, &entry->len);
0595             put_unaligned_be64(lport->wwpn,
0596                     &entry->value);
0597 
0598             /* Port symbolic name */
0599             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0600                     FC_FDMI_PORT_ATTR_PORTNAME_LEN);
0601             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0602             len += FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN;
0603             put_unaligned_be16(FC_FDMI_PORT_ATTR_SYMBOLICNAME,
0604                     &entry->type);
0605             put_unaligned_be16(len, &entry->len);
0606             fc_ct_ms_fill_attr(entry,
0607                     fc_host_symbolic_name(lport->host),
0608                     FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN);
0609 
0610             /* Port type */
0611             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0612                     FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN);
0613             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0614             len += FC_FDMI_PORT_ATTR_PORTTYPE_LEN;
0615             put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTTYPE,
0616                     &entry->type);
0617             put_unaligned_be16(len, &entry->len);
0618             put_unaligned_be32(fc_host_port_type(lport->host),
0619                     &entry->value);
0620 
0621             /* Supported class of service */
0622             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0623                     FC_FDMI_PORT_ATTR_PORTTYPE_LEN);
0624             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0625             len += FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN;
0626             put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC,
0627                     &entry->type);
0628             put_unaligned_be16(len, &entry->len);
0629             put_unaligned_be32(fc_host_supported_classes(lport->host),
0630                     &entry->value);
0631 
0632             /* Port Fabric name */
0633             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0634                     FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN);
0635             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0636             len += FC_FDMI_PORT_ATTR_FABRICNAME_LEN;
0637             put_unaligned_be16(FC_FDMI_PORT_ATTR_FABRICNAME,
0638                     &entry->type);
0639             put_unaligned_be16(len, &entry->len);
0640             put_unaligned_be64(fc_host_fabric_name(lport->host),
0641                     &entry->value);
0642 
0643             /* Port active FC-4 */
0644             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0645                     FC_FDMI_PORT_ATTR_FABRICNAME_LEN);
0646             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0647             len += FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN;
0648             put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTFC4TYPE,
0649                     &entry->type);
0650             put_unaligned_be16(len, &entry->len);
0651             memcpy(&entry->value, fc_host_active_fc4s(lport->host),
0652                     FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN);
0653 
0654             /* Port state */
0655             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0656                     FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN);
0657             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0658             len += FC_FDMI_PORT_ATTR_PORTSTATE_LEN;
0659             put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTSTATE,
0660                     &entry->type);
0661             put_unaligned_be16(len, &entry->len);
0662             put_unaligned_be32(fc_host_port_state(lport->host),
0663                     &entry->value);
0664 
0665             /* Discovered ports */
0666             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0667                     FC_FDMI_PORT_ATTR_PORTSTATE_LEN);
0668             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0669             len += FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN;
0670             put_unaligned_be16(FC_FDMI_PORT_ATTR_DISCOVEREDPORTS,
0671                     &entry->type);
0672             put_unaligned_be16(len, &entry->len);
0673             put_unaligned_be32(fc_host_num_discovered_ports(lport->host),
0674                     &entry->value);
0675 
0676             /* Port ID */
0677             entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
0678                     FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN);
0679             len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
0680             len += FC_FDMI_PORT_ATTR_PORTID_LEN;
0681             put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTID,
0682                     &entry->type);
0683             put_unaligned_be16(len, &entry->len);
0684             put_unaligned_be32(fc_host_port_id(lport->host),
0685                     &entry->value);
0686         }
0687 
0688         break;
0689     case FC_FDMI_DPRT:
0690         len = sizeof(struct fc_fdmi_dprt);
0691         ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
0692                     FC_FDMI_SUBTYPE);
0693         /* Port Name */
0694         put_unaligned_be64(lport->wwpn,
0695                    &ct->payload.dprt.port.portname);
0696         break;
0697     case FC_FDMI_DHBA:
0698         len = sizeof(struct fc_fdmi_dhba);
0699         ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
0700                     FC_FDMI_SUBTYPE);
0701         /* HBA Identifier */
0702         put_unaligned_be64(lport->wwpn, &ct->payload.dhba.hbaid.id);
0703         break;
0704     default:
0705         return -EINVAL;
0706     }
0707     *r_ctl = FC_RCTL_DD_UNSOL_CTL;
0708     *fh_type = FC_TYPE_CT;
0709     return 0;
0710 }
0711 
0712 /**
0713  * fc_ct_fill() - Fill in a common transport service request frame
0714  * @lport: local port.
0715  * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
0716  * @fp: frame to contain payload.
0717  * @op: CT opcode.
0718  * @r_ctl: pointer to FC header R_CTL.
0719  * @fh_type: pointer to FC-4 type.
0720  */
0721 static inline int fc_ct_fill(struct fc_lport *lport,
0722               u32 fc_id, struct fc_frame *fp,
0723               unsigned int op, enum fc_rctl *r_ctl,
0724               enum fc_fh_type *fh_type, u32 *did)
0725 {
0726     int rc = -EINVAL;
0727 
0728     switch (fc_id) {
0729     case FC_FID_MGMT_SERV:
0730         rc = fc_ct_ms_fill(lport, fc_id, fp, op, r_ctl, fh_type);
0731         *did = FC_FID_MGMT_SERV;
0732         break;
0733     case FC_FID_DIR_SERV:
0734     default:
0735         rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type);
0736         *did = FC_FID_DIR_SERV;
0737         break;
0738     }
0739 
0740     return rc;
0741 }
0742 /**
0743  * fc_plogi_fill - Fill in plogi request frame
0744  */
0745 static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
0746                  unsigned int op)
0747 {
0748     struct fc_els_flogi *plogi;
0749     struct fc_els_csp *csp;
0750     struct fc_els_cssp *cp;
0751 
0752     plogi = fc_frame_payload_get(fp, sizeof(*plogi));
0753     memset(plogi, 0, sizeof(*plogi));
0754     plogi->fl_cmd = (u8) op;
0755     put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn);
0756     put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn);
0757 
0758     csp = &plogi->fl_csp;
0759     csp->sp_hi_ver = 0x20;
0760     csp->sp_lo_ver = 0x20;
0761     csp->sp_bb_cred = htons(10);    /* this gets set by gateway */
0762     csp->sp_bb_data = htons((u16) lport->mfs);
0763     cp = &plogi->fl_cssp[3 - 1];    /* class 3 parameters */
0764     cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
0765     csp->sp_features = htons(FC_SP_FT_CIRO);
0766     csp->sp_tot_seq = htons(255);   /* seq. we accept */
0767     csp->sp_rel_off = htons(0x1f);
0768     csp->sp_e_d_tov = htonl(lport->e_d_tov);
0769 
0770     cp->cp_rdfs = htons((u16) lport->mfs);
0771     cp->cp_con_seq = htons(255);
0772     cp->cp_open_seq = 1;
0773 }
0774 
0775 /**
0776  * fc_flogi_fill - Fill in a flogi request frame.
0777  */
0778 static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
0779 {
0780     struct fc_els_csp *sp;
0781     struct fc_els_cssp *cp;
0782     struct fc_els_flogi *flogi;
0783 
0784     flogi = fc_frame_payload_get(fp, sizeof(*flogi));
0785     memset(flogi, 0, sizeof(*flogi));
0786     flogi->fl_cmd = (u8) ELS_FLOGI;
0787     put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
0788     put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
0789     sp = &flogi->fl_csp;
0790     sp->sp_hi_ver = 0x20;
0791     sp->sp_lo_ver = 0x20;
0792     sp->sp_bb_cred = htons(10); /* this gets set by gateway */
0793     sp->sp_bb_data = htons((u16) lport->mfs);
0794     cp = &flogi->fl_cssp[3 - 1];    /* class 3 parameters */
0795     cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
0796     if (lport->does_npiv)
0797         sp->sp_features = htons(FC_SP_FT_NPIV);
0798 }
0799 
0800 /**
0801  * fc_fdisc_fill - Fill in a fdisc request frame.
0802  */
0803 static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
0804 {
0805     struct fc_els_csp *sp;
0806     struct fc_els_cssp *cp;
0807     struct fc_els_flogi *fdisc;
0808 
0809     fdisc = fc_frame_payload_get(fp, sizeof(*fdisc));
0810     memset(fdisc, 0, sizeof(*fdisc));
0811     fdisc->fl_cmd = (u8) ELS_FDISC;
0812     put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn);
0813     put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn);
0814     sp = &fdisc->fl_csp;
0815     sp->sp_hi_ver = 0x20;
0816     sp->sp_lo_ver = 0x20;
0817     sp->sp_bb_cred = htons(10); /* this gets set by gateway */
0818     sp->sp_bb_data = htons((u16) lport->mfs);
0819     cp = &fdisc->fl_cssp[3 - 1];    /* class 3 parameters */
0820     cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
0821 }
0822 
0823 /**
0824  * fc_logo_fill - Fill in a logo request frame.
0825  */
0826 static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
0827 {
0828     struct fc_els_logo *logo;
0829 
0830     logo = fc_frame_payload_get(fp, sizeof(*logo));
0831     memset(logo, 0, sizeof(*logo));
0832     logo->fl_cmd = ELS_LOGO;
0833     hton24(logo->fl_n_port_id, lport->port_id);
0834     logo->fl_n_port_wwn = htonll(lport->wwpn);
0835 }
0836 
0837 /**
0838  * fc_rtv_fill - Fill in RTV (read timeout value) request frame.
0839  */
0840 static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp)
0841 {
0842     struct fc_els_rtv *rtv;
0843 
0844     rtv = fc_frame_payload_get(fp, sizeof(*rtv));
0845     memset(rtv, 0, sizeof(*rtv));
0846     rtv->rtv_cmd = ELS_RTV;
0847 }
0848 
0849 /**
0850  * fc_rec_fill - Fill in rec request frame
0851  */
0852 static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp)
0853 {
0854     struct fc_els_rec *rec;
0855     struct fc_exch *ep = fc_seq_exch(fr_seq(fp));
0856 
0857     rec = fc_frame_payload_get(fp, sizeof(*rec));
0858     memset(rec, 0, sizeof(*rec));
0859     rec->rec_cmd = ELS_REC;
0860     hton24(rec->rec_s_id, lport->port_id);
0861     rec->rec_ox_id = htons(ep->oxid);
0862     rec->rec_rx_id = htons(ep->rxid);
0863 }
0864 
0865 /**
0866  * fc_prli_fill - Fill in prli request frame
0867  */
0868 static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp)
0869 {
0870     struct {
0871         struct fc_els_prli prli;
0872         struct fc_els_spp spp;
0873     } *pp;
0874 
0875     pp = fc_frame_payload_get(fp, sizeof(*pp));
0876     memset(pp, 0, sizeof(*pp));
0877     pp->prli.prli_cmd = ELS_PRLI;
0878     pp->prli.prli_spp_len = sizeof(struct fc_els_spp);
0879     pp->prli.prli_len = htons(sizeof(*pp));
0880     pp->spp.spp_type = FC_TYPE_FCP;
0881     pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR;
0882     pp->spp.spp_params = htonl(lport->service_params);
0883 }
0884 
0885 /**
0886  * fc_scr_fill - Fill in a scr request frame.
0887  */
0888 static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
0889 {
0890     struct fc_els_scr *scr;
0891 
0892     scr = fc_frame_payload_get(fp, sizeof(*scr));
0893     memset(scr, 0, sizeof(*scr));
0894     scr->scr_cmd = ELS_SCR;
0895     scr->scr_reg_func = ELS_SCRF_FULL;
0896 }
0897 
0898 /**
0899  * fc_els_fill - Fill in an ELS  request frame
0900  */
0901 static inline int fc_els_fill(struct fc_lport *lport,
0902                u32 did,
0903                struct fc_frame *fp, unsigned int op,
0904                enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
0905 {
0906     switch (op) {
0907     case ELS_ADISC:
0908         fc_adisc_fill(lport, fp);
0909         break;
0910 
0911     case ELS_PLOGI:
0912         fc_plogi_fill(lport, fp, ELS_PLOGI);
0913         break;
0914 
0915     case ELS_FLOGI:
0916         fc_flogi_fill(lport, fp);
0917         break;
0918 
0919     case ELS_FDISC:
0920         fc_fdisc_fill(lport, fp);
0921         break;
0922 
0923     case ELS_LOGO:
0924         fc_logo_fill(lport, fp);
0925         break;
0926 
0927     case ELS_RTV:
0928         fc_rtv_fill(lport, fp);
0929         break;
0930 
0931     case ELS_REC:
0932         fc_rec_fill(lport, fp);
0933         break;
0934 
0935     case ELS_PRLI:
0936         fc_prli_fill(lport, fp);
0937         break;
0938 
0939     case ELS_SCR:
0940         fc_scr_fill(lport, fp);
0941         break;
0942 
0943     default:
0944         return -EINVAL;
0945     }
0946 
0947     *r_ctl = FC_RCTL_ELS_REQ;
0948     *fh_type = FC_TYPE_ELS;
0949     return 0;
0950 }
0951 #endif /* _FC_ENCODE_H_ */