Commit | Line | Data |
---|---|---|
1da177e4 LT |
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> | |
e041c683 AS |
13 | #include <linux/mutex.h> |
14 | #include <linux/rwsem.h> | |
1da177e4 | 15 | |
e041c683 AS |
16 | /* |
17 | * Notifier chains are of three types: | |
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 | ||
35 | struct notifier_block { | |
36 | int (*notifier_call)(struct notifier_block *, unsigned long, void *); | |
1da177e4 LT |
37 | struct notifier_block *next; |
38 | int priority; | |
39 | }; | |
40 | ||
e041c683 AS |
41 | struct atomic_notifier_head { |
42 | spinlock_t lock; | |
43 | struct notifier_block *head; | |
44 | }; | |
45 | ||
46 | struct blocking_notifier_head { | |
47 | struct rw_semaphore rwsem; | |
48 | struct notifier_block *head; | |
49 | }; | |
50 | ||
51 | struct 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) | |
1da177e4 LT |
85 | |
86 | #ifdef __KERNEL__ | |
87 | ||
e041c683 AS |
88 | extern int atomic_notifier_chain_register(struct atomic_notifier_head *, |
89 | struct notifier_block *); | |
90 | extern int blocking_notifier_chain_register(struct blocking_notifier_head *, | |
91 | struct notifier_block *); | |
92 | extern int raw_notifier_chain_register(struct raw_notifier_head *, | |
93 | struct notifier_block *); | |
94 | ||
95 | extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *, | |
96 | struct notifier_block *); | |
97 | extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *, | |
98 | struct notifier_block *); | |
99 | extern int raw_notifier_chain_unregister(struct raw_notifier_head *, | |
100 | struct notifier_block *); | |
101 | ||
102 | extern int atomic_notifier_call_chain(struct atomic_notifier_head *, | |
103 | unsigned long val, void *v); | |
104 | extern int blocking_notifier_call_chain(struct blocking_notifier_head *, | |
105 | unsigned long val, void *v); | |
106 | extern int raw_notifier_call_chain(struct raw_notifier_head *, | |
107 | unsigned long val, void *v); | |
1da177e4 LT |
108 | |
109 | #define NOTIFY_DONE 0x0000 /* Don't care */ | |
110 | #define NOTIFY_OK 0x0001 /* Suits me */ | |
111 | #define NOTIFY_STOP_MASK 0x8000 /* Don't call further */ | |
e041c683 AS |
112 | #define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002) |
113 | /* Bad/Veto action */ | |
1da177e4 LT |
114 | /* |
115 | * Clean way to return from the notifier and stop further calls. | |
116 | */ | |
117 | #define NOTIFY_STOP (NOTIFY_OK|NOTIFY_STOP_MASK) | |
118 | ||
119 | /* | |
120 | * Declared notifiers so far. I can imagine quite a few more chains | |
121 | * over time (eg laptop power reset chains, reboot chain (to clean | |
122 | * device units up), device [un]mount chain, module load/unload chain, | |
123 | * low memory chain, screenblank chain (for plug in modular screenblankers) | |
124 | * VC switch chains (for loadable kernel svgalib VC switch helpers) etc... | |
125 | */ | |
126 | ||
127 | /* netdevice notifier chain */ | |
128 | #define NETDEV_UP 0x0001 /* For now you can't veto a device up/down */ | |
129 | #define NETDEV_DOWN 0x0002 | |
130 | #define NETDEV_REBOOT 0x0003 /* Tell a protocol stack a network interface | |
131 | detected a hardware crash and restarted | |
132 | - we can use this eg to kick tcp sessions | |
133 | once done */ | |
134 | #define NETDEV_CHANGE 0x0004 /* Notify device state change */ | |
135 | #define NETDEV_REGISTER 0x0005 | |
136 | #define NETDEV_UNREGISTER 0x0006 | |
137 | #define NETDEV_CHANGEMTU 0x0007 | |
138 | #define NETDEV_CHANGEADDR 0x0008 | |
139 | #define NETDEV_GOING_DOWN 0x0009 | |
140 | #define NETDEV_CHANGENAME 0x000A | |
d8a33ac4 | 141 | #define NETDEV_FEAT_CHANGE 0x000B |
1da177e4 LT |
142 | |
143 | #define SYS_DOWN 0x0001 /* Notify of system down */ | |
144 | #define SYS_RESTART SYS_DOWN | |
145 | #define SYS_HALT 0x0002 /* Notify of system halt */ | |
146 | #define SYS_POWER_OFF 0x0003 /* Notify of system power off */ | |
147 | ||
148 | #define NETLINK_URELEASE 0x0001 /* Unicast netlink socket released */ | |
149 | ||
150 | #define CPU_ONLINE 0x0002 /* CPU (unsigned)v is up */ | |
151 | #define CPU_UP_PREPARE 0x0003 /* CPU (unsigned)v coming up */ | |
152 | #define CPU_UP_CANCELED 0x0004 /* CPU (unsigned)v NOT coming up */ | |
153 | #define CPU_DOWN_PREPARE 0x0005 /* CPU (unsigned)v going down */ | |
154 | #define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */ | |
155 | #define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */ | |
156 | ||
157 | #endif /* __KERNEL__ */ | |
158 | #endif /* _LINUX_NOTIFIER_H */ |