Commit 1ea2c1daf4476ac798b1de8196f11dd36425b5ae

Authored by Neerav Parikh
Committed by James Bottomley
1 parent a9277e7783

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

Showing 2 changed files with 49 additions and 14 deletions Side-by-side Diff

drivers/scsi/libfc/fc_elsct.c
... ... @@ -56,8 +56,7 @@
56 56 rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type);
57 57 else {
58 58 /* CT requests */
59   - rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type);
60   - did = FC_FID_DIR_SERV;
  59 + rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type, &did);
61 60 }
62 61  
63 62 if (rc) {
include/scsi/fc_encode.h
... ... @@ -97,7 +97,9 @@
97 97 * returns pointer to ct request.
98 98 */
99 99 static 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 104 struct fc_ct_req *ct;
103 105 size_t ct_plen;
104 106  
... ... @@ -106,14 +108,14 @@
106 108 ct = fc_frame_payload_get(fp, ct_plen);
107 109 memset(ct, 0, ct_plen);
108 110 ct->hdr.ct_rev = FC_CT_REV;
109   - ct->hdr.ct_fs_type = FC_FST_DIR;
110   - ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE;
  111 + ct->hdr.ct_fs_type = fs_type;
  112 + ct->hdr.ct_fs_subtype = subtype;
111 113 ct->hdr.ct_cmd = htons((u16) op);
112 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 119 * @lport: local port.
118 120 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
119 121 * @fp: frame to contain payload.
... ... @@ -121,7 +123,7 @@
121 123 * @r_ctl: pointer to FC header R_CTL.
122 124 * @fh_type: pointer to FC-4 type.
123 125 */
124   -static inline int fc_ct_fill(struct fc_lport *lport,
  126 +static inline int fc_ct_ns_fill(struct fc_lport *lport,
125 127 u32 fc_id, struct fc_frame *fp,
126 128 unsigned int op, enum fc_rctl *r_ctl,
127 129 enum fc_fh_type *fh_type)
128 130  
129 131  
130 132  
... ... @@ -131,23 +133,28 @@
131 133  
132 134 switch (op) {
133 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 138 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
136 139 break;
137 140  
138 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 145 hton24(ct->payload.fid.fp_fid, fc_id);
141 146 break;
142 147  
143 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 151 hton24(ct->payload.rft.fid.fp_fid, lport->port_id);
146 152 ct->payload.rft.fts = lport->fcts;
147 153 break;
148 154  
149 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 158 hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id);
152 159 ct->payload.rff.fr_type = FC_TYPE_FCP;
153 160 if (lport->service_params & FCP_SPPF_INIT_FCN)
154 161  
... ... @@ -157,14 +164,16 @@
157 164 break;
158 165  
159 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 169 hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id);
162 170 put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
163 171 break;
164 172  
165 173 case FC_NS_RSPN_ID:
166 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 177 hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id);
169 178 strncpy(ct->payload.spn.fr_name,
170 179 fc_host_symbolic_name(lport->host), len);
... ... @@ -173,7 +182,8 @@
173 182  
174 183 case FC_NS_RSNN_NN:
175 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 187 put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
178 188 strncpy(ct->payload.snn.fr_name,
179 189 fc_host_symbolic_name(lport->host), len);
... ... @@ -188,6 +198,32 @@
188 198 return 0;
189 199 }
190 200  
  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 + */
  210 +static 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 +}
191 227 /**
192 228 * fc_plogi_fill - Fill in plogi request frame
193 229 */