diff options
-rw-r--r-- | drivers/scsi/libfc/fc_libfc.c | 41 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_libfc.h | 2 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 2 | ||||
-rw-r--r-- | include/scsi/libfc.h | 14 |
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); | |||
36 | MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); | 36 | MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); |
37 | 37 | ||
38 | DEFINE_MUTEX(fc_prov_mutex); | 38 | DEFINE_MUTEX(fc_prov_mutex); |
39 | static LIST_HEAD(fc_local_ports); | ||
40 | struct blocking_notifier_head fc_lport_notifier_head = | ||
41 | BLOCKING_NOTIFIER_INIT(fc_lport_notifier_head); | ||
42 | EXPORT_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 | } |
229 | EXPORT_SYMBOL(fc_fill_reply_hdr); | 233 | EXPORT_SYMBOL(fc_fill_reply_hdr); |
230 | 234 | ||
235 | void 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 | } | ||
244 | EXPORT_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 | } |
272 | EXPORT_SYMBOL(fc_fc4_deregister_provider); | 287 | EXPORT_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 | */ | ||
293 | void 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 | */ | ||
306 | void 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 | */ |
125 | const char *fc_els_resp_type(struct fc_frame *); | 125 | const char *fc_els_resp_type(struct fc_frame *); |
126 | extern void fc_fc4_add_lport(struct fc_lport *); | ||
127 | extern 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 | } |
638 | EXPORT_SYMBOL(fc_lport_destroy); | 639 | EXPORT_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 | */ | ||
769 | extern struct blocking_notifier_head fc_lport_notifier_head; | ||
770 | enum 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 | */ |
810 | struct fc_lport { | 820 | struct 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); | |||
1016 | struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id); | 1027 | struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id); |
1017 | int fc_lport_bsg_request(struct fc_bsg_job *); | 1028 | int fc_lport_bsg_request(struct fc_bsg_job *); |
1018 | void fc_lport_set_local_id(struct fc_lport *, u32 port_id); | 1029 | void fc_lport_set_local_id(struct fc_lport *, u32 port_id); |
1030 | void fc_lport_iterate(void (*func)(struct fc_lport *, void *), void *); | ||
1019 | 1031 | ||
1020 | /* | 1032 | /* |
1021 | * REMOTE PORT LAYER | 1033 | * REMOTE PORT LAYER |