diff options
Diffstat (limited to 'include/scsi/fc_encode.h')
| -rw-r--r-- | include/scsi/fc_encode.h | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h index 27dad703824f..8eb0a0fc0a71 100644 --- a/include/scsi/fc_encode.h +++ b/include/scsi/fc_encode.h | |||
| @@ -32,7 +32,10 @@ struct fc_ct_req { | |||
| 32 | struct fc_ns_gid_ft gid; | 32 | struct fc_ns_gid_ft gid; |
| 33 | struct fc_ns_rn_id rn; | 33 | struct fc_ns_rn_id rn; |
| 34 | struct fc_ns_rft rft; | 34 | struct fc_ns_rft rft; |
| 35 | struct fc_ns_rff_id rff; | ||
| 35 | struct fc_ns_fid fid; | 36 | struct fc_ns_fid fid; |
| 37 | struct fc_ns_rsnn snn; | ||
| 38 | struct fc_ns_rspn spn; | ||
| 36 | } payload; | 39 | } payload; |
| 37 | }; | 40 | }; |
| 38 | 41 | ||
| @@ -109,6 +112,7 @@ static inline int fc_ct_fill(struct fc_lport *lport, | |||
| 109 | enum fc_fh_type *fh_type) | 112 | enum fc_fh_type *fh_type) |
| 110 | { | 113 | { |
| 111 | struct fc_ct_req *ct; | 114 | struct fc_ct_req *ct; |
| 115 | size_t len; | ||
| 112 | 116 | ||
| 113 | switch (op) { | 117 | switch (op) { |
| 114 | case FC_NS_GPN_FT: | 118 | case FC_NS_GPN_FT: |
| @@ -128,12 +132,41 @@ static inline int fc_ct_fill(struct fc_lport *lport, | |||
| 128 | ct->payload.rft.fts = lport->fcts; | 132 | ct->payload.rft.fts = lport->fcts; |
| 129 | break; | 133 | break; |
| 130 | 134 | ||
| 131 | case FC_NS_RPN_ID: | 135 | case FC_NS_RFF_ID: |
| 136 | ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id)); | ||
| 137 | hton24(ct->payload.rff.fr_fid.fp_fid, | ||
| 138 | fc_host_port_id(lport->host)); | ||
| 139 | ct->payload.rff.fr_type = FC_TYPE_FCP; | ||
| 140 | if (lport->service_params & FCP_SPPF_INIT_FCN) | ||
| 141 | ct->payload.rff.fr_feat = FCP_FEAT_INIT; | ||
| 142 | if (lport->service_params & FCP_SPPF_TARG_FCN) | ||
| 143 | ct->payload.rff.fr_feat |= FCP_FEAT_TARG; | ||
| 144 | break; | ||
| 145 | |||
| 146 | case FC_NS_RNN_ID: | ||
| 132 | ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); | 147 | ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); |
| 133 | hton24(ct->payload.rn.fr_fid.fp_fid, | 148 | hton24(ct->payload.rn.fr_fid.fp_fid, |
| 134 | fc_host_port_id(lport->host)); | 149 | fc_host_port_id(lport->host)); |
| 135 | ct->payload.rft.fts = lport->fcts; | 150 | put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn); |
| 136 | put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn); | 151 | break; |
| 152 | |||
| 153 | case FC_NS_RSPN_ID: | ||
| 154 | len = strnlen(fc_host_symbolic_name(lport->host), 255); | ||
| 155 | ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len); | ||
| 156 | hton24(ct->payload.spn.fr_fid.fp_fid, | ||
| 157 | fc_host_port_id(lport->host)); | ||
| 158 | strncpy(ct->payload.spn.fr_name, | ||
| 159 | fc_host_symbolic_name(lport->host), len); | ||
| 160 | ct->payload.spn.fr_name_len = len; | ||
| 161 | break; | ||
| 162 | |||
| 163 | case FC_NS_RSNN_NN: | ||
| 164 | len = strnlen(fc_host_symbolic_name(lport->host), 255); | ||
| 165 | ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len); | ||
| 166 | put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn); | ||
| 167 | strncpy(ct->payload.snn.fr_name, | ||
| 168 | fc_host_symbolic_name(lport->host), len); | ||
| 169 | ct->payload.snn.fr_name_len = len; | ||
| 137 | break; | 170 | break; |
| 138 | 171 | ||
| 139 | default: | 172 | default: |
| @@ -198,6 +231,31 @@ static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp) | |||
| 198 | sp->sp_bb_data = htons((u16) lport->mfs); | 231 | sp->sp_bb_data = htons((u16) lport->mfs); |
| 199 | cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ | 232 | cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ |
| 200 | cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); | 233 | cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); |
| 234 | if (lport->does_npiv) | ||
| 235 | sp->sp_features = htons(FC_SP_FT_NPIV); | ||
| 236 | } | ||
| 237 | |||
| 238 | /** | ||
| 239 | * fc_fdisc_fill - Fill in a fdisc request frame. | ||
| 240 | */ | ||
| 241 | static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp) | ||
| 242 | { | ||
| 243 | struct fc_els_csp *sp; | ||
| 244 | struct fc_els_cssp *cp; | ||
| 245 | struct fc_els_flogi *fdisc; | ||
| 246 | |||
| 247 | fdisc = fc_frame_payload_get(fp, sizeof(*fdisc)); | ||
| 248 | memset(fdisc, 0, sizeof(*fdisc)); | ||
| 249 | fdisc->fl_cmd = (u8) ELS_FDISC; | ||
| 250 | put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn); | ||
| 251 | put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn); | ||
| 252 | sp = &fdisc->fl_csp; | ||
| 253 | sp->sp_hi_ver = 0x20; | ||
| 254 | sp->sp_lo_ver = 0x20; | ||
| 255 | sp->sp_bb_cred = htons(10); /* this gets set by gateway */ | ||
| 256 | sp->sp_bb_data = htons((u16) lport->mfs); | ||
| 257 | cp = &fdisc->fl_cssp[3 - 1]; /* class 3 parameters */ | ||
| 258 | cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); | ||
| 201 | } | 259 | } |
| 202 | 260 | ||
| 203 | /** | 261 | /** |
| @@ -296,6 +354,10 @@ static inline int fc_els_fill(struct fc_lport *lport, | |||
| 296 | fc_flogi_fill(lport, fp); | 354 | fc_flogi_fill(lport, fp); |
| 297 | break; | 355 | break; |
| 298 | 356 | ||
| 357 | case ELS_FDISC: | ||
| 358 | fc_fdisc_fill(lport, fp); | ||
| 359 | break; | ||
| 360 | |||
| 299 | case ELS_LOGO: | 361 | case ELS_LOGO: |
| 300 | fc_logo_fill(lport, fp); | 362 | fc_logo_fill(lport, fp); |
| 301 | break; | 363 | break; |
