linux/drivers/scsi/libfc/fc_encode.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Copyright(c) 2008 Intel Corporation. All rights reserved.
   4 *
   5 * Maintained at www.Open-FCoE.org
   6 */
   7
   8#ifndef _FC_ENCODE_H_
   9#define _FC_ENCODE_H_
  10#include <asm/unaligned.h>
  11#include <linux/utsname.h>
  12#include <scsi/fc/fc_ms.h>
  13
  14/*
  15 * F_CTL values for simple requests and responses.
  16 */
  17#define FC_FCTL_REQ     (FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT)
  18#define FC_FCTL_RESP    (FC_FC_EX_CTX | FC_FC_LAST_SEQ | \
  19                        FC_FC_END_SEQ | FC_FC_SEQ_INIT)
  20
  21struct fc_ns_rft {
  22        struct fc_ns_fid fid;   /* port ID object */
  23        struct fc_ns_fts fts;   /* FC4-types object */
  24};
  25
  26struct fc_ct_req {
  27        struct fc_ct_hdr hdr;
  28        union {
  29                struct fc_ns_gid_ft gid;
  30                struct fc_ns_rn_id  rn;
  31                struct fc_ns_rft rft;
  32                struct fc_ns_rff_id rff;
  33                struct fc_ns_fid fid;
  34                struct fc_ns_rsnn snn;
  35                struct fc_ns_rspn spn;
  36                struct fc_fdmi_rhba rhba;
  37                struct fc_fdmi_rpa  rpa;
  38                struct fc_fdmi_dprt dprt;
  39                struct fc_fdmi_dhba dhba;
  40        } payload;
  41};
  42
  43/**
  44 * fc_adisc_fill() - Fill in adisc request frame
  45 * @lport: local port.
  46 * @fp: fc frame where payload will be placed.
  47 */
  48static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
  49{
  50        struct fc_els_adisc *adisc;
  51
  52        adisc = fc_frame_payload_get(fp, sizeof(*adisc));
  53        memset(adisc, 0, sizeof(*adisc));
  54        adisc->adisc_cmd = ELS_ADISC;
  55        put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
  56        put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
  57        hton24(adisc->adisc_port_id, lport->port_id);
  58}
  59
  60/**
  61 * fc_ct_hdr_fill- fills ct header and reset ct payload
  62 * returns pointer to ct request.
  63 */
  64static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
  65                                               unsigned int op, size_t req_size,
  66                                               enum fc_ct_fs_type fs_type,
  67                                               u8 subtype)
  68{
  69        struct fc_ct_req *ct;
  70        size_t ct_plen;
  71
  72        ct_plen  = sizeof(struct fc_ct_hdr) + req_size;
  73        ct = fc_frame_payload_get(fp, ct_plen);
  74        memset(ct, 0, ct_plen);
  75        ct->hdr.ct_rev = FC_CT_REV;
  76        ct->hdr.ct_fs_type = fs_type;
  77        ct->hdr.ct_fs_subtype = subtype;
  78        ct->hdr.ct_cmd = htons((u16) op);
  79        return ct;
  80}
  81
  82/**
  83 * fc_ct_ns_fill() - Fill in a name service request frame
  84 * @lport: local port.
  85 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
  86 * @fp: frame to contain payload.
  87 * @op: CT opcode.
  88 * @r_ctl: pointer to FC header R_CTL.
  89 * @fh_type: pointer to FC-4 type.
  90 */
  91static inline int fc_ct_ns_fill(struct fc_lport *lport,
  92                      u32 fc_id, struct fc_frame *fp,
  93                      unsigned int op, enum fc_rctl *r_ctl,
  94                      enum fc_fh_type *fh_type)
  95{
  96        struct fc_ct_req *ct;
  97        size_t len;
  98
  99        switch (op) {
 100        case FC_NS_GPN_FT:
 101                ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft),
 102                                    FC_FST_DIR, FC_NS_SUBTYPE);
 103                ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
 104                break;
 105
 106        case FC_NS_GPN_ID:
 107                ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid),
 108                                    FC_FST_DIR, FC_NS_SUBTYPE);
 109                ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
 110                hton24(ct->payload.fid.fp_fid, fc_id);
 111                break;
 112
 113        case FC_NS_RFT_ID:
 114                ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft),
 115                                    FC_FST_DIR, FC_NS_SUBTYPE);
 116                hton24(ct->payload.rft.fid.fp_fid, lport->port_id);
 117                ct->payload.rft.fts = lport->fcts;
 118                break;
 119
 120        case FC_NS_RFF_ID:
 121                ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id),
 122                                    FC_FST_DIR, FC_NS_SUBTYPE);
 123                hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id);
 124                ct->payload.rff.fr_type = FC_TYPE_FCP;
 125                if (lport->service_params & FCP_SPPF_INIT_FCN)
 126                        ct->payload.rff.fr_feat = FCP_FEAT_INIT;
 127                if (lport->service_params & FCP_SPPF_TARG_FCN)
 128                        ct->payload.rff.fr_feat |= FCP_FEAT_TARG;
 129                break;
 130
 131        case FC_NS_RNN_ID:
 132                ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id),
 133                                    FC_FST_DIR, FC_NS_SUBTYPE);
 134                hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id);
 135                put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
 136                break;
 137
 138        case FC_NS_RSPN_ID:
 139                len = strnlen(fc_host_symbolic_name(lport->host), 255);
 140                ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len,
 141                                    FC_FST_DIR, FC_NS_SUBTYPE);
 142                hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id);
 143                strncpy(ct->payload.spn.fr_name,
 144                        fc_host_symbolic_name(lport->host), len);
 145                ct->payload.spn.fr_name_len = len;
 146                break;
 147
 148        case FC_NS_RSNN_NN:
 149                len = strnlen(fc_host_symbolic_name(lport->host), 255);
 150                ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len,
 151                                    FC_FST_DIR, FC_NS_SUBTYPE);
 152                put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
 153                strncpy(ct->payload.snn.fr_name,
 154                        fc_host_symbolic_name(lport->host), len);
 155                ct->payload.snn.fr_name_len = len;
 156                break;
 157
 158        default:
 159                return -EINVAL;
 160        }
 161        *r_ctl = FC_RCTL_DD_UNSOL_CTL;
 162        *fh_type = FC_TYPE_CT;
 163        return 0;
 164}
 165
 166static inline void fc_ct_ms_fill_attr(struct fc_fdmi_attr_entry *entry,
 167                                    const char *in, size_t len)
 168{
 169        int copied;
 170
 171        copied = strscpy(entry->value, in, len);
 172        if (copied > 0 && copied + 1 < len)
 173                memset(entry->value + copied + 1, 0, len - copied - 1);
 174}
 175
 176/**
 177 * fc_ct_ms_fill() - Fill in a mgmt service request frame
 178 * @lport: local port.
 179 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
 180 * @fp: frame to contain payload.
 181 * @op: CT opcode.
 182 * @r_ctl: pointer to FC header R_CTL.
 183 * @fh_type: pointer to FC-4 type.
 184 */
 185static inline int fc_ct_ms_fill(struct fc_lport *lport,
 186                      u32 fc_id, struct fc_frame *fp,
 187                      unsigned int op, enum fc_rctl *r_ctl,
 188                      enum fc_fh_type *fh_type)
 189{
 190        struct fc_ct_req *ct;
 191        size_t len;
 192        struct fc_fdmi_attr_entry *entry;
 193        struct fs_fdmi_attrs *hba_attrs;
 194        int numattrs = 0;
 195        struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
 196
 197        switch (op) {
 198        case FC_FDMI_RHBA:
 199                numattrs = 11;
 200                len = sizeof(struct fc_fdmi_rhba);
 201                len -= sizeof(struct fc_fdmi_attr_entry);
 202                len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
 203                len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
 204                len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
 205                len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
 206                len += FC_FDMI_HBA_ATTR_MODEL_LEN;
 207                len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
 208                len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
 209                len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
 210                len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
 211                len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
 212                len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
 213                len += FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN;
 214
 215                if (fc_host->fdmi_version == FDMI_V2) {
 216                        numattrs += 7;
 217                        len += FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN;
 218                        len += FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN;
 219                        len += FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN;
 220                        len += FC_FDMI_HBA_ATTR_FABRICNAME_LEN;
 221                        len += FC_FDMI_HBA_ATTR_BIOSVERSION_LEN;
 222                        len += FC_FDMI_HBA_ATTR_BIOSSTATE_LEN;
 223                        len += FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN;
 224                }
 225
 226                ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
 227                                FC_FDMI_SUBTYPE);
 228
 229                /* HBA Identifier */
 230                put_unaligned_be64(lport->wwpn, &ct->payload.rhba.hbaid.id);
 231                /* Number of Ports - always 1 */
 232                put_unaligned_be32(1, &ct->payload.rhba.port.numport);
 233                /* Port Name */
 234                put_unaligned_be64(lport->wwpn,
 235                                   &ct->payload.rhba.port.port[0].portname);
 236
 237                /* HBA Attributes */
 238                put_unaligned_be32(numattrs,
 239                                   &ct->payload.rhba.hba_attrs.numattrs);
 240                hba_attrs = &ct->payload.rhba.hba_attrs;
 241                entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
 242                /* NodeName*/
 243                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 244                len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
 245                put_unaligned_be16(FC_FDMI_HBA_ATTR_NODENAME,
 246                                   &entry->type);
 247                put_unaligned_be16(len, &entry->len);
 248                put_unaligned_be64(lport->wwnn,
 249                                   (__be64 *)&entry->value[0]);
 250
 251                /* Manufacturer */
 252                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 253                                        FC_FDMI_HBA_ATTR_NODENAME_LEN);
 254                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 255                len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
 256                put_unaligned_be16(FC_FDMI_HBA_ATTR_MANUFACTURER,
 257                                   &entry->type);
 258                put_unaligned_be16(len, &entry->len);
 259                fc_ct_ms_fill_attr(entry,
 260                        fc_host_manufacturer(lport->host),
 261                        FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
 262
 263                /* SerialNumber */
 264                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 265                                        FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
 266                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 267                len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
 268                put_unaligned_be16(FC_FDMI_HBA_ATTR_SERIALNUMBER,
 269                                   &entry->type);
 270                put_unaligned_be16(len, &entry->len);
 271                fc_ct_ms_fill_attr(entry,
 272                        fc_host_serial_number(lport->host),
 273                        FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
 274
 275                /* Model */
 276                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 277                                        FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
 278                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 279                len += FC_FDMI_HBA_ATTR_MODEL_LEN;
 280                put_unaligned_be16(FC_FDMI_HBA_ATTR_MODEL,
 281                                   &entry->type);
 282                put_unaligned_be16(len, &entry->len);
 283                fc_ct_ms_fill_attr(entry,
 284                        fc_host_model(lport->host),
 285                        FC_FDMI_HBA_ATTR_MODEL_LEN);
 286
 287                /* Model Description */
 288                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 289                                        FC_FDMI_HBA_ATTR_MODEL_LEN);
 290                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 291                len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
 292                put_unaligned_be16(FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
 293                                   &entry->type);
 294                put_unaligned_be16(len, &entry->len);
 295                fc_ct_ms_fill_attr(entry,
 296                        fc_host_model_description(lport->host),
 297                        FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
 298
 299                /* Hardware Version */
 300                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 301                                        FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
 302                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 303                len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
 304                put_unaligned_be16(FC_FDMI_HBA_ATTR_HARDWAREVERSION,
 305                                   &entry->type);
 306                put_unaligned_be16(len, &entry->len);
 307                fc_ct_ms_fill_attr(entry,
 308                        fc_host_hardware_version(lport->host),
 309                        FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
 310
 311                /* Driver Version */
 312                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 313                                        FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
 314                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 315                len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
 316                put_unaligned_be16(FC_FDMI_HBA_ATTR_DRIVERVERSION,
 317                                   &entry->type);
 318                put_unaligned_be16(len, &entry->len);
 319                fc_ct_ms_fill_attr(entry,
 320                        fc_host_driver_version(lport->host),
 321                        FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
 322
 323                /* OptionROM Version */
 324                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 325                                        FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
 326                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 327                len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
 328                put_unaligned_be16(FC_FDMI_HBA_ATTR_OPTIONROMVERSION,
 329                                   &entry->type);
 330                put_unaligned_be16(len, &entry->len);
 331                fc_ct_ms_fill_attr(entry,
 332                        "unknown",
 333                        FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
 334
 335                /* Firmware Version */
 336                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 337                                        FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
 338                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 339                len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
 340                put_unaligned_be16(FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
 341                                   &entry->type);
 342                put_unaligned_be16(len, &entry->len);
 343                fc_ct_ms_fill_attr(entry,
 344                        fc_host_firmware_version(lport->host),
 345                        FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
 346
 347                /* OS Name and Version */
 348                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 349                                        FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
 350                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 351                len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
 352                put_unaligned_be16(FC_FDMI_HBA_ATTR_OSNAMEVERSION,
 353                                   &entry->type);
 354                put_unaligned_be16(len, &entry->len);
 355                snprintf((char *)&entry->value,
 356                        FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN,
 357                        "%s v%s",
 358                        init_utsname()->sysname,
 359                        init_utsname()->release);
 360
 361                /* Max CT payload */
 362                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 363                                        FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN);
 364                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 365                len += FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN;
 366                put_unaligned_be16(FC_FDMI_HBA_ATTR_MAXCTPAYLOAD,
 367                                &entry->type);
 368                put_unaligned_be16(len, &entry->len);
 369                put_unaligned_be32(fc_host_max_ct_payload(lport->host),
 370                                &entry->value);
 371
 372                if (fc_host->fdmi_version == FDMI_V2) {
 373                        /* Node symbolic name */
 374                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 375                                        FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN);
 376                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 377                        len += FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN;
 378                        put_unaligned_be16(FC_FDMI_HBA_ATTR_NODESYMBLNAME,
 379                                        &entry->type);
 380                        put_unaligned_be16(len, &entry->len);
 381                        fc_ct_ms_fill_attr(entry,
 382                                        fc_host_symbolic_name(lport->host),
 383                                        FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN);
 384
 385                        /* Vendor specific info */
 386                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 387                                        FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN);
 388                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 389                        len += FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN;
 390                        put_unaligned_be16(FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO,
 391                                        &entry->type);
 392                        put_unaligned_be16(len, &entry->len);
 393                        put_unaligned_be32(0,
 394                                        &entry->value);
 395
 396                        /* Number of ports */
 397                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 398                                        FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN);
 399                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 400                        len += FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN;
 401                        put_unaligned_be16(FC_FDMI_HBA_ATTR_NUMBEROFPORTS,
 402                                        &entry->type);
 403                        put_unaligned_be16(len, &entry->len);
 404                        put_unaligned_be32(fc_host_num_ports(lport->host),
 405                                        &entry->value);
 406
 407                        /* Fabric name */
 408                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 409                                        FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN);
 410                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 411                        len += FC_FDMI_HBA_ATTR_FABRICNAME_LEN;
 412                        put_unaligned_be16(FC_FDMI_HBA_ATTR_FABRICNAME,
 413                                        &entry->type);
 414                        put_unaligned_be16(len, &entry->len);
 415                        put_unaligned_be64(fc_host_fabric_name(lport->host),
 416                                        &entry->value);
 417
 418                        /* BIOS version */
 419                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 420                                        FC_FDMI_HBA_ATTR_FABRICNAME_LEN);
 421                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 422                        len += FC_FDMI_HBA_ATTR_BIOSVERSION_LEN;
 423                        put_unaligned_be16(FC_FDMI_HBA_ATTR_BIOSVERSION,
 424                                        &entry->type);
 425                        put_unaligned_be16(len, &entry->len);
 426                        fc_ct_ms_fill_attr(entry,
 427                                        fc_host_bootbios_version(lport->host),
 428                                        FC_FDMI_HBA_ATTR_BIOSVERSION_LEN);
 429
 430                        /* BIOS state */
 431                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 432                                        FC_FDMI_HBA_ATTR_BIOSVERSION_LEN);
 433                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 434                        len += FC_FDMI_HBA_ATTR_BIOSSTATE_LEN;
 435                        put_unaligned_be16(FC_FDMI_HBA_ATTR_BIOSSTATE,
 436                                        &entry->type);
 437                        put_unaligned_be16(len, &entry->len);
 438                        put_unaligned_be32(fc_host_bootbios_state(lport->host),
 439                                        &entry->value);
 440
 441                        /* Vendor identifier  */
 442                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 443                                        FC_FDMI_HBA_ATTR_BIOSSTATE_LEN);
 444                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 445                        len += FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN;
 446                        put_unaligned_be16(FC_FDMI_HBA_ATTR_VENDORIDENTIFIER,
 447                                        &entry->type);
 448                        put_unaligned_be16(len, &entry->len);
 449                        fc_ct_ms_fill_attr(entry,
 450                                        fc_host_vendor_identifier(lport->host),
 451                                        FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN);
 452                }
 453
 454                break;
 455        case FC_FDMI_RPA:
 456                numattrs = 6;
 457                len = sizeof(struct fc_fdmi_rpa);
 458                len -= sizeof(struct fc_fdmi_attr_entry);
 459                len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
 460                len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
 461                len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
 462                len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
 463                len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
 464                len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
 465                len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
 466
 467
 468                if (fc_host->fdmi_version == FDMI_V2) {
 469                        numattrs += 10;
 470
 471                        len += FC_FDMI_PORT_ATTR_NODENAME_LEN;
 472                        len += FC_FDMI_PORT_ATTR_PORTNAME_LEN;
 473                        len += FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN;
 474                        len += FC_FDMI_PORT_ATTR_PORTTYPE_LEN;
 475                        len += FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN;
 476                        len += FC_FDMI_PORT_ATTR_FABRICNAME_LEN;
 477                        len += FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN;
 478                        len += FC_FDMI_PORT_ATTR_PORTSTATE_LEN;
 479                        len += FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN;
 480                        len += FC_FDMI_PORT_ATTR_PORTID_LEN;
 481
 482                }
 483
 484                ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
 485                                    FC_FDMI_SUBTYPE);
 486
 487                /* Port Name */
 488                put_unaligned_be64(lport->wwpn,
 489                                   &ct->payload.rpa.port.portname);
 490
 491                /* Port Attributes */
 492                put_unaligned_be32(numattrs,
 493                                   &ct->payload.rpa.hba_attrs.numattrs);
 494
 495                hba_attrs = &ct->payload.rpa.hba_attrs;
 496                entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
 497
 498                /* FC4 types */
 499                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 500                len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
 501                put_unaligned_be16(FC_FDMI_PORT_ATTR_FC4TYPES,
 502                                   &entry->type);
 503                put_unaligned_be16(len, &entry->len);
 504                memcpy(&entry->value, fc_host_supported_fc4s(lport->host),
 505                       FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
 506
 507                /* Supported Speed */
 508                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 509                                        FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
 510                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 511                len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
 512                put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
 513                                   &entry->type);
 514                put_unaligned_be16(len, &entry->len);
 515
 516                put_unaligned_be32(fc_host_supported_speeds(lport->host),
 517                                   &entry->value);
 518
 519                /* Current Port Speed */
 520                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 521                                        FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
 522                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 523                len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
 524                put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
 525                                   &entry->type);
 526                put_unaligned_be16(len, &entry->len);
 527                put_unaligned_be32(lport->link_speed,
 528                                   &entry->value);
 529
 530                /* Max Frame Size */
 531                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 532                                        FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
 533                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 534                len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
 535                put_unaligned_be16(FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
 536                                   &entry->type);
 537                put_unaligned_be16(len, &entry->len);
 538                put_unaligned_be32(fc_host_maxframe_size(lport->host),
 539                                   &entry->value);
 540
 541                /* OS Device Name */
 542                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 543                                        FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN);
 544                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 545                len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
 546                put_unaligned_be16(FC_FDMI_PORT_ATTR_OSDEVICENAME,
 547                                   &entry->type);
 548                put_unaligned_be16(len, &entry->len);
 549                /* Use the sysfs device name */
 550                fc_ct_ms_fill_attr(entry,
 551                        dev_name(&lport->host->shost_gendev),
 552                        strnlen(dev_name(&lport->host->shost_gendev),
 553                                FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
 554
 555                /* Host Name */
 556                entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 557                                        FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN);
 558                len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 559                len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
 560                put_unaligned_be16(FC_FDMI_PORT_ATTR_HOSTNAME,
 561                                   &entry->type);
 562                put_unaligned_be16(len, &entry->len);
 563                if (strlen(fc_host_system_hostname(lport->host)))
 564                        fc_ct_ms_fill_attr(entry,
 565                                fc_host_system_hostname(lport->host),
 566                                strnlen(fc_host_system_hostname(lport->host),
 567                                        FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
 568                else
 569                        fc_ct_ms_fill_attr(entry,
 570                                init_utsname()->nodename,
 571                                FC_FDMI_PORT_ATTR_HOSTNAME_LEN);
 572
 573
 574                if (fc_host->fdmi_version == FDMI_V2) {
 575
 576                        /* Node name */
 577                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 578                                        FC_FDMI_PORT_ATTR_HOSTNAME_LEN);
 579                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 580                        len += FC_FDMI_PORT_ATTR_NODENAME_LEN;
 581                        put_unaligned_be16(FC_FDMI_PORT_ATTR_NODENAME,
 582                                        &entry->type);
 583                        put_unaligned_be16(len, &entry->len);
 584                        put_unaligned_be64(fc_host_node_name(lport->host),
 585                                        &entry->value);
 586
 587                        /* Port name  */
 588                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 589                                        FC_FDMI_PORT_ATTR_NODENAME_LEN);
 590                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 591                        len += FC_FDMI_PORT_ATTR_PORTNAME_LEN;
 592                        put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTNAME,
 593                                        &entry->type);
 594                        put_unaligned_be16(len, &entry->len);
 595                        put_unaligned_be64(lport->wwpn,
 596                                        &entry->value);
 597
 598                        /* Port symbolic name */
 599                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 600                                        FC_FDMI_PORT_ATTR_PORTNAME_LEN);
 601                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 602                        len += FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN;
 603                        put_unaligned_be16(FC_FDMI_PORT_ATTR_SYMBOLICNAME,
 604                                        &entry->type);
 605                        put_unaligned_be16(len, &entry->len);
 606                        fc_ct_ms_fill_attr(entry,
 607                                        fc_host_symbolic_name(lport->host),
 608                                        FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN);
 609
 610                        /* Port type */
 611                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 612                                        FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN);
 613                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 614                        len += FC_FDMI_PORT_ATTR_PORTTYPE_LEN;
 615                        put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTTYPE,
 616                                        &entry->type);
 617                        put_unaligned_be16(len, &entry->len);
 618                        put_unaligned_be32(fc_host_port_type(lport->host),
 619                                        &entry->value);
 620
 621                        /* Supported class of service */
 622                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 623                                        FC_FDMI_PORT_ATTR_PORTTYPE_LEN);
 624                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 625                        len += FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN;
 626                        put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC,
 627                                        &entry->type);
 628                        put_unaligned_be16(len, &entry->len);
 629                        put_unaligned_be32(fc_host_supported_classes(lport->host),
 630                                        &entry->value);
 631
 632                        /* Port Fabric name */
 633                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 634                                        FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN);
 635                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 636                        len += FC_FDMI_PORT_ATTR_FABRICNAME_LEN;
 637                        put_unaligned_be16(FC_FDMI_PORT_ATTR_FABRICNAME,
 638                                        &entry->type);
 639                        put_unaligned_be16(len, &entry->len);
 640                        put_unaligned_be64(fc_host_fabric_name(lport->host),
 641                                        &entry->value);
 642
 643                        /* Port active FC-4 */
 644                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 645                                        FC_FDMI_PORT_ATTR_FABRICNAME_LEN);
 646                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 647                        len += FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN;
 648                        put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTFC4TYPE,
 649                                        &entry->type);
 650                        put_unaligned_be16(len, &entry->len);
 651                        memcpy(&entry->value, fc_host_active_fc4s(lport->host),
 652                                        FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN);
 653
 654                        /* Port state */
 655                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 656                                        FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN);
 657                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 658                        len += FC_FDMI_PORT_ATTR_PORTSTATE_LEN;
 659                        put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTSTATE,
 660                                        &entry->type);
 661                        put_unaligned_be16(len, &entry->len);
 662                        put_unaligned_be32(fc_host_port_state(lport->host),
 663                                        &entry->value);
 664
 665                        /* Discovered ports */
 666                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 667                                        FC_FDMI_PORT_ATTR_PORTSTATE_LEN);
 668                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 669                        len += FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN;
 670                        put_unaligned_be16(FC_FDMI_PORT_ATTR_DISCOVEREDPORTS,
 671                                        &entry->type);
 672                        put_unaligned_be16(len, &entry->len);
 673                        put_unaligned_be32(fc_host_num_discovered_ports(lport->host),
 674                                        &entry->value);
 675
 676                        /* Port ID */
 677                        entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 678                                        FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN);
 679                        len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 680                        len += FC_FDMI_PORT_ATTR_PORTID_LEN;
 681                        put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTID,
 682                                        &entry->type);
 683                        put_unaligned_be16(len, &entry->len);
 684                        put_unaligned_be32(fc_host_port_id(lport->host),
 685                                        &entry->value);
 686                }
 687
 688                break;
 689        case FC_FDMI_DPRT:
 690                len = sizeof(struct fc_fdmi_dprt);
 691                ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
 692                                    FC_FDMI_SUBTYPE);
 693                /* Port Name */
 694                put_unaligned_be64(lport->wwpn,
 695                                   &ct->payload.dprt.port.portname);
 696                break;
 697        case FC_FDMI_DHBA:
 698                len = sizeof(struct fc_fdmi_dhba);
 699                ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
 700                                    FC_FDMI_SUBTYPE);
 701                /* HBA Identifier */
 702                put_unaligned_be64(lport->wwpn, &ct->payload.dhba.hbaid.id);
 703                break;
 704        default:
 705                return -EINVAL;
 706        }
 707        *r_ctl = FC_RCTL_DD_UNSOL_CTL;
 708        *fh_type = FC_TYPE_CT;
 709        return 0;
 710}
 711
 712/**
 713 * fc_ct_fill() - Fill in a common transport service request frame
 714 * @lport: local port.
 715 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
 716 * @fp: frame to contain payload.
 717 * @op: CT opcode.
 718 * @r_ctl: pointer to FC header R_CTL.
 719 * @fh_type: pointer to FC-4 type.
 720 */
 721static inline int fc_ct_fill(struct fc_lport *lport,
 722                      u32 fc_id, struct fc_frame *fp,
 723                      unsigned int op, enum fc_rctl *r_ctl,
 724                      enum fc_fh_type *fh_type, u32 *did)
 725{
 726        int rc = -EINVAL;
 727
 728        switch (fc_id) {
 729        case FC_FID_MGMT_SERV:
 730                rc = fc_ct_ms_fill(lport, fc_id, fp, op, r_ctl, fh_type);
 731                *did = FC_FID_MGMT_SERV;
 732                break;
 733        case FC_FID_DIR_SERV:
 734        default:
 735                rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type);
 736                *did = FC_FID_DIR_SERV;
 737                break;
 738        }
 739
 740        return rc;
 741}
 742/**
 743 * fc_plogi_fill - Fill in plogi request frame
 744 */
 745static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
 746                                 unsigned int op)
 747{
 748        struct fc_els_flogi *plogi;
 749        struct fc_els_csp *csp;
 750        struct fc_els_cssp *cp;
 751
 752        plogi = fc_frame_payload_get(fp, sizeof(*plogi));
 753        memset(plogi, 0, sizeof(*plogi));
 754        plogi->fl_cmd = (u8) op;
 755        put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn);
 756        put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn);
 757
 758        csp = &plogi->fl_csp;
 759        csp->sp_hi_ver = 0x20;
 760        csp->sp_lo_ver = 0x20;
 761        csp->sp_bb_cred = htons(10);    /* this gets set by gateway */
 762        csp->sp_bb_data = htons((u16) lport->mfs);
 763        cp = &plogi->fl_cssp[3 - 1];    /* class 3 parameters */
 764        cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
 765        csp->sp_features = htons(FC_SP_FT_CIRO);
 766        csp->sp_tot_seq = htons(255);   /* seq. we accept */
 767        csp->sp_rel_off = htons(0x1f);
 768        csp->sp_e_d_tov = htonl(lport->e_d_tov);
 769
 770        cp->cp_rdfs = htons((u16) lport->mfs);
 771        cp->cp_con_seq = htons(255);
 772        cp->cp_open_seq = 1;
 773}
 774
 775/**
 776 * fc_flogi_fill - Fill in a flogi request frame.
 777 */
 778static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
 779{
 780        struct fc_els_csp *sp;
 781        struct fc_els_cssp *cp;
 782        struct fc_els_flogi *flogi;
 783
 784        flogi = fc_frame_payload_get(fp, sizeof(*flogi));
 785        memset(flogi, 0, sizeof(*flogi));
 786        flogi->fl_cmd = (u8) ELS_FLOGI;
 787        put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
 788        put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
 789        sp = &flogi->fl_csp;
 790        sp->sp_hi_ver = 0x20;
 791        sp->sp_lo_ver = 0x20;
 792        sp->sp_bb_cred = htons(10);     /* this gets set by gateway */
 793        sp->sp_bb_data = htons((u16) lport->mfs);
 794        cp = &flogi->fl_cssp[3 - 1];    /* class 3 parameters */
 795        cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
 796        if (lport->does_npiv)
 797                sp->sp_features = htons(FC_SP_FT_NPIV);
 798}
 799
 800/**
 801 * fc_fdisc_fill - Fill in a fdisc request frame.
 802 */
 803static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
 804{
 805        struct fc_els_csp *sp;
 806        struct fc_els_cssp *cp;
 807        struct fc_els_flogi *fdisc;
 808
 809        fdisc = fc_frame_payload_get(fp, sizeof(*fdisc));
 810        memset(fdisc, 0, sizeof(*fdisc));
 811        fdisc->fl_cmd = (u8) ELS_FDISC;
 812        put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn);
 813        put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn);
 814        sp = &fdisc->fl_csp;
 815        sp->sp_hi_ver = 0x20;
 816        sp->sp_lo_ver = 0x20;
 817        sp->sp_bb_cred = htons(10);     /* this gets set by gateway */
 818        sp->sp_bb_data = htons((u16) lport->mfs);
 819        cp = &fdisc->fl_cssp[3 - 1];    /* class 3 parameters */
 820        cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
 821}
 822
 823/**
 824 * fc_logo_fill - Fill in a logo request frame.
 825 */
 826static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
 827{
 828        struct fc_els_logo *logo;
 829
 830        logo = fc_frame_payload_get(fp, sizeof(*logo));
 831        memset(logo, 0, sizeof(*logo));
 832        logo->fl_cmd = ELS_LOGO;
 833        hton24(logo->fl_n_port_id, lport->port_id);
 834        logo->fl_n_port_wwn = htonll(lport->wwpn);
 835}
 836
 837/**
 838 * fc_rtv_fill - Fill in RTV (read timeout value) request frame.
 839 */
 840static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp)
 841{
 842        struct fc_els_rtv *rtv;
 843
 844        rtv = fc_frame_payload_get(fp, sizeof(*rtv));
 845        memset(rtv, 0, sizeof(*rtv));
 846        rtv->rtv_cmd = ELS_RTV;
 847}
 848
 849/**
 850 * fc_rec_fill - Fill in rec request frame
 851 */
 852static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp)
 853{
 854        struct fc_els_rec *rec;
 855        struct fc_exch *ep = fc_seq_exch(fr_seq(fp));
 856
 857        rec = fc_frame_payload_get(fp, sizeof(*rec));
 858        memset(rec, 0, sizeof(*rec));
 859        rec->rec_cmd = ELS_REC;
 860        hton24(rec->rec_s_id, lport->port_id);
 861        rec->rec_ox_id = htons(ep->oxid);
 862        rec->rec_rx_id = htons(ep->rxid);
 863}
 864
 865/**
 866 * fc_prli_fill - Fill in prli request frame
 867 */
 868static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp)
 869{
 870        struct {
 871                struct fc_els_prli prli;
 872                struct fc_els_spp spp;
 873        } *pp;
 874
 875        pp = fc_frame_payload_get(fp, sizeof(*pp));
 876        memset(pp, 0, sizeof(*pp));
 877        pp->prli.prli_cmd = ELS_PRLI;
 878        pp->prli.prli_spp_len = sizeof(struct fc_els_spp);
 879        pp->prli.prli_len = htons(sizeof(*pp));
 880        pp->spp.spp_type = FC_TYPE_FCP;
 881        pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR;
 882        pp->spp.spp_params = htonl(lport->service_params);
 883}
 884
 885/**
 886 * fc_scr_fill - Fill in a scr request frame.
 887 */
 888static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
 889{
 890        struct fc_els_scr *scr;
 891
 892        scr = fc_frame_payload_get(fp, sizeof(*scr));
 893        memset(scr, 0, sizeof(*scr));
 894        scr->scr_cmd = ELS_SCR;
 895        scr->scr_reg_func = ELS_SCRF_FULL;
 896}
 897
 898/**
 899 * fc_els_fill - Fill in an ELS  request frame
 900 */
 901static inline int fc_els_fill(struct fc_lport *lport,
 902                       u32 did,
 903                       struct fc_frame *fp, unsigned int op,
 904                       enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
 905{
 906        switch (op) {
 907        case ELS_ADISC:
 908                fc_adisc_fill(lport, fp);
 909                break;
 910
 911        case ELS_PLOGI:
 912                fc_plogi_fill(lport, fp, ELS_PLOGI);
 913                break;
 914
 915        case ELS_FLOGI:
 916                fc_flogi_fill(lport, fp);
 917                break;
 918
 919        case ELS_FDISC:
 920                fc_fdisc_fill(lport, fp);
 921                break;
 922
 923        case ELS_LOGO:
 924                fc_logo_fill(lport, fp);
 925                break;
 926
 927        case ELS_RTV:
 928                fc_rtv_fill(lport, fp);
 929                break;
 930
 931        case ELS_REC:
 932                fc_rec_fill(lport, fp);
 933                break;
 934
 935        case ELS_PRLI:
 936                fc_prli_fill(lport, fp);
 937                break;
 938
 939        case ELS_SCR:
 940                fc_scr_fill(lport, fp);
 941                break;
 942
 943        default:
 944                return -EINVAL;
 945        }
 946
 947        *r_ctl = FC_RCTL_ELS_REQ;
 948        *fh_type = FC_TYPE_ELS;
 949        return 0;
 950}
 951#endif /* _FC_ENCODE_H_ */
 952