150107Smsmith/*-
250107Smsmith * Copyright (c) 1999 Michael Smith <msmith@freebsd.org>
350107Smsmith * All rights reserved.
450107Smsmith *
550107Smsmith * Redistribution and use in source and binary forms, with or without
650107Smsmith * modification, are permitted provided that the following conditions
750107Smsmith * are met:
850107Smsmith * 1. Redistributions of source code must retain the above copyright
950107Smsmith *    notice, this list of conditions and the following disclaimer.
1050107Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1150107Smsmith *    notice, this list of conditions and the following disclaimer in the
1250107Smsmith *    documentation and/or other materials provided with the distribution.
1350107Smsmith *
1450107Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1550107Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1650107Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1750107Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1850107Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1950107Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2050107Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2150107Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2250107Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2350107Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2450107Smsmith * SUCH DAMAGE.
2550107Smsmith *
2650477Speter * $FreeBSD: stable/10/sys/sys/eventhandler.h 307253 2016-10-14 03:11:31Z sephe $
2750107Smsmith */
2850107Smsmith
2967535Sjhb#ifndef SYS_EVENTHANDLER_H
3067535Sjhb#define SYS_EVENTHANDLER_H
3167535Sjhb
3293615Salfred#include <sys/lock.h>
33112111Sjhb#include <sys/ktr.h>
34112111Sjhb#include <sys/mutex.h>
3550107Smsmith#include <sys/queue.h>
3650107Smsmith
3795193Smarkmstruct eventhandler_entry {
3895193Smarkm	TAILQ_ENTRY(eventhandler_entry)	ee_link;
3995193Smarkm	int				ee_priority;
40112111Sjhb#define	EHE_DEAD_PRIORITY	(-1)
4195193Smarkm	void				*ee_arg;
4250107Smsmith};
4350107Smsmith
44205345Sbz#ifdef VIMAGE
45205345Sbzstruct eventhandler_entry_vimage {
46205345Sbz	void	(* func)(void);		/* Original function registered. */
47205345Sbz	void	*ee_arg;		/* Original argument registered. */
48205345Sbz	void	*sparep[2];
49205345Sbz};
50205345Sbz#endif
51205345Sbz
5295193Smarkmstruct eventhandler_list {
5395193Smarkm	char				*el_name;
5495193Smarkm	int				el_flags;
55112111Sjhb#define EHL_INITTED	(1<<0)
56112111Sjhb	u_int				el_runcount;
57112111Sjhb	struct mtx			el_lock;
5895193Smarkm	TAILQ_ENTRY(eventhandler_list)	el_link;
5995193Smarkm	TAILQ_HEAD(,eventhandler_entry)	el_entries;
6050107Smsmith};
6150107Smsmith
6250107Smsmithtypedef struct eventhandler_entry	*eventhandler_tag;
6350107Smsmith
64112111Sjhb#define	EHL_LOCK(p)		mtx_lock(&(p)->el_lock)
65112111Sjhb#define	EHL_UNLOCK(p)		mtx_unlock(&(p)->el_lock)
66112111Sjhb#define	EHL_LOCK_ASSERT(p, x)	mtx_assert(&(p)->el_lock, x)
6793615Salfred
68112111Sjhb/*
69112111Sjhb * Macro to invoke the handlers for a given event.
70112111Sjhb */
71112111Sjhb#define _EVENTHANDLER_INVOKE(name, list, ...) do {			\
72112111Sjhb	struct eventhandler_entry *_ep;					\
73112111Sjhb	struct eventhandler_entry_ ## name *_t;				\
74112111Sjhb									\
75112111Sjhb	KASSERT((list)->el_flags & EHL_INITTED,				\
76112111Sjhb 	   ("eventhandler_invoke: running non-inited list"));		\
77112111Sjhb	EHL_LOCK_ASSERT((list), MA_OWNED);				\
78112111Sjhb	(list)->el_runcount++;						\
79112111Sjhb	KASSERT((list)->el_runcount > 0,				\
80112111Sjhb	    ("eventhandler_invoke: runcount overflow"));		\
81112111Sjhb	CTR0(KTR_EVH, "eventhandler_invoke(\"" __STRING(name) "\")");	\
82112111Sjhb	TAILQ_FOREACH(_ep, &((list)->el_entries), ee_link) {		\
83112111Sjhb		if (_ep->ee_priority != EHE_DEAD_PRIORITY) {		\
84112111Sjhb			EHL_UNLOCK((list));				\
85112111Sjhb			_t = (struct eventhandler_entry_ ## name *)_ep;	\
86112111Sjhb			CTR1(KTR_EVH, "eventhandler_invoke: executing %p", \
87112111Sjhb 			    (void *)_t->eh_func);			\
88112111Sjhb			_t->eh_func(_ep->ee_arg , ## __VA_ARGS__);	\
89112111Sjhb			EHL_LOCK((list));				\
90112111Sjhb		}							\
91112111Sjhb	}								\
92112111Sjhb	KASSERT((list)->el_runcount > 0,				\
93112111Sjhb	    ("eventhandler_invoke: runcount underflow"));		\
94112111Sjhb	(list)->el_runcount--;						\
95112111Sjhb	if ((list)->el_runcount == 0)					\
96112111Sjhb		eventhandler_prune_list(list);				\
97112111Sjhb	EHL_UNLOCK((list));						\
98112111Sjhb} while (0)
99112111Sjhb
10050107Smsmith/*
10166205Smsmith * Slow handlers are entirely dynamic; lists are created
10250107Smsmith * when entries are added to them, and thus have no concept of "owner",
10350107Smsmith *
10466205Smsmith * Slow handlers need to be declared, but do not need to be defined. The
10550107Smsmith * declaration must be in scope wherever the handler is to be invoked.
10650107Smsmith */
10795193Smarkm#define EVENTHANDLER_DECLARE(name, type)				\
10895193Smarkmstruct eventhandler_entry_ ## name 					\
10995193Smarkm{									\
11095193Smarkm	struct eventhandler_entry	ee;				\
11195193Smarkm	type				eh_func;			\
11295193Smarkm};									\
11356093Sbdestruct __hack
11450107Smsmith
115167905Snjl#define EVENTHANDLER_DEFINE(name, func, arg, priority)			\
116167905Snjl	static eventhandler_tag name ## _tag;				\
117167905Snjl	static void name ## _evh_init(void *ctx)			\
118167905Snjl	{								\
119167905Snjl		name ## _tag = EVENTHANDLER_REGISTER(name, func, ctx,	\
120167905Snjl		    priority);						\
121167905Snjl	}								\
122167905Snjl	SYSINIT(name ## _evh_init, SI_SUB_CONFIGURE, SI_ORDER_ANY,	\
123177253Srwatson	    name ## _evh_init, arg);					\
124167905Snjl	struct __hack
125167905Snjl
126100111Smarkm#define EVENTHANDLER_INVOKE(name, ...)					\
12795193Smarkmdo {									\
12895193Smarkm	struct eventhandler_list *_el;					\
12995193Smarkm									\
130112111Sjhb	if ((_el = eventhandler_find_list(#name)) != NULL) 		\
131112111Sjhb		_EVENTHANDLER_INVOKE(name, _el , ## __VA_ARGS__);	\
13256093Sbde} while (0)
13350107Smsmith
13495193Smarkm#define EVENTHANDLER_REGISTER(name, func, arg, priority)		\
13595193Smarkm	eventhandler_register(NULL, #name, func, arg, priority)
13650107Smsmith
13795193Smarkm#define EVENTHANDLER_DEREGISTER(name, tag) 				\
13895193Smarkmdo {									\
13995193Smarkm	struct eventhandler_list *_el;					\
14095193Smarkm									\
14195193Smarkm	if ((_el = eventhandler_find_list(#name)) != NULL)		\
14295193Smarkm		eventhandler_deregister(_el, tag);			\
14356093Sbde} while(0)
14450107Smsmith
14550107Smsmith
146112111Sjhbeventhandler_tag eventhandler_register(struct eventhandler_list *list,
147138439Sjkoshy	    const char *name, void *func, void *arg, int priority);
148112111Sjhbvoid	eventhandler_deregister(struct eventhandler_list *list,
149112111Sjhb	    eventhandler_tag tag);
150138439Sjkoshystruct eventhandler_list *eventhandler_find_list(const char *name);
151112111Sjhbvoid	eventhandler_prune_list(struct eventhandler_list *list);
15250107Smsmith
153205345Sbz#ifdef VIMAGE
154205345Sbztypedef	void (*vimage_iterator_func_t)(void *, ...);
155205345Sbz
156205345Sbzeventhandler_tag vimage_eventhandler_register(struct eventhandler_list *list,
157205345Sbz	    const char *name, void *func, void *arg, int priority,
158205345Sbz	    vimage_iterator_func_t);
159205345Sbz#endif
160205345Sbz
16150107Smsmith/*
16250107Smsmith * Standard system event queues.
16350107Smsmith */
16450107Smsmith
165112563Sjhb/* Generic priority levels */
166112563Sjhb#define	EVENTHANDLER_PRI_FIRST	0
167112563Sjhb#define	EVENTHANDLER_PRI_ANY	10000
168112563Sjhb#define	EVENTHANDLER_PRI_LAST	20000
169112563Sjhb
17050107Smsmith/* Shutdown events */
17192719Salfredtypedef void (*shutdown_fn)(void *, int);
17250107Smsmith
173112563Sjhb#define	SHUTDOWN_PRI_FIRST	EVENTHANDLER_PRI_FIRST
174112563Sjhb#define	SHUTDOWN_PRI_DEFAULT	EVENTHANDLER_PRI_ANY
175112565Sjhb#define	SHUTDOWN_PRI_LAST	EVENTHANDLER_PRI_LAST
17650107Smsmith
17750107SmsmithEVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn);	/* before fs sync */
17850107SmsmithEVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn);	/* after fs sync */
17950107SmsmithEVENTHANDLER_DECLARE(shutdown_final, shutdown_fn);
18050107Smsmith
181220647Sjkim/* Power state change events */
182220647Sjkimtypedef void (*power_change_fn)(void *);
183220647SjkimEVENTHANDLER_DECLARE(power_resume, power_change_fn);
184220647SjkimEVENTHANDLER_DECLARE(power_suspend, power_change_fn);
185282750SavgEVENTHANDLER_DECLARE(power_suspend_early, power_change_fn);
186220647Sjkim
187107136Sjeff/* Low memory event */
188107136Sjefftypedef void (*vm_lowmem_handler_t)(void *, int);
189112563Sjhb#define	LOWMEM_PRI_DEFAULT	EVENTHANDLER_PRI_FIRST
190107136SjeffEVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t);
19166205Smsmith
192178016Ssam/* Root mounted event */
193178016Ssamtypedef void (*mountroot_handler_t)(void *);
194178016SsamEVENTHANDLER_DECLARE(mountroot, mountroot_handler_t);
195178016Ssam
196253158Smarcel/* File system mount events */
197253158Smarcelstruct mount;
198253158Smarcelstruct vnode;
199253158Smarcelstruct thread;
200253158Smarceltypedef void (*vfs_mounted_notify_fn)(void *, struct mount *, struct vnode *,
201253158Smarcel    struct thread *);
202253158Smarceltypedef void (*vfs_unmounted_notify_fn)(void *, struct mount *,
203253158Smarcel    struct thread *);
204253158SmarcelEVENTHANDLER_DECLARE(vfs_mounted, vfs_mounted_notify_fn);
205253158SmarcelEVENTHANDLER_DECLARE(vfs_unmounted, vfs_unmounted_notify_fn);
206253158Smarcel
207180510Sjfv/* VLAN state change events */
208180510Sjfvstruct ifnet;
209180510Sjfvtypedef void (*vlan_config_fn)(void *, struct ifnet *, uint16_t);
210180510Sjfvtypedef void (*vlan_unconfig_fn)(void *, struct ifnet *, uint16_t);
211180510SjfvEVENTHANDLER_DECLARE(vlan_config, vlan_config_fn);
212180510SjfvEVENTHANDLER_DECLARE(vlan_unconfig, vlan_unconfig_fn);
213180510Sjfv
214192313Ssam/* BPF attach/detach events */
215192313Ssamstruct ifnet;
216192763Ssamtypedef void (*bpf_track_fn)(void *, struct ifnet *, int /* dlt */,
217192763Ssam    int /* 1 =>'s attach */);
218192313SsamEVENTHANDLER_DECLARE(bpf_track, bpf_track_fn);
219192313Ssam
220126940Speter/*
221126940Speter * Process events
222126941Speter * process_fork and exit handlers are called without Giant.
223126941Speter * exec handlers are called with Giant, but that is by accident.
224126940Speter */
225112564Sjhbstruct proc;
226161302Snetchildstruct image_params;
227112564Sjhb
228112564Sjhbtypedef void (*exitlist_fn)(void *, struct proc *);
229112564Sjhbtypedef void (*forklist_fn)(void *, struct proc *, struct proc *, int);
230161302Snetchildtypedef void (*execlist_fn)(void *, struct proc *, struct image_params *);
231173631Srrstypedef void (*proc_ctor_fn)(void *, struct proc *);
232173631Srrstypedef void (*proc_dtor_fn)(void *, struct proc *);
233173631Srrstypedef void (*proc_init_fn)(void *, struct proc *);
234173631Srrstypedef void (*proc_fini_fn)(void *, struct proc *);
235173631SrrsEVENTHANDLER_DECLARE(process_ctor, proc_ctor_fn);
236173631SrrsEVENTHANDLER_DECLARE(process_dtor, proc_dtor_fn);
237173631SrrsEVENTHANDLER_DECLARE(process_init, proc_init_fn);
238173631SrrsEVENTHANDLER_DECLARE(process_fini, proc_fini_fn);
239112564SjhbEVENTHANDLER_DECLARE(process_exit, exitlist_fn);
240112564SjhbEVENTHANDLER_DECLARE(process_fork, forklist_fn);
241112564SjhbEVENTHANDLER_DECLARE(process_exec, execlist_fn);
242112564Sjhb
243204552Salfred/*
244204552Salfred * application dump event
245204552Salfred */
246204552Salfredtypedef void (*app_coredump_start_fn)(void *, struct thread *, char *name);
247204552Salfredtypedef void (*app_coredump_progress_fn)(void *, struct thread *td, int byte_count);
248204552Salfredtypedef void (*app_coredump_finish_fn)(void *, struct thread *td);
249204552Salfredtypedef void (*app_coredump_error_fn)(void *, struct thread *td, char *msg, ...);
250204552Salfred
251204552SalfredEVENTHANDLER_DECLARE(app_coredump_start, app_coredump_start_fn);
252204552SalfredEVENTHANDLER_DECLARE(app_coredump_progress, app_coredump_progress_fn);
253204552SalfredEVENTHANDLER_DECLARE(app_coredump_finish, app_coredump_finish_fn);
254204552SalfredEVENTHANDLER_DECLARE(app_coredump_error, app_coredump_error_fn);
255204552Salfred
256173631Srrstypedef void (*thread_ctor_fn)(void *, struct thread *);
257173631Srrstypedef void (*thread_dtor_fn)(void *, struct thread *);
258173631Srrstypedef void (*thread_fini_fn)(void *, struct thread *);
259173631Srrstypedef void (*thread_init_fn)(void *, struct thread *);
260173631SrrsEVENTHANDLER_DECLARE(thread_ctor, thread_ctor_fn);
261173631SrrsEVENTHANDLER_DECLARE(thread_dtor, thread_dtor_fn);
262173631SrrsEVENTHANDLER_DECLARE(thread_init, thread_init_fn);
263173631SrrsEVENTHANDLER_DECLARE(thread_fini, thread_fini_fn);
264173631Srrs
265157927Spstypedef void (*uma_zone_chfn)(void *);
266157927SpsEVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn);
267243631SandreEVENTHANDLER_DECLARE(nmbufs_change, uma_zone_chfn);
268157927SpsEVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn);
269161302Snetchild
270254309Smarkj/* Kernel linker file load and unload events */
271254266Smarkjstruct linker_file;
272254309Smarkjtypedef void (*kld_load_fn)(void *, struct linker_file *);
273254813Smarkjtypedef void (*kld_unload_fn)(void *, const char *, caddr_t, size_t);
274254813Smarkjtypedef void (*kld_unload_try_fn)(void *, struct linker_file *, int *);
275254309SmarkjEVENTHANDLER_DECLARE(kld_load, kld_load_fn);
276254309SmarkjEVENTHANDLER_DECLARE(kld_unload, kld_unload_fn);
277254813SmarkjEVENTHANDLER_DECLARE(kld_unload_try, kld_unload_try_fn);
278254266Smarkj
279262861Sjhb/* Generic graphics framebuffer interface */
280262861Sjhbstruct fb_info;
281262861Sjhbtypedef void (*register_framebuffer_fn)(void *, struct fb_info *);
282262861Sjhbtypedef void (*unregister_framebuffer_fn)(void *, struct fb_info *);
283262861SjhbEVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn);
284262861SjhbEVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn);
285262861Sjhb
286307253Ssephe/* Veto ada attachment */
287307253Ssephestruct cam_path;
288307253Ssephestruct ata_params;
289307253Ssephetypedef void (*ada_probe_veto_fn)(void *, struct cam_path *,
290307253Ssephe    struct ata_params *, int *);
291307253SsepheEVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn);
292307253Ssephe
29350107Smsmith#endif /* SYS_EVENTHANDLER_H */
294