connector: Delete buggy notification code.
[safe/jmp/linux-2.6] / include / scsi / fc_encode.h
index a0ff61c..8eb0a0f 100644 (file)
@@ -32,6 +32,10 @@ struct fc_ct_req {
                struct fc_ns_gid_ft gid;
                struct fc_ns_rn_id  rn;
                struct fc_ns_rft rft;
+               struct fc_ns_rff_id rff;
+               struct fc_ns_fid fid;
+               struct fc_ns_rsnn snn;
+               struct fc_ns_rspn spn;
        } payload;
 };
 
@@ -57,6 +61,23 @@ static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
 }
 
 /**
+ * fc_adisc_fill() - Fill in adisc request frame
+ * @lport: local port.
+ * @fp: fc frame where payload will be placed.
+ */
+static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
+{
+       struct fc_els_adisc *adisc;
+
+       adisc = fc_frame_payload_get(fp, sizeof(*adisc));
+       memset(adisc, 0, sizeof(*adisc));
+       adisc->adisc_cmd = ELS_ADISC;
+       put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
+       put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
+       hton24(adisc->adisc_port_id, fc_host_port_id(lport->host));
+}
+
+/**
  * fc_ct_hdr_fill- fills ct header and reset ct payload
  * returns pointer to ct request.
  */
@@ -77,13 +98,21 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
 }
 
 /**
- * fc_ct_fill - Fill in a name service request frame
+ * fc_ct_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.
+ * @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, struct fc_frame *fp,
-                     unsigned int op, enum fc_rctl *r_ctl, u32 *did,
+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)
 {
        struct fc_ct_req *ct;
+       size_t len;
 
        switch (op) {
        case FC_NS_GPN_FT:
@@ -91,6 +120,11 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
                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));
+               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));
                hton24(ct->payload.rft.fid.fp_fid,
@@ -98,19 +132,47 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
                ct->payload.rft.fts = lport->fcts;
                break;
 
-       case FC_NS_RPN_ID:
+       case FC_NS_RFF_ID:
+               ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id));
+               hton24(ct->payload.rff.fr_fid.fp_fid,
+                      fc_host_port_id(lport->host));
+               ct->payload.rff.fr_type = FC_TYPE_FCP;
+               if (lport->service_params & FCP_SPPF_INIT_FCN)
+                       ct->payload.rff.fr_feat = FCP_FEAT_INIT;
+               if (lport->service_params & FCP_SPPF_TARG_FCN)
+                       ct->payload.rff.fr_feat |= FCP_FEAT_TARG;
+               break;
+
+       case FC_NS_RNN_ID:
                ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id));
                hton24(ct->payload.rn.fr_fid.fp_fid,
                       fc_host_port_id(lport->host));
-               ct->payload.rft.fts = lport->fcts;
-               put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn);
+               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);
+               hton24(ct->payload.spn.fr_fid.fp_fid,
+                      fc_host_port_id(lport->host));
+               strncpy(ct->payload.spn.fr_name,
+                       fc_host_symbolic_name(lport->host), len);
+               ct->payload.spn.fr_name_len = len;
+               break;
+
+       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);
+               put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
+               strncpy(ct->payload.snn.fr_name,
+                       fc_host_symbolic_name(lport->host), len);
+               ct->payload.snn.fr_name_len = len;
                break;
 
        default:
                return -EINVAL;
        }
        *r_ctl = FC_RCTL_DD_UNSOL_CTL;
-       *did = FC_FID_DIR_SERV;
        *fh_type = FC_TYPE_CT;
        return 0;
 }
@@ -169,6 +231,31 @@ static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
        sp->sp_bb_data = htons((u16) lport->mfs);
        cp = &flogi->fl_cssp[3 - 1];    /* class 3 parameters */
        cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
+       if (lport->does_npiv)
+               sp->sp_features = htons(FC_SP_FT_NPIV);
+}
+
+/**
+ * fc_fdisc_fill - Fill in a fdisc request frame.
+ */
+static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
+{
+       struct fc_els_csp *sp;
+       struct fc_els_cssp *cp;
+       struct fc_els_flogi *fdisc;
+
+       fdisc = fc_frame_payload_get(fp, sizeof(*fdisc));
+       memset(fdisc, 0, sizeof(*fdisc));
+       fdisc->fl_cmd = (u8) ELS_FDISC;
+       put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn);
+       put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn);
+       sp = &fdisc->fl_csp;
+       sp->sp_hi_ver = 0x20;
+       sp->sp_lo_ver = 0x20;
+       sp->sp_bb_cred = htons(10);     /* this gets set by gateway */
+       sp->sp_bb_data = htons((u16) lport->mfs);
+       cp = &fdisc->fl_cssp[3 - 1];    /* class 3 parameters */
+       cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
 }
 
 /**
@@ -249,51 +336,46 @@ static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
 /**
  * fc_els_fill - Fill in an ELS  request frame
  */
-static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport,
+static inline int fc_els_fill(struct fc_lport *lport,
+                      u32 did,
                       struct fc_frame *fp, unsigned int op,
-                      enum fc_rctl *r_ctl, u32 *did, enum fc_fh_type *fh_type)
+                      enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
 {
        switch (op) {
+       case ELS_ADISC:
+               fc_adisc_fill(lport, fp);
+               break;
+
        case ELS_PLOGI:
                fc_plogi_fill(lport, fp, ELS_PLOGI);
-               *did = rport->port_id;
                break;
 
        case ELS_FLOGI:
                fc_flogi_fill(lport, fp);
-               *did = FC_FID_FLOGI;
+               break;
+
+       case ELS_FDISC:
+               fc_fdisc_fill(lport, fp);
                break;
 
        case ELS_LOGO:
                fc_logo_fill(lport, fp);
-               *did = FC_FID_FLOGI;
-               /*
-                * if rport is valid then it
-                * is port logo, therefore
-                * set did to rport id.
-                */
-               if (rport)
-                       *did = rport->port_id;
                break;
 
        case ELS_RTV:
                fc_rtv_fill(lport, fp);
-               *did = rport->port_id;
                break;
 
        case ELS_REC:
                fc_rec_fill(lport, fp);
-               *did = rport->port_id;
                break;
 
        case ELS_PRLI:
                fc_prli_fill(lport, fp);
-               *did = rport->port_id;
                break;
 
        case ELS_SCR:
                fc_scr_fill(lport, fp);
-               *did = FC_FID_FCTRL;
                break;
 
        default: