Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Neerav Parikh and committed by
James Bottomley
1ea2c1da a9277e77

+49 -14
+1 -2
drivers/scsi/libfc/fc_elsct.c
··· 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) {
+48 -12
include/scsi/fc_encode.h
··· 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; ··· 108 106 ct = fc_frame_payload_get(fp, ct_plen); 109 107 memset(ct, 0, ct_plen); 110 108 ct->hdr.ct_rev = FC_CT_REV; 111 - ct->hdr.ct_fs_type = FC_FST_DIR; 112 - ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE; 109 + ct->hdr.ct_fs_type = fs_type; 110 + ct->hdr.ct_fs_subtype = subtype; 113 111 ct->hdr.ct_cmd = htons((u16) op); 114 112 return ct; 115 113 } 116 114 117 115 /** 118 - * fc_ct_fill() - Fill in a name service request frame 116 + * fc_ct_ns_fill() - Fill in a name service request frame 119 117 * @lport: local port. 120 118 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. 121 119 * @fp: frame to contain payload. ··· 123 121 * @r_ctl: pointer to FC header R_CTL. 124 122 * @fh_type: pointer to FC-4 type. 125 123 */ 126 - static inline int fc_ct_fill(struct fc_lport *lport, 124 + static inline int fc_ct_ns_fill(struct fc_lport *lport, 127 125 u32 fc_id, struct fc_frame *fp, 128 126 unsigned int op, enum fc_rctl *r_ctl, 129 127 enum fc_fh_type *fh_type) ··· 133 131 134 132 switch (op) { 135 133 case FC_NS_GPN_FT: 136 - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft)); 134 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft), 135 + FC_FST_DIR, FC_NS_SUBTYPE); 137 136 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; 138 137 break; 139 138 140 139 case FC_NS_GPN_ID: 141 - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid)); 140 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid), 141 + FC_FST_DIR, FC_NS_SUBTYPE); 142 + ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; 142 143 hton24(ct->payload.fid.fp_fid, fc_id); 143 144 break; 144 145 145 146 case FC_NS_RFT_ID: 146 - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); 147 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft), 148 + FC_FST_DIR, FC_NS_SUBTYPE); 147 149 hton24(ct->payload.rft.fid.fp_fid, lport->port_id); 148 150 ct->payload.rft.fts = lport->fcts; 149 151 break; 150 152 151 153 case FC_NS_RFF_ID: 152 - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id)); 154 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id), 155 + FC_FST_DIR, FC_NS_SUBTYPE); 153 156 hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id); 154 157 ct->payload.rff.fr_type = FC_TYPE_FCP; 155 158 if (lport->service_params & FCP_SPPF_INIT_FCN) ··· 164 157 break; 165 158 166 159 case FC_NS_RNN_ID: 167 - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); 160 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id), 161 + FC_FST_DIR, FC_NS_SUBTYPE); 168 162 hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id); 169 163 put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn); 170 164 break; 171 165 172 166 case FC_NS_RSPN_ID: 173 167 len = strnlen(fc_host_symbolic_name(lport->host), 255); 174 - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len); 168 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len, 169 + FC_FST_DIR, FC_NS_SUBTYPE); 175 170 hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id); 176 171 strncpy(ct->payload.spn.fr_name, 177 172 fc_host_symbolic_name(lport->host), len); ··· 182 173 183 174 case FC_NS_RSNN_NN: 184 175 len = strnlen(fc_host_symbolic_name(lport->host), 255); 185 - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len); 176 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len, 177 + FC_FST_DIR, FC_NS_SUBTYPE); 186 178 put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn); 187 179 strncpy(ct->payload.snn.fr_name, 188 180 fc_host_symbolic_name(lport->host), len); ··· 198 188 return 0; 199 189 } 200 190 191 + /** 192 + * fc_ct_fill() - Fill in a common transport service request frame 193 + * @lport: local port. 194 + * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. 195 + * @fp: frame to contain payload. 196 + * @op: CT opcode. 197 + * @r_ctl: pointer to FC header R_CTL. 198 + * @fh_type: pointer to FC-4 type. 199 + */ 200 + static inline int fc_ct_fill(struct fc_lport *lport, 201 + u32 fc_id, struct fc_frame *fp, 202 + unsigned int op, enum fc_rctl *r_ctl, 203 + enum fc_fh_type *fh_type, u32 *did) 204 + { 205 + int rc = -EINVAL; 206 + 207 + switch (fc_id) { 208 + case FC_FID_DIR_SERV: 209 + default: 210 + rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type); 211 + *did = FC_FID_DIR_SERV; 212 + break; 213 + } 214 + 215 + return rc; 216 + } 201 217 /** 202 218 * fc_plogi_fill - Fill in plogi request frame 203 219 */