aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libfc/fc_elsct.c3
-rw-r--r--include/scsi/fc_encode.h60
2 files changed, 49 insertions, 14 deletions
diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
index e17a28d324d0..c2384d501470 100644
--- a/drivers/scsi/libfc/fc_elsct.c
+++ b/drivers/scsi/libfc/fc_elsct.c
@@ -56,8 +56,7 @@ struct fc_seq *fc_elsct_send(struct fc_lport *lport, u32 did,
56 rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type); 56 rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type);
57 else { 57 else {
58 /* CT requests */ 58 /* CT requests */
59 rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type); 59 rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type, &did);
60 did = FC_FID_DIR_SERV;
61 } 60 }
62 61
63 if (rc) { 62 if (rc) {
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
index be418d8448a5..73bc43329f86 100644
--- a/include/scsi/fc_encode.h
+++ b/include/scsi/fc_encode.h
@@ -97,7 +97,9 @@ static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
97 * returns pointer to ct request. 97 * returns pointer to ct request.
98 */ 98 */
99static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, 99static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
100 unsigned int op, size_t req_size) 100 unsigned int op, size_t req_size,
101 enum fc_ct_fs_type fs_type,
102 u8 subtype)
101{ 103{
102 struct fc_ct_req *ct; 104 struct fc_ct_req *ct;
103 size_t ct_plen; 105 size_t ct_plen;
@@ -106,14 +108,14 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
106 ct = fc_frame_payload_get(fp, ct_plen); 108 ct = fc_frame_payload_get(fp, ct_plen);
107 memset(ct, 0, ct_plen); 109 memset(ct, 0, ct_plen);
108 ct->hdr.ct_rev = FC_CT_REV; 110 ct->hdr.ct_rev = FC_CT_REV;
109 ct->hdr.ct_fs_type = FC_FST_DIR; 111 ct->hdr.ct_fs_type = fs_type;
110 ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE; 112 ct->hdr.ct_fs_subtype = subtype;
111 ct->hdr.ct_cmd = htons((u16) op); 113 ct->hdr.ct_cmd = htons((u16) op);
112 return ct; 114 return ct;
113} 115}
114 116
115/** 117/**
116 * fc_ct_fill() - Fill in a name service request frame 118 * fc_ct_ns_fill() - Fill in a name service request frame
117 * @lport: local port. 119 * @lport: local port.
118 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. 120 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
119 * @fp: frame to contain payload. 121 * @fp: frame to contain payload.
@@ -121,7 +123,7 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
121 * @r_ctl: pointer to FC header R_CTL. 123 * @r_ctl: pointer to FC header R_CTL.
122 * @fh_type: pointer to FC-4 type. 124 * @fh_type: pointer to FC-4 type.
123 */ 125 */
124static inline int fc_ct_fill(struct fc_lport *lport, 126static inline int fc_ct_ns_fill(struct fc_lport *lport,
125 u32 fc_id, struct fc_frame *fp, 127 u32 fc_id, struct fc_frame *fp,
126 unsigned int op, enum fc_rctl *r_ctl, 128 unsigned int op, enum fc_rctl *r_ctl,
127 enum fc_fh_type *fh_type) 129 enum fc_fh_type *fh_type)
@@ -131,23 +133,28 @@ static inline int fc_ct_fill(struct fc_lport *lport,
131 133
132 switch (op) { 134 switch (op) {
133 case FC_NS_GPN_FT: 135 case FC_NS_GPN_FT:
134 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft)); 136 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft),
137 FC_FST_DIR, FC_NS_SUBTYPE);
135 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; 138 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
136 break; 139 break;
137 140
138 case FC_NS_GPN_ID: 141 case FC_NS_GPN_ID:
139 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid)); 142 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid),
143 FC_FST_DIR, FC_NS_SUBTYPE);
144 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
140 hton24(ct->payload.fid.fp_fid, fc_id); 145 hton24(ct->payload.fid.fp_fid, fc_id);
141 break; 146 break;
142 147
143 case FC_NS_RFT_ID: 148 case FC_NS_RFT_ID:
144 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); 149 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft),
150 FC_FST_DIR, FC_NS_SUBTYPE);
145 hton24(ct->payload.rft.fid.fp_fid, lport->port_id); 151 hton24(ct->payload.rft.fid.fp_fid, lport->port_id);
146 ct->payload.rft.fts = lport->fcts; 152 ct->payload.rft.fts = lport->fcts;
147 break; 153 break;
148 154
149 case FC_NS_RFF_ID: 155 case FC_NS_RFF_ID:
150 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id)); 156 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id),
157 FC_FST_DIR, FC_NS_SUBTYPE);
151 hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id); 158 hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id);
152 ct->payload.rff.fr_type = FC_TYPE_FCP; 159 ct->payload.rff.fr_type = FC_TYPE_FCP;
153 if (lport->service_params & FCP_SPPF_INIT_FCN) 160 if (lport->service_params & FCP_SPPF_INIT_FCN)
@@ -157,14 +164,16 @@ static inline int fc_ct_fill(struct fc_lport *lport,
157 break; 164 break;
158 165
159 case FC_NS_RNN_ID: 166 case FC_NS_RNN_ID:
160 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); 167 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id),
168 FC_FST_DIR, FC_NS_SUBTYPE);
161 hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id); 169 hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id);
162 put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn); 170 put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
163 break; 171 break;
164 172
165 case FC_NS_RSPN_ID: 173 case FC_NS_RSPN_ID:
166 len = strnlen(fc_host_symbolic_name(lport->host), 255); 174 len = strnlen(fc_host_symbolic_name(lport->host), 255);
167 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len); 175 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len,
176 FC_FST_DIR, FC_NS_SUBTYPE);
168 hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id); 177 hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id);
169 strncpy(ct->payload.spn.fr_name, 178 strncpy(ct->payload.spn.fr_name,
170 fc_host_symbolic_name(lport->host), len); 179 fc_host_symbolic_name(lport->host), len);
@@ -173,7 +182,8 @@ static inline int fc_ct_fill(struct fc_lport *lport,
173 182
174 case FC_NS_RSNN_NN: 183 case FC_NS_RSNN_NN:
175 len = strnlen(fc_host_symbolic_name(lport->host), 255); 184 len = strnlen(fc_host_symbolic_name(lport->host), 255);
176 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len); 185 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len,
186 FC_FST_DIR, FC_NS_SUBTYPE);
177 put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn); 187 put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
178 strncpy(ct->payload.snn.fr_name, 188 strncpy(ct->payload.snn.fr_name,
179 fc_host_symbolic_name(lport->host), len); 189 fc_host_symbolic_name(lport->host), len);
@@ -189,6 +199,32 @@ static inline int fc_ct_fill(struct fc_lport *lport,
189} 199}
190 200
191/** 201/**
202 * fc_ct_fill() - Fill in a common transport service request frame
203 * @lport: local port.
204 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
205 * @fp: frame to contain payload.
206 * @op: CT opcode.
207 * @r_ctl: pointer to FC header R_CTL.
208 * @fh_type: pointer to FC-4 type.
209 */
210static inline int fc_ct_fill(struct fc_lport *lport,
211 u32 fc_id, struct fc_frame *fp,
212 unsigned int op, enum fc_rctl *r_ctl,
213 enum fc_fh_type *fh_type, u32 *did)
214{
215 int rc = -EINVAL;
216
217 switch (fc_id) {
218 case FC_FID_DIR_SERV:
219 default:
220 rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type);
221 *did = FC_FID_DIR_SERV;
222 break;
223 }
224
225 return rc;
226}
227/**
192 * fc_plogi_fill - Fill in plogi request frame 228 * fc_plogi_fill - Fill in plogi request frame
193 */ 229 */
194static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp, 230static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,