aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libfc/fc_libfc.c41
-rw-r--r--drivers/scsi/libfc/fc_libfc.h2
-rw-r--r--drivers/scsi/libfc/fc_lport.c2
-rw-r--r--include/scsi/libfc.h14
4 files changed, 58 insertions, 1 deletions
diff --git a/drivers/scsi/libfc/fc_libfc.c b/drivers/scsi/libfc/fc_libfc.c
index ae3abef6523e..5e40dab8f919 100644
--- a/drivers/scsi/libfc/fc_libfc.c
+++ b/drivers/scsi/libfc/fc_libfc.c
@@ -36,6 +36,10 @@ module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR);
36MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); 36MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
37 37
38DEFINE_MUTEX(fc_prov_mutex); 38DEFINE_MUTEX(fc_prov_mutex);
39static LIST_HEAD(fc_local_ports);
40struct blocking_notifier_head fc_lport_notifier_head =
41 BLOCKING_NOTIFIER_INIT(fc_lport_notifier_head);
42EXPORT_SYMBOL(fc_lport_notifier_head);
39 43
40/* 44/*
41 * Providers which primarily send requests and PRLIs. 45 * 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} 232}
229EXPORT_SYMBOL(fc_fill_reply_hdr); 233EXPORT_SYMBOL(fc_fill_reply_hdr);
230 234
235void fc_lport_iterate(void (*notify)(struct fc_lport *, void *), void *arg)
236{
237 struct fc_lport *lport;
238
239 mutex_lock(&fc_prov_mutex);
240 list_for_each_entry(lport, &fc_local_ports, lport_list)
241 notify(lport, arg);
242 mutex_unlock(&fc_prov_mutex);
243}
244EXPORT_SYMBOL(fc_lport_iterate);
245
231/** 246/**
232 * fc_fc4_register_provider() - register FC-4 upper-level provider. 247 * fc_fc4_register_provider() - register FC-4 upper-level provider.
233 * @type: FC-4 type, such as FC_TYPE_FCP 248 * @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 synchronize_rcu(); 285 synchronize_rcu();
271} 286}
272EXPORT_SYMBOL(fc_fc4_deregister_provider); 287EXPORT_SYMBOL(fc_fc4_deregister_provider);
288
289/**
290 * fc_fc4_add_lport() - add new local port to list and run notifiers.
291 * @lport: The new local port.
292 */
293void fc_fc4_add_lport(struct fc_lport *lport)
294{
295 mutex_lock(&fc_prov_mutex);
296 list_add_tail(&lport->lport_list, &fc_local_ports);
297 blocking_notifier_call_chain(&fc_lport_notifier_head,
298 FC_LPORT_EV_ADD, lport);
299 mutex_unlock(&fc_prov_mutex);
300}
301
302/**
303 * fc_fc4_del_lport() - remove local port from list and run notifiers.
304 * @lport: The new local port.
305 */
306void fc_fc4_del_lport(struct fc_lport *lport)
307{
308 mutex_lock(&fc_prov_mutex);
309 list_del(&lport->lport_list);
310 blocking_notifier_call_chain(&fc_lport_notifier_head,
311 FC_LPORT_EV_DEL, lport);
312 mutex_unlock(&fc_prov_mutex);
313}
diff --git a/drivers/scsi/libfc/fc_libfc.h b/drivers/scsi/libfc/fc_libfc.h
index 205de285e456..8496f7020b97 100644
--- a/drivers/scsi/libfc/fc_libfc.h
+++ b/drivers/scsi/libfc/fc_libfc.h
@@ -123,6 +123,8 @@ void fc_destroy_fcp(void);
123 * Internal libfc functions 123 * Internal libfc functions
124 */ 124 */
125const char *fc_els_resp_type(struct fc_frame *); 125const char *fc_els_resp_type(struct fc_frame *);
126extern void fc_fc4_add_lport(struct fc_lport *);
127extern void fc_fc4_del_lport(struct fc_lport *);
126 128
127/* 129/*
128 * Copies a buffer into an sg list 130 * Copies a buffer into an sg list
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index e2cd087e71b2..e0ef81426c33 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -633,6 +633,7 @@ int fc_lport_destroy(struct fc_lport *lport)
633 lport->tt.fcp_abort_io(lport); 633 lport->tt.fcp_abort_io(lport);
634 lport->tt.disc_stop_final(lport); 634 lport->tt.disc_stop_final(lport);
635 lport->tt.exch_mgr_reset(lport, 0, 0); 635 lport->tt.exch_mgr_reset(lport, 0, 0);
636 fc_fc4_del_lport(lport);
636 return 0; 637 return 0;
637} 638}
638EXPORT_SYMBOL(fc_lport_destroy); 639EXPORT_SYMBOL(fc_lport_destroy);
@@ -1633,6 +1634,7 @@ int fc_lport_init(struct fc_lport *lport)
1633 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT; 1634 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT;
1634 if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT) 1635 if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
1635 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT; 1636 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
1637 fc_fc4_add_lport(lport);
1636 1638
1637 return 0; 1639 return 0;
1638} 1640}
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index a9aff25a399b..79d1c76b4269 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -763,6 +763,15 @@ struct fc_disc {
763 enum fc_disc_event); 763 enum fc_disc_event);
764}; 764};
765 765
766/*
767 * Local port notifier and events.
768 */
769extern struct blocking_notifier_head fc_lport_notifier_head;
770enum fc_lport_event {
771 FC_LPORT_EV_ADD,
772 FC_LPORT_EV_DEL,
773};
774
766/** 775/**
767 * struct fc_lport - Local port 776 * struct fc_lport - Local port
768 * @host: The SCSI host associated with a local port 777 * @host: The SCSI host associated with a local port
@@ -803,9 +812,10 @@ struct fc_disc {
803 * @lso_max: The maximum large offload send size 812 * @lso_max: The maximum large offload send size
804 * @fcts: FC-4 type mask 813 * @fcts: FC-4 type mask
805 * @lp_mutex: Mutex to protect the local port 814 * @lp_mutex: Mutex to protect the local port
806 * @list: Handle for list of local ports 815 * @list: Linkage on list of vport peers
807 * @retry_work: Handle to local port for delayed retry context 816 * @retry_work: Handle to local port for delayed retry context
808 * @prov: Pointers available for use by passive FC-4 providers 817 * @prov: Pointers available for use by passive FC-4 providers
818 * @lport_list: Linkage on module-wide list of local ports
809 */ 819 */
810struct fc_lport { 820struct fc_lport {
811 /* Associations */ 821 /* Associations */
@@ -862,6 +872,7 @@ struct fc_lport {
862 struct list_head list; 872 struct list_head list;
863 struct delayed_work retry_work; 873 struct delayed_work retry_work;
864 void *prov[FC_FC4_PROV_SIZE]; 874 void *prov[FC_FC4_PROV_SIZE];
875 struct list_head lport_list;
865}; 876};
866 877
867/** 878/**
@@ -1016,6 +1027,7 @@ struct fc_lport *libfc_vport_create(struct fc_vport *, int privsize);
1016struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id); 1027struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id);
1017int fc_lport_bsg_request(struct fc_bsg_job *); 1028int fc_lport_bsg_request(struct fc_bsg_job *);
1018void fc_lport_set_local_id(struct fc_lport *, u32 port_id); 1029void fc_lport_set_local_id(struct fc_lport *, u32 port_id);
1030void fc_lport_iterate(void (*func)(struct fc_lport *, void *), void *);
1019 1031
1020/* 1032/*
1021 * REMOTE PORT LAYER 1033 * REMOTE PORT LAYER