aboutsummaryrefslogtreecommitdiffstats
path: root/include/scsi
diff options
context:
space:
mode:
authorNeerav Parikh <neerav.parikh@intel.com>2012-01-22 20:30:00 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 09:08:58 -0500
commit1ea2c1daf4476ac798b1de8196f11dd36425b5ae (patch)
treede1d14fa0c5b912e22947b0e2177c0ee31b9ba4e /include/scsi
parenta9277e7783651d4e0a849f7988340b1c1cf748a4 (diff)
[SCSI] libfc: Make the libfc Common Transport(CT) code generic
Currently the libfc Common Transport(CT) calls assume that the CT requests are Name Server specific only. This patch makes it more flexible to allow more FC-GS services to make use of these routines. Signed-off-by: Neerav Parikh <neerav.parikh@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Acked-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/fc_encode.h60
1 files changed, 48 insertions, 12 deletions
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,