aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/adb.h2
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/memory.h1
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h17
-rw-r--r--include/linux/notifier.h96
5 files changed, 100 insertions, 18 deletions
diff --git a/include/linux/adb.h b/include/linux/adb.h
index e9fdc63483c7..b7305b178279 100644
--- a/include/linux/adb.h
+++ b/include/linux/adb.h
@@ -85,7 +85,7 @@ enum adb_message {
85 ADB_MSG_POST_RESET /* Called after resetting the bus (re-do init & register) */ 85 ADB_MSG_POST_RESET /* Called after resetting the bus (re-do init & register) */
86}; 86};
87extern struct adb_driver *adb_controller; 87extern struct adb_driver *adb_controller;
88extern struct notifier_block *adb_client_list; 88extern struct blocking_notifier_head adb_client_list;
89 89
90int adb_request(struct adb_request *req, void (*done)(struct adb_request *), 90int adb_request(struct adb_request *req, void (*done)(struct adb_request *),
91 int flags, int nbytes, ...); 91 int flags, int nbytes, ...);
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 03d6cfaa5b8a..a3720f973ea5 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -87,7 +87,7 @@ extern int cond_resched(void);
87 (__x < 0) ? -__x : __x; \ 87 (__x < 0) ? -__x : __x; \
88 }) 88 })
89 89
90extern struct notifier_block *panic_notifier_list; 90extern struct atomic_notifier_head panic_notifier_list;
91extern long (*panic_blink)(long time); 91extern long (*panic_blink)(long time);
92NORET_TYPE void panic(const char * fmt, ...) 92NORET_TYPE void panic(const char * fmt, ...)
93 __attribute__ ((NORET_AND format (printf, 1, 2))); 93 __attribute__ ((NORET_AND format (printf, 1, 2)));
diff --git a/include/linux/memory.h b/include/linux/memory.h
index e251dc43d0f5..8f04143ca363 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -77,7 +77,6 @@ extern int remove_memory_block(unsigned long, struct mem_section *, int);
77 77
78#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) 78#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
79 79
80struct notifier_block;
81 80
82#endif /* CONFIG_MEMORY_HOTPLUG */ 81#endif /* CONFIG_MEMORY_HOTPLUG */
83 82
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index f32d75c4f4cf..d54d7b278e96 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -308,29 +308,30 @@ DECLARE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache);
308 308
309#define CONNTRACK_ECACHE(x) (__get_cpu_var(ip_conntrack_ecache).x) 309#define CONNTRACK_ECACHE(x) (__get_cpu_var(ip_conntrack_ecache).x)
310 310
311extern struct notifier_block *ip_conntrack_chain; 311extern struct atomic_notifier_head ip_conntrack_chain;
312extern struct notifier_block *ip_conntrack_expect_chain; 312extern struct atomic_notifier_head ip_conntrack_expect_chain;
313 313
314static inline int ip_conntrack_register_notifier(struct notifier_block *nb) 314static inline int ip_conntrack_register_notifier(struct notifier_block *nb)
315{ 315{
316 return notifier_chain_register(&ip_conntrack_chain, nb); 316 return atomic_notifier_chain_register(&ip_conntrack_chain, nb);
317} 317}
318 318
319static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb) 319static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb)
320{ 320{
321 return notifier_chain_unregister(&ip_conntrack_chain, nb); 321 return atomic_notifier_chain_unregister(&ip_conntrack_chain, nb);
322} 322}
323 323
324static inline int 324static inline int
325ip_conntrack_expect_register_notifier(struct notifier_block *nb) 325ip_conntrack_expect_register_notifier(struct notifier_block *nb)
326{ 326{
327 return notifier_chain_register(&ip_conntrack_expect_chain, nb); 327 return atomic_notifier_chain_register(&ip_conntrack_expect_chain, nb);
328} 328}
329 329
330static inline int 330static inline int
331ip_conntrack_expect_unregister_notifier(struct notifier_block *nb) 331ip_conntrack_expect_unregister_notifier(struct notifier_block *nb)
332{ 332{
333 return notifier_chain_unregister(&ip_conntrack_expect_chain, nb); 333 return atomic_notifier_chain_unregister(&ip_conntrack_expect_chain,
334 nb);
334} 335}
335 336
336extern void ip_ct_deliver_cached_events(const struct ip_conntrack *ct); 337extern void ip_ct_deliver_cached_events(const struct ip_conntrack *ct);
@@ -355,14 +356,14 @@ static inline void ip_conntrack_event(enum ip_conntrack_events event,
355 struct ip_conntrack *ct) 356 struct ip_conntrack *ct)
356{ 357{
357 if (is_confirmed(ct) && !is_dying(ct)) 358 if (is_confirmed(ct) && !is_dying(ct))
358 notifier_call_chain(&ip_conntrack_chain, event, ct); 359 atomic_notifier_call_chain(&ip_conntrack_chain, event, ct);
359} 360}
360 361
361static inline void 362static inline void
362ip_conntrack_expect_event(enum ip_conntrack_expect_events event, 363ip_conntrack_expect_event(enum ip_conntrack_expect_events event,
363 struct ip_conntrack_expect *exp) 364 struct ip_conntrack_expect *exp)
364{ 365{
365 notifier_call_chain(&ip_conntrack_expect_chain, event, exp); 366 atomic_notifier_call_chain(&ip_conntrack_expect_chain, event, exp);
366} 367}
367#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */ 368#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */
368static inline void ip_conntrack_event_cache(enum ip_conntrack_events event, 369static inline void ip_conntrack_event_cache(enum ip_conntrack_events event,
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 5937dd6053c3..51dbab9710c7 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -10,25 +10,107 @@
10#ifndef _LINUX_NOTIFIER_H 10#ifndef _LINUX_NOTIFIER_H
11#define _LINUX_NOTIFIER_H 11#define _LINUX_NOTIFIER_H
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/mutex.h>
14#include <linux/rwsem.h>
13 15
14struct notifier_block 16/*
15{ 17 * Notifier chains are of three types:
16 int (*notifier_call)(struct notifier_block *self, unsigned long, void *); 18 *
19 * Atomic notifier chains: Chain callbacks run in interrupt/atomic
20 * context. Callouts are not allowed to block.
21 * Blocking notifier chains: Chain callbacks run in process context.
22 * Callouts are allowed to block.
23 * Raw notifier chains: There are no restrictions on callbacks,
24 * registration, or unregistration. All locking and protection
25 * must be provided by the caller.
26 *
27 * atomic_notifier_chain_register() may be called from an atomic context,
28 * but blocking_notifier_chain_register() must be called from a process
29 * context. Ditto for the corresponding _unregister() routines.
30 *
31 * atomic_notifier_chain_unregister() and blocking_notifier_chain_unregister()
32 * _must not_ be called from within the call chain.
33 */
34
35struct notifier_block {
36 int (*notifier_call)(struct notifier_block *, unsigned long, void *);
17 struct notifier_block *next; 37 struct notifier_block *next;
18 int priority; 38 int priority;
19}; 39};
20 40
41struct atomic_notifier_head {
42 spinlock_t lock;
43 struct notifier_block *head;
44};
45
46struct blocking_notifier_head {
47 struct rw_semaphore rwsem;
48 struct notifier_block *head;
49};
50
51struct raw_notifier_head {
52 struct notifier_block *head;
53};
54
55#define ATOMIC_INIT_NOTIFIER_HEAD(name) do { \
56 spin_lock_init(&(name)->lock); \
57 (name)->head = NULL; \
58 } while (0)
59#define BLOCKING_INIT_NOTIFIER_HEAD(name) do { \
60 init_rwsem(&(name)->rwsem); \
61 (name)->head = NULL; \
62 } while (0)
63#define RAW_INIT_NOTIFIER_HEAD(name) do { \
64 (name)->head = NULL; \
65 } while (0)
66
67#define ATOMIC_NOTIFIER_INIT(name) { \
68 .lock = SPIN_LOCK_UNLOCKED, \
69 .head = NULL }
70#define BLOCKING_NOTIFIER_INIT(name) { \
71 .rwsem = __RWSEM_INITIALIZER((name).rwsem), \
72 .head = NULL }
73#define RAW_NOTIFIER_INIT(name) { \
74 .head = NULL }
75
76#define ATOMIC_NOTIFIER_HEAD(name) \
77 struct atomic_notifier_head name = \
78 ATOMIC_NOTIFIER_INIT(name)
79#define BLOCKING_NOTIFIER_HEAD(name) \
80 struct blocking_notifier_head name = \
81 BLOCKING_NOTIFIER_INIT(name)
82#define RAW_NOTIFIER_HEAD(name) \
83 struct raw_notifier_head name = \
84 RAW_NOTIFIER_INIT(name)
21 85
22#ifdef __KERNEL__ 86#ifdef __KERNEL__
23 87
24extern int notifier_chain_register(struct notifier_block **list, struct notifier_block *n); 88extern int atomic_notifier_chain_register(struct atomic_notifier_head *,
25extern int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n); 89 struct notifier_block *);
26extern int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v); 90extern int blocking_notifier_chain_register(struct blocking_notifier_head *,
91 struct notifier_block *);
92extern int raw_notifier_chain_register(struct raw_notifier_head *,
93 struct notifier_block *);
94
95extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *,
96 struct notifier_block *);
97extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *,
98 struct notifier_block *);
99extern int raw_notifier_chain_unregister(struct raw_notifier_head *,
100 struct notifier_block *);
101
102extern int atomic_notifier_call_chain(struct atomic_notifier_head *,
103 unsigned long val, void *v);
104extern int blocking_notifier_call_chain(struct blocking_notifier_head *,
105 unsigned long val, void *v);
106extern int raw_notifier_call_chain(struct raw_notifier_head *,
107 unsigned long val, void *v);
27 108
28#define NOTIFY_DONE 0x0000 /* Don't care */ 109#define NOTIFY_DONE 0x0000 /* Don't care */
29#define NOTIFY_OK 0x0001 /* Suits me */ 110#define NOTIFY_OK 0x0001 /* Suits me */
30#define NOTIFY_STOP_MASK 0x8000 /* Don't call further */ 111#define NOTIFY_STOP_MASK 0x8000 /* Don't call further */
31#define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002) /* Bad/Veto action */ 112#define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002)
113 /* Bad/Veto action */
32/* 114/*
33 * Clean way to return from the notifier and stop further calls. 115 * Clean way to return from the notifier and stop further calls.
34 */ 116 */