Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75a2792d authored by Bhanu Prakash Gollapudi's avatar Bhanu Prakash Gollapudi Committed by James Bottomley
Browse files

[SCSI] libfc: introduce LLD event callback



This patch enables LLD to listen to rport events and perform LLD
specific operations based on the rport event. This patch also stores
sp_features and spp_type in rdata for further reference by LLD.

Signed-off-by: default avatarBhanu Prakash Gollapudi <bprakash@broadcom.com>
Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent acc1a921
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -86,6 +86,7 @@ struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id)


	return lport;
	return lport;
}
}
EXPORT_SYMBOL(fc_vport_id_lookup);


/*
/*
 * When setting the link state of vports during an lport state change, it's
 * When setting the link state of vports during an lport state change, it's
+18 −1
Original line number Original line Diff line number Diff line
@@ -145,8 +145,10 @@ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport,
	rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
	rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
	INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
	INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
	INIT_WORK(&rdata->event_work, fc_rport_work);
	INIT_WORK(&rdata->event_work, fc_rport_work);
	if (port_id != FC_FID_DIR_SERV)
	if (port_id != FC_FID_DIR_SERV) {
		rdata->lld_event_callback = lport->tt.rport_event_callback;
		list_add_rcu(&rdata->peers, &lport->disc.rports);
		list_add_rcu(&rdata->peers, &lport->disc.rports);
	}
	return rdata;
	return rdata;
}
}


@@ -302,6 +304,10 @@ static void fc_rport_work(struct work_struct *work)
			FC_RPORT_DBG(rdata, "callback ev %d\n", event);
			FC_RPORT_DBG(rdata, "callback ev %d\n", event);
			rport_ops->event_callback(lport, rdata, event);
			rport_ops->event_callback(lport, rdata, event);
		}
		}
		if (rdata->lld_event_callback) {
			FC_RPORT_DBG(rdata, "lld callback ev %d\n", event);
			rdata->lld_event_callback(lport, rdata, event);
		}
		kref_put(&rdata->kref, lport->tt.rport_destroy);
		kref_put(&rdata->kref, lport->tt.rport_destroy);
		break;
		break;


@@ -324,6 +330,10 @@ static void fc_rport_work(struct work_struct *work)
			FC_RPORT_DBG(rdata, "callback ev %d\n", event);
			FC_RPORT_DBG(rdata, "callback ev %d\n", event);
			rport_ops->event_callback(lport, rdata, event);
			rport_ops->event_callback(lport, rdata, event);
		}
		}
		if (rdata->lld_event_callback) {
			FC_RPORT_DBG(rdata, "lld callback ev %d\n", event);
			rdata->lld_event_callback(lport, rdata, event);
		}
		cancel_delayed_work_sync(&rdata->retry_work);
		cancel_delayed_work_sync(&rdata->retry_work);


		/*
		/*
@@ -890,6 +900,9 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
		rdata->ids.port_name = get_unaligned_be64(&plp->fl_wwpn);
		rdata->ids.port_name = get_unaligned_be64(&plp->fl_wwpn);
		rdata->ids.node_name = get_unaligned_be64(&plp->fl_wwnn);
		rdata->ids.node_name = get_unaligned_be64(&plp->fl_wwnn);


		/* save plogi response sp_features for further reference */
		rdata->sp_features = ntohs(plp->fl_csp.sp_features);

		if (lport->point_to_multipoint)
		if (lport->point_to_multipoint)
			fc_rport_login_complete(rdata, fp);
			fc_rport_login_complete(rdata, fp);
		csp_seq = ntohs(plp->fl_csp.sp_tot_seq);
		csp_seq = ntohs(plp->fl_csp.sp_tot_seq);
@@ -997,6 +1010,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
		resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK);
		resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK);
		FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x\n",
		FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x\n",
			     pp->spp.spp_flags);
			     pp->spp.spp_flags);
		rdata->spp_type = pp->spp.spp_type;
		if (resp_code != FC_SPP_RESP_ACK) {
		if (resp_code != FC_SPP_RESP_ACK) {
			if (resp_code == FC_SPP_RESP_CONF)
			if (resp_code == FC_SPP_RESP_CONF)
				fc_rport_error(rdata, fp);
				fc_rport_error(rdata, fp);
@@ -1010,6 +1024,8 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
		fcp_parm = ntohl(pp->spp.spp_params);
		fcp_parm = ntohl(pp->spp.spp_params);
		if (fcp_parm & FCP_SPPF_RETRY)
		if (fcp_parm & FCP_SPPF_RETRY)
			rdata->flags |= FC_RP_FLAGS_RETRY;
			rdata->flags |= FC_RP_FLAGS_RETRY;
		if (fcp_parm & FCP_SPPF_CONF_COMPL)
			rdata->flags |= FC_RP_FLAGS_CONF_REQ;


		prov = fc_passive_prov[FC_TYPE_FCP];
		prov = fc_passive_prov[FC_TYPE_FCP];
		if (prov) {
		if (prov) {
@@ -1719,6 +1735,7 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
	spp = &pp->spp;
	spp = &pp->spp;
	mutex_lock(&fc_prov_mutex);
	mutex_lock(&fc_prov_mutex);
	while (len >= plen) {
	while (len >= plen) {
		rdata->spp_type = rspp->spp_type;
		spp->spp_type = rspp->spp_type;
		spp->spp_type = rspp->spp_type;
		spp->spp_type_ext = rspp->spp_type_ext;
		spp->spp_type_ext = rspp->spp_type_ext;
		resp = 0;
		resp = 0;
+15 −0
Original line number Original line Diff line number Diff line
@@ -158,6 +158,7 @@ struct fc_rport_libfc_priv {
	#define FC_RP_FLAGS_REC_SUPPORTED	(1 << 0)
	#define FC_RP_FLAGS_REC_SUPPORTED	(1 << 0)
	#define FC_RP_FLAGS_RETRY		(1 << 1)
	#define FC_RP_FLAGS_RETRY		(1 << 1)
	#define FC_RP_STARTED			(1 << 2)
	#define FC_RP_STARTED			(1 << 2)
	#define FC_RP_FLAGS_CONF_REQ		(1 << 3)
	unsigned int	           e_d_tov;
	unsigned int	           e_d_tov;
	unsigned int	           r_a_tov;
	unsigned int	           r_a_tov;
};
};
@@ -207,6 +208,11 @@ struct fc_rport_priv {
	u32			    supported_classes;
	u32			    supported_classes;
	u16                         prli_count;
	u16                         prli_count;
	struct rcu_head		    rcu;
	struct rcu_head		    rcu;
	u16			    sp_features;
	u8			    spp_type;
	void			    (*lld_event_callback)(struct fc_lport *,
						      struct fc_rport_priv *,
						      enum fc_rport_event);
};
};


/**
/**
@@ -676,6 +682,15 @@ struct libfc_function_template {
	 */
	 */
	void (*rport_destroy)(struct kref *);
	void (*rport_destroy)(struct kref *);


	/*
	 * Callback routine after the remote port is logged in
	 *
	 * STATUS: OPTIONAL
	 */
	void (*rport_event_callback)(struct fc_lport *,
				     struct fc_rport_priv *,
				     enum fc_rport_event);

	/*
	/*
	 * Send a fcp cmd from fsp pkt.
	 * Send a fcp cmd from fsp pkt.
	 * Called with the SCSI host lock unlocked and irqs disabled.
	 * Called with the SCSI host lock unlocked and irqs disabled.