Blame view

include/linux/notifier.h 7.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
  /*
   *	Routines to manage notifier chains for passing status changes to any
   *	interested routines. We need this instead of hard coded call lists so
   *	that modules can poke their nose into the innards. The network devices
   *	needed them so here they are for the rest of you.
   *
   *				Alan Cox <Alan.Cox@linux.org>
   */
   
  #ifndef _LINUX_NOTIFIER_H
  #define _LINUX_NOTIFIER_H
  #include <linux/errno.h>
e041c6834   Alan Stern   [PATCH] Notifier ...
13
14
  #include <linux/mutex.h>
  #include <linux/rwsem.h>
eabc06940   Alan Stern   [PATCH] Add SRCU-...
15
  #include <linux/srcu.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16

e041c6834   Alan Stern   [PATCH] Notifier ...
17
  /*
eabc06940   Alan Stern   [PATCH] Add SRCU-...
18
   * Notifier chains are of four types:
e041c6834   Alan Stern   [PATCH] Notifier ...
19
20
21
22
23
24
25
26
   *
   *	Atomic notifier chains: Chain callbacks run in interrupt/atomic
   *		context. Callouts are not allowed to block.
   *	Blocking notifier chains: Chain callbacks run in process context.
   *		Callouts are allowed to block.
   *	Raw notifier chains: There are no restrictions on callbacks,
   *		registration, or unregistration.  All locking and protection
   *		must be provided by the caller.
eabc06940   Alan Stern   [PATCH] Add SRCU-...
27
28
   *	SRCU notifier chains: A variant of blocking notifier chains, with
   *		the same restrictions.
e041c6834   Alan Stern   [PATCH] Notifier ...
29
30
   *
   * atomic_notifier_chain_register() may be called from an atomic context,
eabc06940   Alan Stern   [PATCH] Add SRCU-...
31
32
33
   * but blocking_notifier_chain_register() and srcu_notifier_chain_register()
   * must be called from a process context.  Ditto for the corresponding
   * _unregister() routines.
e041c6834   Alan Stern   [PATCH] Notifier ...
34
   *
eabc06940   Alan Stern   [PATCH] Add SRCU-...
35
36
37
38
39
40
41
42
43
44
45
46
47
   * atomic_notifier_chain_unregister(), blocking_notifier_chain_unregister(),
   * and srcu_notifier_chain_unregister() _must not_ be called from within
   * the call chain.
   *
   * SRCU notifier chains are an alternative form of blocking notifier chains.
   * They use SRCU (Sleepable Read-Copy Update) instead of rw-semaphores for
   * protection of the chain links.  This means there is _very_ low overhead
   * in srcu_notifier_call_chain(): no cache bounces and no memory barriers.
   * As compensation, srcu_notifier_chain_unregister() is rather expensive.
   * SRCU notifier chains should be used when the chain will be called very
   * often but notifier_blocks will seldom be removed.  Also, SRCU notifier
   * chains are slightly more difficult to use because they require special
   * runtime initialization.
e041c6834   Alan Stern   [PATCH] Notifier ...
48
49
50
51
   */
  
  struct notifier_block {
  	int (*notifier_call)(struct notifier_block *, unsigned long, void *);
374a8e0dc   Arnd Bergmann   notifiers: __rcu ...
52
  	struct notifier_block __rcu *next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
54
  	int priority;
  };
e041c6834   Alan Stern   [PATCH] Notifier ...
55
56
  struct atomic_notifier_head {
  	spinlock_t lock;
374a8e0dc   Arnd Bergmann   notifiers: __rcu ...
57
  	struct notifier_block __rcu *head;
e041c6834   Alan Stern   [PATCH] Notifier ...
58
59
60
61
  };
  
  struct blocking_notifier_head {
  	struct rw_semaphore rwsem;
374a8e0dc   Arnd Bergmann   notifiers: __rcu ...
62
  	struct notifier_block __rcu *head;
e041c6834   Alan Stern   [PATCH] Notifier ...
63
64
65
  };
  
  struct raw_notifier_head {
374a8e0dc   Arnd Bergmann   notifiers: __rcu ...
66
  	struct notifier_block __rcu *head;
e041c6834   Alan Stern   [PATCH] Notifier ...
67
  };
