1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/*
* 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>
struct notifier_block
{
int (*notifier_call)(struct notifier_block *self, unsigned long, void *);
struct notifier_block *next;
int priority;
};
#ifdef __KERNEL__
#define NOTIFY_DONE 0x0000 /* Don't care */
#define NOTIFY_OK 0x0001 /* Suits me */
#define NOTIFY_STOP_MASK 0x8000 /* Don't call further */
#define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002) /* Bad/Veto action */
extern __inline__ int notifier_chain_register(struct notifier_block **list, struct notifier_block *n)
{
while(*list)
{
if(n->priority > (*list)->priority)
break;
list= &((*list)->next);
}
n->next = *list;
*list=n;
return 0;
}
/*
* Warning to any non GPL module writers out there.. these functions are
* GPL'd
*/
extern __inline__ int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n)
{
while((*nl)!=NULL)
{
if((*nl)==n)
{
*nl=n->next;
return 0;
}
nl=&((*nl)->next);
}
return -ENOENT;
}
/*
* This is one of these things that is generally shorter inline
*/
extern __inline__ int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
{
int ret=NOTIFY_DONE;
struct notifier_block *nb = *n;
while(nb)
{
ret=nb->notifier_call(nb,val,v);
if(ret&NOTIFY_STOP_MASK)
return ret;
nb=nb->next;
}
return ret;
}
/*
* 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...
*/
/* netdevice notifier chain */
#define NETDEV_UP 0x0001 /* For now you can't veto a device up/down */
#define NETDEV_DOWN 0x0002
#define NETDEV_REBOOT 0x0003 /* Tell a protocol stack a network interface
detected a hardware crash and restarted
- we can use this eg to kick tcp sessions
once done */
#define NETDEV_CHANGE 0x0004 /* Notify device state change */
#define NETDEV_REGISTER 0x0005
#define NETDEV_UNREGISTER 0x0006
#define NETDEV_CHANGEMTU 0x0007
#define NETDEV_CHANGEADDR 0x0008
#define SYS_DOWN 0x0001 /* Notify of system down */
#define SYS_RESTART SYS_DOWN
#define SYS_HALT 0x0002 /* Notify of system halt */
#define SYS_POWER_OFF 0x0003 /* Notify of system power off */
/*
* Publically visible notifier objects
*/
extern struct notifier_block *boot_notifier_list;
#endif
#endif
|