1/*
2 *	Routines to manage notifier chains for passing status changes to any
3 *	interested routines. We need this instead of hard coded call lists so
4 *	that modules can poke their nose into the innards. The network devices
5 *	needed them so here they are for the rest of you.
6 *
7 *				Alan Cox <Alan.Cox@linux.org>
8 */
9
10#ifndef _LINUX_NOTIFIER_H
11#define _LINUX_NOTIFIER_H
12#include <linux/errno.h>
13#include <linux/mutex.h>
14#include <linux/rwsem.h>
15#include <linux/srcu.h>
16
17/*
18 * Notifier chains are of four types:
19 *
20 *	Atomic notifier chains: Chain callbacks run in interrupt/atomic
21 *		context. Callouts are not allowed to block.
22 *	Blocking notifier chains: Chain callbacks run in process context.
23 *		Callouts are allowed to block.
24 *	Raw notifier chains: There are no restrictions on callbacks,
25 *		registration, or unregistration.  All locking and protection
26 *		must be provided by the caller.
27 *	SRCU notifier chains: A variant of blocking notifier chains, with
28 *		the same restrictions.
29 *
30 * atomic_notifier_chain_register() may be called from an atomic context,
31 * but blocking_notifier_chain_register() and srcu_notifier_chain_register()
32 * must be called from a process context.  Ditto for the corresponding
33 * _unregister() routines.
34 *
35 * atomic_notifier_chain_unregister(), blocking_notifier_chain_unregister(),
36 * and srcu_notifier_chain_unregister() _must not_ be called from within
37 * the call chain.
38 *
39 * SRCU notifier chains are an alternative form of blocking notifier chains.
40 * They use SRCU (Sleepable Read-Copy Update) instead of rw-semaphores for
41 * protection of the chain links.  This means there is _very_ low overhead
42 * in srcu_notifier_call_chain(): no cache bounces and no memory barriers.
43 * As compensation, srcu_notifier_chain_unregister() is rather expensive.
44 * SRCU notifier chains should be used when the chain will be called very
45 * often but notifier_blocks will seldom be removed.  Also, SRCU notifier
46 * chains are slightly more difficult to use because they require special
47 * runtime initialization.
48 */
49
50typedef	int (*notifier_fn_t)(struct notifier_block *nb,
51			unsigned long action, void *data);
52
53struct notifier_block {
54	notifier_fn_t notifier_call;
55	struct notifier_block __rcu *next;
56	int priority;
57};
58
59struct atomic_notifier_head {
60	spinlock_t lock;
61	struct notifier_block __rcu *head;
62};
63
64struct blocking_notifier_head {
65	struct rw_semaphore rwsem;
66	struct notifier_block __rcu *head;
67};
68
69struct raw_notifier_head {
70	struct notifier_block __rcu *head;
71};
72
73struct srcu_notifier_head {
74	struct mutex mutex;
75	struct srcu_struct srcu;
76	struct notifier_block __rcu *head;
77};
78
79#define ATOMIC_INIT_NOTIFIER_HEAD(name) do {	\
80		spin_lock_init(&(name)->lock);	\
81		(name)->head = NULL;		\
82	} while (0)
83#define BLOCKING_INIT_NOTIFIER_HEAD(name) do {	\
84		init_rwsem(&(name)->rwsem);	\
85		(name)->head = NULL;		\
86	} while (0)
87#define RAW_INIT_NOTIFIER_HEAD(name) do {	\
88		(name)->head = NULL;		\
89	} while (0)
90
91/* srcu_notifier_heads must be initialized and cleaned up dynamically */
92extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
93#define srcu_cleanup_notifier_head(name)	\
94		cleanup_srcu_struct(&(name)->srcu);
95
96#define ATOMIC_NOTIFIER_INIT(name) {				\
97		.lock = __SPIN_LOCK_UNLOCKED(name.lock),	\
98		.head = NULL }
99#define BLOCKING_NOTIFIER_INIT(name) {				\
100		.rwsem = __RWSEM_INITIALIZER((name).rwsem),	\
101		.head = NULL }
102#define RAW_NOTIFIER_INIT(name)	{				\
103		.head = NULL }
104/* srcu_notifier_heads cannot be initialized statically */
105
106#define ATOMIC_NOTIFIER_HEAD(name)				\
107	struct atomic_notifier_head name =			\
108		ATOMIC_NOTIFIER_INIT(name)
109#define BLOCKING_NOTIFIER_HEAD(name)				\
110	struct blocking_notifier_head name =			\
111		BLOCKING_NOTIFIER_INIT(name)
112#define RAW_NOTIFIER_HEAD(name)					\
113	struct raw_notifier_head name =				\
114		RAW_NOTIFIER_INIT(name)
115
116#ifdef __KERNEL__
117
118extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
119		struct notifier_block *nb);
120extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
121		struct notifier_block *nb);
122extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
123		struct notifier_block *nb);
124extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
125		struct notifier_block *nb);
126
127extern int blocking_notifier_chain_cond_register(
128		struct blocking_notifier_head *nh,
129		struct notifier_block *nb);
130
131extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
132		struct notifier_block *nb);
133extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
134		struct notifier_block *nb);
135extern int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
136		struct notifier_block *nb);
137extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
138		struct notifier_block *nb);
139
140extern int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
141		unsigned long val, void *v);
142extern int __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
143	unsigned long val, void *v, int nr_to_call, int *nr_calls);
144extern int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
145		unsigned long val, void *v);
146extern int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
147	unsigned long val, void *v, int nr_to_call, int *nr_calls);
148extern int raw_notifier_call_chain(struct raw_notifier_head *nh,
149		unsigned long val, void *v);
150extern int __raw_notifier_call_chain(struct raw_notifier_head *nh,
151	unsigned long val, void *v, int nr_to_call, int *nr_calls);
152extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
153		unsigned long val, void *v);
154extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
155	unsigned long val, void *v, int nr_to_call, int *nr_calls);
156
157#define NOTIFY_DONE		0x0000		/* Don't care */
158#define NOTIFY_OK		0x0001		/* Suits me */
159#define NOTIFY_STOP_MASK	0x8000		/* Don't call further */
160#define NOTIFY_BAD		(NOTIFY_STOP_MASK|0x0002)
161						/* Bad/Veto action */
162/*
163 * Clean way to return from the notifier and stop further calls.
164 */
165#define NOTIFY_STOP		(NOTIFY_OK|NOTIFY_STOP_MASK)
166
167/* Encapsulate (negative) errno value (in particular, NOTIFY_BAD <=> EPERM). */
168static inline int notifier_from_errno(int err)
169{
170	if (err)
171		return NOTIFY_STOP_MASK | (NOTIFY_OK - err);
172
173	return NOTIFY_OK;
174}
175
176/* Restore (negative) errno value from notify return value. */
177static inline int notifier_to_errno(int ret)
178{
179	ret &= ~NOTIFY_STOP_MASK;
180	return ret > NOTIFY_OK ? NOTIFY_OK - ret : 0;
181}
182
183/*
184 *	Declared notifiers so far. I can imagine quite a few more chains
185 *	over time (eg laptop power reset chains, reboot chain (to clean
186 *	device units up), device [un]mount chain, module load/unload chain,
187 *	low memory chain, screenblank chain (for plug in modular screenblankers)
188 *	VC switch chains (for loadable kernel svgalib VC switch helpers) etc...
189 */
190
191/* CPU notfiers are defined in include/linux/cpu.h. */
192
193/* netdevice notifiers are defined in include/linux/netdevice.h */
194
195/* reboot notifiers are defined in include/linux/reboot.h. */
196
197/* Hibernation and suspend events are defined in include/linux/suspend.h. */
198
199/* Virtual Terminal events are defined in include/linux/vt.h. */
200
201#define NETLINK_URELEASE	0x0001	/* Unicast netlink socket released */
202
203/* Console keyboard events.
204 * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
205 * KBD_KEYSYM. */
206#define KBD_KEYCODE		0x0001 /* Keyboard keycode, called before any other */
207#define KBD_UNBOUND_KEYCODE	0x0002 /* Keyboard keycode which is not bound to any other */
208#define KBD_UNICODE		0x0003 /* Keyboard unicode */
209#define KBD_KEYSYM		0x0004 /* Keyboard keysym */
210#define KBD_POST_KEYSYM		0x0005 /* Called after keyboard keysym interpretation */
211
212extern struct blocking_notifier_head reboot_notifier_list;
213
214#endif /* __KERNEL__ */
215#endif /* _LINUX_NOTIFIER_H */
216