eabc06940   Alan Stern   [PATCH] Add SRCU-...
68
69
70
  struct srcu_notifier_head {
  	struct mutex mutex;
  	struct srcu_struct srcu;
374a8e0dc   Arnd Bergmann   notifiers: __rcu ...
71
  	struct notifier_block __rcu *head;
eabc06940   Alan Stern   [PATCH] Add SRCU-...
72
  };
e041c6834   Alan Stern   [PATCH] Notifier ...
73
74
75
76
77
78
79
80
81
82
83
  #define ATOMIC_INIT_NOTIFIER_HEAD(name) do {	\
  		spin_lock_init(&(name)->lock);	\
  		(name)->head = NULL;		\
  	} while (0)
  #define BLOCKING_INIT_NOTIFIER_HEAD(name) do {	\
  		init_rwsem(&(name)->rwsem);	\
  		(name)->head = NULL;		\
  	} while (0)
  #define RAW_INIT_NOTIFIER_HEAD(name) do {	\
  		(name)->head = NULL;		\
  	} while (0)
eabc06940   Alan Stern   [PATCH] Add SRCU-...
84
85
86
87
  /* srcu_notifier_heads must be initialized and cleaned up dynamically */
  extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
  #define srcu_cleanup_notifier_head(name)	\
  		cleanup_srcu_struct(&(name)->srcu);
e041c6834   Alan Stern   [PATCH] Notifier ...
88
  #define ATOMIC_NOTIFIER_INIT(name) {				\
e4d919188   Ingo Molnar   [PATCH] lockdep: ...
89
  		.lock = __SPIN_LOCK_UNLOCKED(name.lock),	\
e041c6834   Alan Stern   [PATCH] Notifier ...
90
91
92
93
94
95
  		.head = NULL }
  #define BLOCKING_NOTIFIER_INIT(name) {				\
  		.rwsem = __RWSEM_INITIALIZER((name).rwsem),	\
  		.head = NULL }
  #define RAW_NOTIFIER_INIT(name)	{				\
  		.head = NULL }
eabc06940   Alan Stern   [PATCH] Add SRCU-...
96
  /* srcu_notifier_heads cannot be initialized statically */
e041c6834   Alan Stern   [PATCH] Notifier ...
97
98
99
100
101
102
103
104
105
106
  
  #define ATOMIC_NOTIFIER_HEAD(name)				\
  	struct atomic_notifier_head name =			\
  		ATOMIC_NOTIFIER_INIT(name)
  #define BLOCKING_NOTIFIER_HEAD(name)				\
  	struct blocking_notifier_head name =			\
  		BLOCKING_NOTIFIER_INIT(name)
  #define RAW_NOTIFIER_HEAD(name)					\
  	struct raw_notifier_head name =				\
  		RAW_NOTIFIER_INIT(name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
  
  #ifdef __KERNEL__
6f7cc11aa   Gautham R Shenoy   Extend notifier_c...
109
110
111
112
113
114
115
116
  extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
  		struct notifier_block *nb);
  extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
  		struct notifier_block *nb);
  extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
  		struct notifier_block *nb);
  extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
  		struct notifier_block *nb);
6546bc427   Nadia Derbey   ipc: re-enable ms...
117
118
119
  extern int blocking_notifier_chain_cond_register(
  		struct blocking_notifier_head *nh,
  		struct notifier_block *nb);
6f7cc11aa   Gautham R Shenoy   Extend notifier_c...
120
121
122
123
124
125
126
127
128
129
  extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
  		struct notifier_block *nb);
  extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
  		struct notifier_block *nb);
  extern int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
  		struct notifier_block *nb);
  extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
  		struct notifier_block *nb);
  
  extern int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
e041c6834   Alan Stern   [PATCH] Notifier ...
130
  		unsigned long val, void *v);
6f7cc11aa   Gautham R Shenoy   Extend notifier_c...
131
132
133
  extern int __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
  	unsigned long val, void *v, int nr_to_call, int *nr_calls);
  extern int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
e041c6834   Alan Stern   [PATCH] Notifier ...
134
  		unsigned long val, void *v);
6f7cc11aa   Gautham R Shenoy   Extend notifier_c...
135
136
137
  extern int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
  	unsigned long val, void *v, int nr_to_call, int *nr_calls);
  extern int raw_notifier_call_chain(struct raw_notifier_head *nh,
e041c6834   Alan Stern   [PATCH] Notifier ...
138
  		unsigned long val, void *v);
