提交 70d53b04 编写于 作者: J Joe Eykholt 提交者: James Bottomley

[SCSI] libfc: add hook to notify providers of local port changes

When an SCST provider is registered, it needs to know what
local ports are available for configuration as targets.

Add a notifier chain that is invoked when any local port
that is added or deleted.

Maintain a global list of local ports and add an
interator function that calls a given function for
every existing local port.  This is used when first
loading a provider.
Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
Signed-off-by: NRobert Love <robert.w.love@intel.com>
Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
上级 baf9fdf0
...@@ -36,6 +36,10 @@ module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR); ...@@ -36,6 +36,10 @@ module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
DEFINE_MUTEX(fc_prov_mutex); DEFINE_MUTEX(fc_prov_mutex);
static LIST_HEAD(fc_local_ports);
struct blocking_notifier_head fc_lport_notifier_head =
BLOCKING_NOTIFIER_INIT(fc_lport_notifier_head);
EXPORT_SYMBOL(fc_lport_notifier_head);
/* /*
* Providers which primarily send requests and PRLIs. * Providers which primarily send requests and PRLIs.
...@@ -228,6 +232,17 @@ void fc_fill_reply_hdr(struct fc_frame *fp, const struct fc_frame *in_fp, ...@@ -228,6 +232,17 @@ void fc_fill_reply_hdr(struct fc_frame *fp, const struct fc_frame *in_fp,
} }
EXPORT_SYMBOL(fc_fill_reply_hdr); EXPORT_SYMBOL(fc_fill_reply_hdr);
void fc_lport_iterate(void (*notify)(struct fc_lport *, void *), void *arg)
{
struct fc_lport *lport;
mutex_lock(&fc_prov_mutex);
list_for_each_entry(lport, &fc_local_ports, lport_list)
notify(lport, arg);
mutex_unlock(&fc_prov_mutex);
}
EXPORT_SYMBOL(fc_lport_iterate);
/** /**
* fc_fc4_register_provider() - register FC-4 upper-level provider. * fc_fc4_register_provider() - register FC-4 upper-level provider.
* @type: FC-4 type, such as FC_TYPE_FCP * @type: FC-4 type, such as FC_TYPE_FCP
...@@ -270,3 +285,29 @@ void fc_fc4_deregister_provider(enum fc_fh_type type, struct fc4_prov *prov) ...@@ -270,3 +285,29 @@ void fc_fc4_deregister_provider(enum fc_fh_type type, struct fc4_prov *prov)
synchronize_rcu(); synchronize_rcu();
} }
EXPORT_SYMBOL(fc_fc4_deregister_provider); EXPORT_SYMBOL(fc_fc4_deregister_provider);
/**
* fc_fc4_add_lport() - add new local port to list and run notifiers.
* @lport: The new local port.
*/
void fc_fc4_add_lport(struct fc_lport *lport)
{
mutex_lock(&fc_prov_mutex);
list_add_tail(&lport->lport_list, &fc_local_ports);
blocking_notifier_call_chain(&fc_lport_notifier_head,
FC_LPORT_EV_ADD, lport);
mutex_unlock(&fc_prov_mutex);
}
/**
* fc_fc4_del_lport() - remove local port from list and run notifiers.
* @lport: The new local port.
*/
void fc_fc4_del_lport(struct fc_lport *lport)
{
mutex_lock(&fc_prov_mutex);
list_del(&lport->lport_list);
blocking_notifier_call_chain(&fc_lport_notifier_head,
FC_LPORT_EV_DEL, lport);
mutex_unlock(&fc_prov_mutex);
}
...@@ -123,6 +123,8 @@ void fc_destroy_fcp(void); ...@@ -123,6 +123,8 @@ void fc_destroy_fcp(void);
* Internal libfc functions * Internal libfc functions
*/ */
const char *fc_els_resp_type(struct fc_frame *); const char *fc_els_resp_type(struct fc_frame *);
extern void fc_fc4_add_lport(struct fc_lport *);
extern void fc_fc4_del_lport(struct fc_lport *);
/* /*
* Copies a buffer into an sg list * Copies a buffer into an sg list
......
...@@ -633,6 +633,7 @@ int fc_lport_destroy(struct fc_lport *lport) ...@@ -633,6 +633,7 @@ int fc_lport_destroy(struct fc_lport *lport)
lport->tt.fcp_abort_io(lport); lport->tt.fcp_abort_io(lport);
lport->tt.disc_stop_final(lport); lport->tt.disc_stop_final(lport);
lport->tt.exch_mgr_reset(lport, 0, 0); lport->tt.exch_mgr_reset(lport, 0, 0);
fc_fc4_del_lport(lport);
return 0; return 0;
} }
EXPORT_SYMBOL(fc_lport_destroy); EXPORT_SYMBOL(fc_lport_destroy);
...@@ -1633,6 +1634,7 @@ int fc_lport_init(struct fc_lport *lport) ...@@ -1633,6 +1634,7 @@ int fc_lport_init(struct fc_lport *lport)
fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT; fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT;
if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT) if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT; fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
fc_fc4_add_lport(lport);
return 0; return 0;
} }
......
...@@ -763,6 +763,15 @@ struct fc_disc { ...@@ -763,6 +763,15 @@ struct fc_disc {
enum fc_disc_event); enum fc_disc_event);
}; };
/*
* Local port notifier and events.
*/
extern struct blocking_notifier_head fc_lport_notifier_head;
enum fc_lport_event {
FC_LPORT_EV_ADD,
FC_LPORT_EV_DEL,
};
/** /**
* struct fc_lport - Local port * struct fc_lport - Local port
* @host: The SCSI host associated with a local port * @host: The SCSI host associated with a local port
...@@ -803,9 +812,10 @@ struct fc_disc { ...@@ -803,9 +812,10 @@ struct fc_disc {
* @lso_max: The maximum large offload send size * @lso_max: The maximum large offload send size
* @fcts: FC-4 type mask * @fcts: FC-4 type mask
* @lp_mutex: Mutex to protect the local port * @lp_mutex: Mutex to protect the local port
* @list: Handle for list of local ports * @list: Linkage on list of vport peers
* @retry_work: Handle to local port for delayed retry context * @retry_work: Handle to local port for delayed retry context
* @prov: Pointers available for use by passive FC-4 providers * @prov: Pointers available for use by passive FC-4 providers
* @lport_list: Linkage on module-wide list of local ports
*/ */
struct fc_lport { struct fc_lport {
/* Associations */ /* Associations */
...@@ -862,6 +872,7 @@ struct fc_lport { ...@@ -862,6 +872,7 @@ struct fc_lport {
struct list_head list; struct list_head list;
struct delayed_work retry_work; struct delayed_work retry_work;
void *prov[FC_FC4_PROV_SIZE]; void *prov[FC_FC4_PROV_SIZE];
struct list_head lport_list;
}; };
/** /**
...@@ -1016,6 +1027,7 @@ struct fc_lport *libfc_vport_create(struct fc_vport *, int privsize); ...@@ -1016,6 +1027,7 @@ struct fc_lport *libfc_vport_create(struct fc_vport *, int privsize);
struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id); struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id);
int fc_lport_bsg_request(struct fc_bsg_job *); int fc_lport_bsg_request(struct fc_bsg_job *);
void fc_lport_set_local_id(struct fc_lport *, u32 port_id); void fc_lport_set_local_id(struct fc_lport *, u32 port_id);
void fc_lport_iterate(void (*func)(struct fc_lport *, void *), void *);
/* /*
* REMOTE PORT LAYER * REMOTE PORT LAYER
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册