From 96ad846445ae33dcae1805b68752e3d5c840e3ed Mon Sep 17 00:00:00 2001 From: Joe Eykholt Date: Fri, 28 Jan 2011 16:04:02 -0800 Subject: [SCSI] libfc: add hook for FC-4 provider registration Allow FC-4 provider modules to hook into libfc, mostly for targets. This should allow any FC-4 module to handle PRLI requests and maintain process-association states. Each provider registers its ops with libfc and then will be called for any incoming PRLI for that FC-4 type on any instance. The provider can decide whether to handle that particular instance using any method it likes, such as ACLs or other configuration information. A count is kept of the number of successful PRLIs from the remote port. Providers are called back with an implicit PRLO when the remote port is about to be deleted or has been reset. fc_lport_recv_req() now sends incoming FC-4 requests to FC-4 providers, and there is a built-in provider always registered for handling incoming ELS requests. The call to provider recv() routines uses rcu_read_lock() so that providers aren't removed during the call. That lock is very cheap and shouldn't affect any performance on ELS requests. Providers can rely on the RCU lock to protect a session lookup as well. Signed-off-by: Joe Eykholt Signed-off-by: Robert Love Signed-off-by: James Bottomley --- include/scsi/libfc.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include/scsi/libfc.h') diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index f53c8e31d5fb..3ae2a760b4f3 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -35,6 +35,8 @@ #include +#define FC_FC4_PROV_SIZE (FC_TYPE_FCP + 1) /* size of tables */ + /* * libfc error codes */ @@ -179,6 +181,7 @@ struct fc_rport_libfc_priv { * @rp_mutex: The mutex that protects the remote port * @retry_work: Handle for retries * @event_callback: Callback when READY, FAILED or LOGO states complete + * @prli_count: Count of open PRLI sessions in providers * @rcu: Structure used for freeing in an RCU-safe manner */ struct fc_rport_priv { @@ -202,6 +205,7 @@ struct fc_rport_priv { struct list_head peers; struct work_struct event_work; u32 supported_classes; + u16 prli_count; struct rcu_head rcu; }; @@ -848,6 +852,28 @@ struct fc_lport { struct delayed_work retry_work; }; +/** + * struct fc4_prov - FC-4 provider registration + * @prli: Handler for incoming PRLI + * @prlo: Handler for session reset + * @recv: Handler for incoming request + * @module: Pointer to module. May be NULL. + */ +struct fc4_prov { + int (*prli)(struct fc_rport_priv *, u32 spp_len, + const struct fc_els_spp *spp_in, + struct fc_els_spp *spp_out); + void (*prlo)(struct fc_rport_priv *); + void (*recv)(struct fc_lport *, struct fc_frame *); + struct module *module; +}; + +/* + * Register FC-4 provider with libfc. + */ +int fc_fc4_register_provider(enum fc_fh_type type, struct fc4_prov *); +void fc_fc4_deregister_provider(enum fc_fh_type type, struct fc4_prov *); + /* * FC_LPORT HELPER FUNCTIONS *****************************/ -- cgit v1.2.3