6f7cc11aa   Gautham R Shenoy   Extend notifier_c...
139
140
141
  extern int __raw_notifier_call_chain(struct raw_notifier_head *nh,
  	unsigned long val, void *v, int nr_to_call, int *nr_calls);
  extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
eabc06940   Alan Stern   [PATCH] Add SRCU-...
142
  		unsigned long val, void *v);
6f7cc11aa   Gautham R Shenoy   Extend notifier_c...
143
144
  extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
  	unsigned long val, void *v, int nr_to_call, int *nr_calls);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
148
  
  #define NOTIFY_DONE		0x0000		/* Don't care */
  #define NOTIFY_OK		0x0001		/* Suits me */
  #define NOTIFY_STOP_MASK	0x8000		/* Don't call further */
e041c6834   Alan Stern   [PATCH] Notifier ...
149
150
  #define NOTIFY_BAD		(NOTIFY_STOP_MASK|0x0002)
  						/* Bad/Veto action */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
  /*
   * Clean way to return from the notifier and stop further calls.
   */
  #define NOTIFY_STOP		(NOTIFY_OK|NOTIFY_STOP_MASK)
fcc5a03ac   Herbert Xu   [NET]: Allow netd...
155
156
157
  /* Encapsulate (negative) errno value (in particular, NOTIFY_BAD <=> EPERM). */
  static inline int notifier_from_errno(int err)
  {
b957e043e   Akinobu Mita   notifier: change ...
158
159
160
161
  	if (err)
  		return NOTIFY_STOP_MASK | (NOTIFY_OK - err);
  
  	return NOTIFY_OK;
fcc5a03ac   Herbert Xu   [NET]: Allow netd...
162
163
164
165
166
167
168
169
  }
  
  /* Restore (negative) errno value from notify return value. */
  static inline int notifier_to_errno(int ret)
  {
  	ret &= ~NOTIFY_STOP_MASK;
  	return ret > NOTIFY_OK ? NOTIFY_OK - ret : 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
172
173
174
175
176
177
  /*
   *	Declared notifiers so far. I can imagine quite a few more chains
   *	over time (eg laptop power reset chains, reboot chain (to clean 
   *	device units up), device [un]mount chain, module load/unload chain,
   *	low memory chain, screenblank chain (for plug in modular screenblankers) 
   *	VC switch chains (for loadable kernel svgalib VC switch helpers) etc...
   */
   
80f1ff97d   Amerigo Wang   notifiers: cpu: m...
178
  /* CPU notfiers are defined in include/linux/cpu.h. */
dcfe1421c   Amerigo Wang   notifiers: net: m...
179
  /* netdevice notifiers are defined in include/linux/netdevice.h */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180

c5f41752f   Amerigo Wang   notifiers: sys: m...
181
  /* reboot notifiers are defined in include/linux/reboot.h. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182

35eb6db11   Amerigo Wang   notifiers: pm: mo...
183
  /* Hibernation and suspend events are defined in include/linux/suspend.h. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184

a376d3d67   Amerigo Wang   notifiers: vt: mo...
185
  /* Virtual Terminal events are defined in include/linux/vt.h. */
35eb6db11   Amerigo Wang   notifiers: pm: mo...
186
  #define NETLINK_URELEASE	0x0001	/* Unicast netlink socket released */
b10d91174   Rafael J. Wysocki   PM: introduce hib...
187

41ab4396e   Samuel Thibault   Console keyboard ...
188
189
190
191
192
193
194
195
  /* Console keyboard events.
   * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
   * KBD_KEYSYM. */
  #define KBD_KEYCODE		0x0001 /* Keyboard keycode, called before any other */
  #define KBD_UNBOUND_KEYCODE	0x0002 /* Keyboard keycode which is not bound to any other */
  #define KBD_UNICODE		0x0003 /* Keyboard unicode */
  #define KBD_KEYSYM		0x0004 /* Keyboard keysym */
  #define KBD_POST_KEYSYM		0x0005 /* Called after keyboard keysym interpretation */
fe9d4f576   Alexey Dobriyan   Add kernel/notifi...
196
  extern struct blocking_notifier_head reboot_notifier_list;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
  #endif /* __KERNEL__ */
  #endif /* _LINUX_NOTIFIER_H */