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; |