From 1ea2c1daf4476ac798b1de8196f11dd36425b5ae Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Sun, 22 Jan 2012 17:30:00 -0800 Subject: [PATCH] [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 Tested-by: Ross Brattain Acked-by: Robert Love Signed-off-by: James Bottomley --- drivers/scsi/libfc/fc_elsct.c | 3 +- include/scsi/fc_encode.h | 60 ++++++++++++++++++++++++++++------- 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, rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type); else { /* CT requests */ - rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type); - did = FC_FID_DIR_SERV; + rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type, &did); } 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) * returns pointer to ct request. */ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, - unsigned int op, size_t req_size) + unsigned int op, size_t req_size, + enum fc_ct_fs_type fs_type, + u8 subtype) { struct fc_ct_req *ct; size_t ct_plen; @@ -106,14 +108,14 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, ct = fc_frame_payload_get(fp, ct_plen); memset(ct, 0, ct_plen); ct->hdr.ct_rev = FC_CT_REV; - ct->hdr.ct_fs_type = FC_FST_DIR; - ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE; + ct->hdr.ct_fs_type = fs_type; + ct->hdr.ct_fs_subtype = subtype; ct->hdr.ct_cmd = htons((u16) op); return ct; } /** - * fc_ct_fill() - Fill in a name service request frame + * fc_ct_ns_fill() - Fill in a name service request frame * @lport: local port. * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. * @fp: frame to contain payload. @@ -121,7 +123,7 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, * @r_ctl: pointer to FC header R_CTL. * @fh_type: pointer to FC-4 type. */ -static inline int fc_ct_fill(struct fc_lport *lport, +static inline int fc_ct_ns_fill(struct fc_lport *lport, u32 fc_id, struct fc_frame *fp, unsigned int op, enum fc_rctl *r_ctl, enum fc_fh_type *fh_type) @@ -131,23 +133,28 @@ static inline int fc_ct_fill(struct fc_lport *lport, switch (op) { case FC_NS_GPN_FT: - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft)); + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft), + FC_FST_DIR, FC_NS_SUBTYPE); ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; break; case FC_NS_GPN_ID: - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid)); + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid), + FC_FST_DIR, FC_NS_SUBTYPE); + ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; hton24(ct->payload.fid.fp_fid, fc_id); break; case FC_NS_RFT_ID: - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft), + FC_FST_DIR, FC_NS_SUBTYPE); hton24(ct->payload.rft.fid.fp_fid, lport->port_id); ct->payload.rft.fts = lport->fcts; break; case FC_NS_RFF_ID: - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id)); + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id), + FC_FST_DIR, FC_NS_SUBTYPE); hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id); ct->payload.rff.fr_type = FC_TYPE_FCP; if (lport->service_params & FCP_SPPF_INIT_FCN) @@ -157,14 +164,16 @@ static inline int fc_ct_fill(struct fc_lport *lport, break; case FC_NS_RNN_ID: - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id), + FC_FST_DIR, FC_NS_SUBTYPE); hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id); put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn); break; case FC_NS_RSPN_ID: len = strnlen(fc_host_symbolic_name(lport->host), 255); - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len); + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len, + FC_FST_DIR, FC_NS_SUBTYPE); hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id); strncpy(ct->payload.spn.fr_name, fc_host_symbolic_name(lport->host), len); @@ -173,7 +182,8 @@ static inline int fc_ct_fill(struct fc_lport *lport, case FC_NS_RSNN_NN: len = strnlen(fc_host_symbolic_name(lport->host), 255); - ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len); + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len, + FC_FST_DIR, FC_NS_SUBTYPE); put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn); strncpy(ct->payload.snn.fr_name, fc_host_symbolic_name(lport->host), len); @@ -188,6 +198,32 @@ static inline int fc_ct_fill(struct fc_lport *lport, return 0; } +/** + * fc_ct_fill() - Fill in a common transport service request frame + * @lport: local port. + * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. + * @fp: frame to contain payload. + * @op: CT opcode. + * @r_ctl: pointer to FC header R_CTL. + * @fh_type: pointer to FC-4 type. + */ +static inline int fc_ct_fill(struct fc_lport *lport, + u32 fc_id, struct fc_frame *fp, + unsigned int op, enum fc_rctl *r_ctl, + enum fc_fh_type *fh_type, u32 *did) +{ + int rc = -EINVAL; + + switch (fc_id) { + case FC_FID_DIR_SERV: + default: + rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type); + *did = FC_FID_DIR_SERV; + break; + } + + return rc; +} /** * fc_plogi_fill - Fill in plogi request frame */ -- GitLab