root/include/scsi/fc_encode.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. __fc_fill_fc_hdr
  2. fc_fill_fc_hdr
  3. fc_adisc_fill
  4. fc_ct_hdr_fill
  5. fc_ct_ns_fill
  6. fc_ct_ms_fill
  7. fc_ct_fill
  8. fc_plogi_fill
  9. fc_flogi_fill
  10. fc_fdisc_fill
  11. fc_logo_fill
  12. fc_rtv_fill
  13. fc_rec_fill
  14. fc_prli_fill
  15. fc_scr_fill
  16. fc_els_fill

   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 
  13 /*
  14  * F_CTL values for simple requests and responses.
  15  */
  16 #define FC_FCTL_REQ     (FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT)
  17 #define FC_FCTL_RESP    (FC_FC_EX_CTX | FC_FC_LAST_SEQ | \
  18                         FC_FC_END_SEQ | FC_FC_SEQ_INIT)
  19 
  20 struct fc_ns_rft {
  21         struct fc_ns_fid fid;   /* port ID object */
  22         struct fc_ns_fts fts;   /* FC4-types object */
  23 };
  24 
  25 struct fc_ct_req {
  26         struct fc_ct_hdr hdr;
  27         union {
  28                 struct fc_ns_gid_ft gid;
  29                 struct fc_ns_rn_id  rn;
  30                 struct fc_ns_rft rft;
  31                 struct fc_ns_rff_id rff;
  32                 struct fc_ns_fid fid;
  33                 struct fc_ns_rsnn snn;
  34                 struct fc_ns_rspn spn;
  35                 struct fc_fdmi_rhba rhba;
  36                 struct fc_fdmi_rpa  rpa;
  37                 struct fc_fdmi_dprt dprt;
  38                 struct fc_fdmi_dhba dhba;
  39         } payload;
  40 };
  41 
  42 static inline void __fc_fill_fc_hdr(struct fc_frame_header *fh,
  43                                     enum fc_rctl r_ctl,
  44                                     u32 did, u32 sid, enum fc_fh_type type,
  45                                     u32 f_ctl, u32 parm_offset)
  46 {
  47         WARN_ON(r_ctl == 0);
  48         fh->fh_r_ctl = r_ctl;
  49         hton24(fh->fh_d_id, did);
  50         hton24(fh->fh_s_id, sid);
  51         fh->fh_type = type;
  52         hton24(fh->fh_f_ctl, f_ctl);
  53         fh->fh_cs_ctl = 0;
  54         fh->fh_df_ctl = 0;
  55         fh->fh_parm_offset = htonl(parm_offset);
  56 }
  57 
  58 /**
  59  * fill FC header fields in specified fc_frame
  60  */
  61 static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
  62                                   u32 did, u32 sid, enum fc_fh_type type,
  63                                   u32 f_ctl, u32 parm_offset)
  64 {
  65         struct fc_frame_header *fh;
  66 
  67         fh = fc_frame_header_get(fp);
  68         __fc_fill_fc_hdr(fh, r_ctl, did, sid, type, f_ctl, parm_offset);
  69 }
  70 
  71 /**
  72  * fc_adisc_fill() - Fill in adisc request frame
  73  * @lport: local port.
  74  * @fp: fc frame where payload will be placed.
  75  */
  76 static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
  77 {
  78         struct fc_els_adisc *adisc;
  79 
  80         adisc = fc_frame_payload_get(fp, sizeof(*adisc));
  81         memset(adisc, 0, sizeof(*adisc));
  82         adisc->adisc_cmd = ELS_ADISC;
  83         put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
  84         put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
  85         hton24(adisc->adisc_port_id, lport->port_id);
  86 }
  87 
  88 /**
  89  * fc_ct_hdr_fill- fills ct header and reset ct payload
  90  * returns pointer to ct request.
  91  */
  92 static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
  93                                                unsigned int op, size_t req_size,
  94                                                enum fc_ct_fs_type fs_type,
  95                                                u8 subtype)
  96 {
  97         struct fc_ct_req *ct;
  98         size_t ct_plen;
  99 
 100         ct_plen  = sizeof(struct fc_ct_hdr) + req_size;
 101         ct = fc_frame_payload_get(fp, ct_plen);
 102         memset(ct, 0, ct_plen);
 103         ct->hdr.ct_rev = FC_CT_REV;
 104         ct->hdr.ct_fs_type = fs_type;
 105         ct->hdr.ct_fs_subtype = subtype;
 106         ct->hdr.ct_cmd = htons((u16) op);
 107         return ct;
 108 }
 109 
 110 /**
 111  * fc_ct_ns_fill() - Fill in a name service request frame
 112  * @lport: local port.
 113  * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
 114  * @fp: frame to contain payload.
 115  * @op: CT opcode.
 116  * @r_ctl: pointer to FC header R_CTL.
 117  * @fh_type: pointer to FC-4 type.
 118  */
 119 static inline int fc_ct_ns_fill(struct fc_lport *lport,
 120                       u32 fc_id, struct fc_frame *fp,
 121                       unsigned int op, enum fc_rctl *r_ctl,
 122                       enum fc_fh_type *fh_type)
 123 {
 124         struct fc_ct_req *ct;
 125         size_t len;
 126 
 127         switch (op) {
 128         case FC_NS_GPN_FT:
 129                 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft),
 130                                     FC_FST_DIR, FC_NS_SUBTYPE);
 131                 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
 132                 break;
 133 
 134         case FC_NS_GPN_ID:
 135                 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid),
 136                                     FC_FST_DIR, FC_NS_SUBTYPE);
 137                 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
 138                 hton24(ct->payload.fid.fp_fid, fc_id);
 139                 break;
 140 
 141         case FC_NS_RFT_ID:
 142                 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft),
 143                                     FC_FST_DIR, FC_NS_SUBTYPE);
 144                 hton24(ct->payload.rft.fid.fp_fid, lport->port_id);
 145                 ct->payload.rft.fts = lport->fcts;
 146                 break;
 147 
 148         case FC_NS_RFF_ID:
 149                 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id),
 150                                     FC_FST_DIR, FC_NS_SUBTYPE);
 151                 hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id);
 152                 ct->payload.rff.fr_type = FC_TYPE_FCP;
 153                 if (lport->service_params & FCP_SPPF_INIT_FCN)
 154                         ct->payload.rff.fr_feat = FCP_FEAT_INIT;
 155                 if (lport->service_params & FCP_SPPF_TARG_FCN)
 156                         ct->payload.rff.fr_feat |= FCP_FEAT_TARG;
 157                 break;
 158 
 159         case FC_NS_RNN_ID:
 160                 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id),
 161                                     FC_FST_DIR, FC_NS_SUBTYPE);
 162                 hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id);
 163                 put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
 164                 break;
 165 
 166         case FC_NS_RSPN_ID:
 167                 len = strnlen(fc_host_symbolic_name(lport->host), 255);
 168                 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len,
 169                                     FC_FST_DIR, FC_NS_SUBTYPE);
 170                 hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id);
 171                 strncpy(ct->payload.spn.fr_name,
 172                         fc_host_symbolic_name(lport->host), len);
 173                 ct->payload.spn.fr_name_len = len;
 174                 break;
 175 
 176         case FC_NS_RSNN_NN:
 177                 len = strnlen(fc_host_symbolic_name(lport->host), 255);
 178                 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len,
 179                                     FC_FST_DIR, FC_NS_SUBTYPE);
 180                 put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
 181                 strncpy(ct->payload.snn.fr_name,
 182                         fc_host_symbolic_name(lport->host), len);
 183                 ct->payload.snn.fr_name_len = len;
 184                 break;
 185 
 186         default:
 187                 return -EINVAL;
 188         }
 189         *r_ctl = FC_RCTL_DD_UNSOL_CTL;
 190         *fh_type = FC_TYPE_CT;
 191         return 0;
 192 }
 193 
 194 /**
 195  * fc_ct_ms_fill() - Fill in a mgmt service request frame
 196  * @lport: local port.
 197  * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
 198  * @fp: frame to contain payload.
 199  * @op: CT opcode.
 200  * @r_ctl: pointer to FC header R_CTL.
 201  * @fh_type: pointer to FC-4 type.
 202  */
 203 static inline int fc_ct_ms_fill(struct fc_lport *lport,
 204                       u32 fc_id, struct fc_frame *fp,
 205                       unsigned int op, enum fc_rctl *r_ctl,
 206                       enum fc_fh_type *fh_type)
 207 {
 208         struct fc_ct_req *ct;
 209         size_t len;
 210         struct fc_fdmi_attr_entry *entry;
 211         struct fs_fdmi_attrs *hba_attrs;
 212         int numattrs = 0;
 213 
 214         switch (op) {
 215         case FC_FDMI_RHBA:
 216                 numattrs = 10;
 217                 len = sizeof(struct fc_fdmi_rhba);
 218                 len -= sizeof(struct fc_fdmi_attr_entry);
 219                 len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
 220                 len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
 221                 len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
 222                 len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
 223                 len += FC_FDMI_HBA_ATTR_MODEL_LEN;
 224                 len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
 225                 len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
 226                 len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
 227                 len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
 228                 len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
 229                 len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
 230                 ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
 231                                     FC_FDMI_SUBTYPE);
 232 
 233                 /* HBA Identifier */
 234                 put_unaligned_be64(lport->wwpn, &ct->payload.rhba.hbaid.id);
 235                 /* Number of Ports - always 1 */
 236                 put_unaligned_be32(1, &ct->payload.rhba.port.numport);
 237                 /* Port Name */
 238                 put_unaligned_be64(lport->wwpn,
 239                                    &ct->payload.rhba.port.port[0].portname);
 240 
 241                 /* HBA Attributes */
 242                 put_unaligned_be32(numattrs,
 243                                    &ct->payload.rhba.hba_attrs.numattrs);
 244                 hba_attrs = &ct->payload.rhba.hba_attrs;
 245                 entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
 246                 /* NodeName*/
 247                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 248                 len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
 249                 put_unaligned_be16(FC_FDMI_HBA_ATTR_NODENAME,
 250                                    &entry->type);
 251                 put_unaligned_be16(len, &entry->len);
 252                 put_unaligned_be64(lport->wwnn,
 253                                    (__be64 *)&entry->value[0]);
 254 
 255                 /* Manufacturer */
 256                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 257                                         FC_FDMI_HBA_ATTR_NODENAME_LEN);
 258                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 259                 len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
 260                 put_unaligned_be16(FC_FDMI_HBA_ATTR_MANUFACTURER,
 261                                    &entry->type);
 262                 put_unaligned_be16(len, &entry->len);
 263                 strncpy((char *)&entry->value,
 264                         fc_host_manufacturer(lport->host),
 265                         FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
 266 
 267                 /* SerialNumber */
 268                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 269                                         FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
 270                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 271                 len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
 272                 put_unaligned_be16(FC_FDMI_HBA_ATTR_SERIALNUMBER,
 273                                    &entry->type);
 274                 put_unaligned_be16(len, &entry->len);
 275                 strncpy((char *)&entry->value,
 276                         fc_host_serial_number(lport->host),
 277                         FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
 278 
 279                 /* Model */
 280                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 281                                         FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
 282                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 283                 len += FC_FDMI_HBA_ATTR_MODEL_LEN;
 284                 put_unaligned_be16(FC_FDMI_HBA_ATTR_MODEL,
 285                                    &entry->type);
 286                 put_unaligned_be16(len, &entry->len);
 287                 strncpy((char *)&entry->value,
 288                         fc_host_model(lport->host),
 289                         FC_FDMI_HBA_ATTR_MODEL_LEN);
 290 
 291                 /* Model Description */
 292                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 293                                         FC_FDMI_HBA_ATTR_MODEL_LEN);
 294                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 295                 len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
 296                 put_unaligned_be16(FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
 297                                    &entry->type);
 298                 put_unaligned_be16(len, &entry->len);
 299                 strncpy((char *)&entry->value,
 300                         fc_host_model_description(lport->host),
 301                         FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
 302 
 303                 /* Hardware Version */
 304                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 305                                         FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
 306                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 307                 len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
 308                 put_unaligned_be16(FC_FDMI_HBA_ATTR_HARDWAREVERSION,
 309                                    &entry->type);
 310                 put_unaligned_be16(len, &entry->len);
 311                 strncpy((char *)&entry->value,
 312                         fc_host_hardware_version(lport->host),
 313                         FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
 314 
 315                 /* Driver Version */
 316                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 317                                         FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
 318                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 319                 len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
 320                 put_unaligned_be16(FC_FDMI_HBA_ATTR_DRIVERVERSION,
 321                                    &entry->type);
 322                 put_unaligned_be16(len, &entry->len);
 323                 strncpy((char *)&entry->value,
 324                         fc_host_driver_version(lport->host),
 325                         FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
 326 
 327                 /* OptionROM Version */
 328                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 329                                         FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
 330                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 331                 len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
 332                 put_unaligned_be16(FC_FDMI_HBA_ATTR_OPTIONROMVERSION,
 333                                    &entry->type);
 334                 put_unaligned_be16(len, &entry->len);
 335                 strncpy((char *)&entry->value,
 336                         fc_host_optionrom_version(lport->host),
 337                         FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
 338 
 339                 /* Firmware Version */
 340                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 341                                         FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
 342                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 343                 len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
 344                 put_unaligned_be16(FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
 345                                    &entry->type);
 346                 put_unaligned_be16(len, &entry->len);
 347                 strncpy((char *)&entry->value,
 348                         fc_host_firmware_version(lport->host),
 349                         FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
 350 
 351                 /* OS Name and Version */
 352                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 353                                         FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
 354                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 355                 len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
 356                 put_unaligned_be16(FC_FDMI_HBA_ATTR_OSNAMEVERSION,
 357                                    &entry->type);
 358                 put_unaligned_be16(len, &entry->len);
 359                 snprintf((char *)&entry->value,
 360                         FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN,
 361                         "%s v%s",
 362                         init_utsname()->sysname,
 363                         init_utsname()->release);
 364                 break;
 365         case FC_FDMI_RPA:
 366                 numattrs = 6;
 367                 len = sizeof(struct fc_fdmi_rpa);
 368                 len -= sizeof(struct fc_fdmi_attr_entry);
 369                 len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
 370                 len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
 371                 len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
 372                 len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
 373                 len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
 374                 len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
 375                 len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
 376                 ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
 377                                     FC_FDMI_SUBTYPE);
 378 
 379                 /* Port Name */
 380                 put_unaligned_be64(lport->wwpn,
 381                                    &ct->payload.rpa.port.portname);
 382 
 383                 /* Port Attributes */
 384                 put_unaligned_be32(numattrs,
 385                                    &ct->payload.rpa.hba_attrs.numattrs);
 386 
 387                 hba_attrs = &ct->payload.rpa.hba_attrs;
 388                 entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
 389 
 390                 /* FC4 types */
 391                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 392                 len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
 393                 put_unaligned_be16(FC_FDMI_PORT_ATTR_FC4TYPES,
 394                                    &entry->type);
 395                 put_unaligned_be16(len, &entry->len);
 396                 memcpy(&entry->value, fc_host_supported_fc4s(lport->host),
 397                        FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
 398 
 399                 /* Supported Speed */
 400                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 401                                         FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
 402                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 403                 len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
 404                 put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
 405                                    &entry->type);
 406                 put_unaligned_be16(len, &entry->len);
 407 
 408                 put_unaligned_be32(fc_host_supported_speeds(lport->host),
 409                                    &entry->value);
 410 
 411                 /* Current Port Speed */
 412                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 413                                         FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
 414                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 415                 len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
 416                 put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
 417                                    &entry->type);
 418                 put_unaligned_be16(len, &entry->len);
 419                 put_unaligned_be32(lport->link_speed,
 420                                    &entry->value);
 421 
 422                 /* Max Frame Size */
 423                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 424                                         FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
 425                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 426                 len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
 427                 put_unaligned_be16(FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
 428                                    &entry->type);
 429                 put_unaligned_be16(len, &entry->len);
 430                 put_unaligned_be32(fc_host_maxframe_size(lport->host),
 431                                    &entry->value);
 432 
 433                 /* OS Device Name */
 434                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 435                                         FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN);
 436                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 437                 len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
 438                 put_unaligned_be16(FC_FDMI_PORT_ATTR_OSDEVICENAME,
 439                                    &entry->type);
 440                 put_unaligned_be16(len, &entry->len);
 441                 /* Use the sysfs device name */
 442                 strncpy((char *)&entry->value,
 443                         dev_name(&lport->host->shost_gendev),
 444                         strnlen(dev_name(&lport->host->shost_gendev),
 445                                 FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
 446 
 447                 /* Host Name */
 448                 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
 449                                         FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN);
 450                 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
 451                 len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
 452                 put_unaligned_be16(FC_FDMI_PORT_ATTR_HOSTNAME,
 453                                    &entry->type);
 454                 put_unaligned_be16(len, &entry->len);
 455                 if (strlen(fc_host_system_hostname(lport->host)))
 456                         strncpy((char *)&entry->value,
 457                                 fc_host_system_hostname(lport->host),
 458                                 strnlen(fc_host_system_hostname(lport->host),
 459                                         FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
 460                 else
 461                         strncpy((char *)&entry->value,
 462                                 init_utsname()->nodename,
 463                                 FC_FDMI_PORT_ATTR_HOSTNAME_LEN);
 464                 break;
 465         case FC_FDMI_DPRT:
 466                 len = sizeof(struct fc_fdmi_dprt);
 467                 ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
 468                                     FC_FDMI_SUBTYPE);
 469                 /* Port Name */
 470                 put_unaligned_be64(lport->wwpn,
 471                                    &ct->payload.dprt.port.portname);
 472                 break;
 473         case FC_FDMI_DHBA:
 474                 len = sizeof(struct fc_fdmi_dhba);
 475                 ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
 476                                     FC_FDMI_SUBTYPE);
 477                 /* HBA Identifier */
 478                 put_unaligned_be64(lport->wwpn, &ct->payload.dhba.hbaid.id);
 479                 break;
 480         default:
 481                 return -EINVAL;
 482         }
 483         *r_ctl = FC_RCTL_DD_UNSOL_CTL;
 484         *fh_type = FC_TYPE_CT;
 485         return 0;
 486 }
 487 
 488 /**
 489  * fc_ct_fill() - Fill in a common transport service request frame
 490  * @lport: local port.
 491  * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
 492  * @fp: frame to contain payload.
 493  * @op: CT opcode.
 494  * @r_ctl: pointer to FC header R_CTL.
 495  * @fh_type: pointer to FC-4 type.
 496  */
 497 static inline int fc_ct_fill(struct fc_lport *lport,
 498                       u32 fc_id, struct fc_frame *fp,
 499                       unsigned int op, enum fc_rctl *r_ctl,
 500                       enum fc_fh_type *fh_type, u32 *did)
 501 {
 502         int rc = -EINVAL;
 503 
 504         switch (fc_id) {
 505         case FC_FID_MGMT_SERV:
 506                 rc = fc_ct_ms_fill(lport, fc_id, fp, op, r_ctl, fh_type);
 507                 *did = FC_FID_MGMT_SERV;
 508                 break;
 509         case FC_FID_DIR_SERV:
 510         default:
 511                 rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type);
 512                 *did = FC_FID_DIR_SERV;
 513                 break;
 514         }
 515 
 516         return rc;
 517 }
 518 /**
 519  * fc_plogi_fill - Fill in plogi request frame
 520  */
 521 static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
 522                                  unsigned int op)
 523 {
 524         struct fc_els_flogi *plogi;
 525         struct fc_els_csp *csp;
 526         struct fc_els_cssp *cp;
 527 
 528         plogi = fc_frame_payload_get(fp, sizeof(*plogi));
 529         memset(plogi, 0, sizeof(*plogi));
 530         plogi->fl_cmd = (u8) op;
 531         put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn);
 532         put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn);
 533 
 534         csp = &plogi->fl_csp;
 535         csp->sp_hi_ver = 0x20;
 536         csp->sp_lo_ver = 0x20;
 537         csp->sp_bb_cred = htons(10);    /* this gets set by gateway */
 538         csp->sp_bb_data = htons((u16) lport->mfs);
 539         cp = &plogi->fl_cssp[3 - 1];    /* class 3 parameters */
 540         cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
 541         csp->sp_features = htons(FC_SP_FT_CIRO);
 542         csp->sp_tot_seq = htons(255);   /* seq. we accept */
 543         csp->sp_rel_off = htons(0x1f);
 544         csp->sp_e_d_tov = htonl(lport->e_d_tov);
 545 
 546         cp->cp_rdfs = htons((u16) lport->mfs);
 547         cp->cp_con_seq = htons(255);
 548         cp->cp_open_seq = 1;
 549 }
 550 
 551 /**
 552  * fc_flogi_fill - Fill in a flogi request frame.
 553  */
 554 static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
 555 {
 556         struct fc_els_csp *sp;
 557         struct fc_els_cssp *cp;
 558         struct fc_els_flogi *flogi;
 559 
 560         flogi = fc_frame_payload_get(fp, sizeof(*flogi));
 561         memset(flogi, 0, sizeof(*flogi));
 562         flogi->fl_cmd = (u8) ELS_FLOGI;
 563         put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
 564         put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
 565         sp = &flogi->fl_csp;
 566         sp->sp_hi_ver = 0x20;
 567         sp->sp_lo_ver = 0x20;
 568         sp->sp_bb_cred = htons(10);     /* this gets set by gateway */
 569         sp->sp_bb_data = htons((u16) lport->mfs);
 570         cp = &flogi->fl_cssp[3 - 1];    /* class 3 parameters */
 571         cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
 572         if (lport->does_npiv)
 573                 sp->sp_features = htons(FC_SP_FT_NPIV);
 574 }
 575 
 576 /**
 577  * fc_fdisc_fill - Fill in a fdisc request frame.
 578  */
 579 static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
 580 {
 581         struct fc_els_csp *sp;
 582         struct fc_els_cssp *cp;
 583         struct fc_els_flogi *fdisc;
 584 
 585         fdisc = fc_frame_payload_get(fp, sizeof(*fdisc));
 586         memset(fdisc, 0, sizeof(*fdisc));
 587         fdisc->fl_cmd = (u8) ELS_FDISC;
 588         put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn);
 589         put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn);
 590         sp = &fdisc->fl_csp;
 591         sp->sp_hi_ver = 0x20;
 592         sp->sp_lo_ver = 0x20;
 593         sp->sp_bb_cred = htons(10);     /* this gets set by gateway */
 594         sp->sp_bb_data = htons((u16) lport->mfs);
 595         cp = &fdisc->fl_cssp[3 - 1];    /* class 3 parameters */
 596         cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
 597 }
 598 
 599 /**
 600  * fc_logo_fill - Fill in a logo request frame.
 601  */
 602 static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
 603 {
 604         struct fc_els_logo *logo;
 605 
 606         logo = fc_frame_payload_get(fp, sizeof(*logo));
 607         memset(logo, 0, sizeof(*logo));
 608         logo->fl_cmd = ELS_LOGO;
 609         hton24(logo->fl_n_port_id, lport->port_id);
 610         logo->fl_n_port_wwn = htonll(lport->wwpn);
 611 }
 612 
 613 /**
 614  * fc_rtv_fill - Fill in RTV (read timeout value) request frame.
 615  */
 616 static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp)
 617 {
 618         struct fc_els_rtv *rtv;
 619 
 620         rtv = fc_frame_payload_get(fp, sizeof(*rtv));
 621         memset(rtv, 0, sizeof(*rtv));
 622         rtv->rtv_cmd = ELS_RTV;
 623 }
 624 
 625 /**
 626  * fc_rec_fill - Fill in rec request frame
 627  */
 628 static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp)
 629 {
 630         struct fc_els_rec *rec;
 631         struct fc_exch *ep = fc_seq_exch(fr_seq(fp));
 632 
 633         rec = fc_frame_payload_get(fp, sizeof(*rec));
 634         memset(rec, 0, sizeof(*rec));
 635         rec->rec_cmd = ELS_REC;
 636         hton24(rec->rec_s_id, lport->port_id);
 637         rec->rec_ox_id = htons(ep->oxid);
 638         rec->rec_rx_id = htons(ep->rxid);
 639 }
 640 
 641 /**
 642  * fc_prli_fill - Fill in prli request frame
 643  */
 644 static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp)
 645 {
 646         struct {
 647                 struct fc_els_prli prli;
 648                 struct fc_els_spp spp;
 649         } *pp;
 650 
 651         pp = fc_frame_payload_get(fp, sizeof(*pp));
 652         memset(pp, 0, sizeof(*pp));
 653         pp->prli.prli_cmd = ELS_PRLI;
 654         pp->prli.prli_spp_len = sizeof(struct fc_els_spp);
 655         pp->prli.prli_len = htons(sizeof(*pp));
 656         pp->spp.spp_type = FC_TYPE_FCP;
 657         pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR;
 658         pp->spp.spp_params = htonl(lport->service_params);
 659 }
 660 
 661 /**
 662  * fc_scr_fill - Fill in a scr request frame.
 663  */
 664 static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
 665 {
 666         struct fc_els_scr *scr;
 667 
 668         scr = fc_frame_payload_get(fp, sizeof(*scr));
 669         memset(scr, 0, sizeof(*scr));
 670         scr->scr_cmd = ELS_SCR;
 671         scr->scr_reg_func = ELS_SCRF_FULL;
 672 }
 673 
 674 /**
 675  * fc_els_fill - Fill in an ELS  request frame
 676  */
 677 static inline int fc_els_fill(struct fc_lport *lport,
 678                        u32 did,
 679                        struct fc_frame *fp, unsigned int op,
 680                        enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
 681 {
 682         switch (op) {
 683         case ELS_ADISC:
 684                 fc_adisc_fill(lport, fp);
 685                 break;
 686 
 687         case ELS_PLOGI:
 688                 fc_plogi_fill(lport, fp, ELS_PLOGI);
 689                 break;
 690 
 691         case ELS_FLOGI:
 692                 fc_flogi_fill(lport, fp);
 693                 break;
 694 
 695         case ELS_FDISC:
 696                 fc_fdisc_fill(lport, fp);
 697                 break;
 698 
 699         case ELS_LOGO:
 700                 fc_logo_fill(lport, fp);
 701                 break;
 702 
 703         case ELS_RTV:
 704                 fc_rtv_fill(lport, fp);
 705                 break;
 706 
 707         case ELS_REC:
 708                 fc_rec_fill(lport, fp);
 709                 break;
 710 
 711         case ELS_PRLI:
 712                 fc_prli_fill(lport, fp);
 713                 break;
 714 
 715         case ELS_SCR:
 716                 fc_scr_fill(lport, fp);
 717                 break;
 718 
 719         default:
 720                 return -EINVAL;
 721         }
 722 
 723         *r_ctl = FC_RCTL_ELS_REQ;
 724         *fh_type = FC_TYPE_ELS;
 725         return 0;
 726 }
 727 #endif /* _FC_ENCODE_H_ */

/* [<][>][^][v][top][bottom][index][help] */