diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
commit | 6d403070f28cd44860fdb3a53be5da0275c65cf4 (patch) | |
tree | 0d0e7fe7b5fb7568d19e11d7d862b77a866ce081 /kernel/sys.c | |
parent | ecf1bf5f6c2e668d03b0a9fb026db7aa41e292e1 (diff) |
Merge with 2.4.0-test1-ac21 + pile of MIPS cleanups to make merging
possible. Chainsawed RM200 kernel to compile again. Jazz machine
status unknown.
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 0c78f80b4..8bd07d55f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -4,6 +4,7 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ +#include <linux/module.h> #include <linux/mm.h> #include <linux/utsname.h> #include <linux/mman.h> @@ -46,13 +47,123 @@ int C_A_D = 1; * and the like. */ -struct notifier_block *reboot_notifier_list = NULL; +static struct notifier_block *reboot_notifier_list = NULL; +rwlock_t notifier_lock = RW_LOCK_UNLOCKED; +/** + * notifier_chain_register - Add notifier to a notifier chain + * @list: Pointer to root list pointer + * @n: New entry in notifier chain + * + * Adds a notifier to a notifier chain. + * + * Currently always returns zero. + */ + +int notifier_chain_register(struct notifier_block **list, struct notifier_block *n) +{ + write_lock(¬ifier_lock); + while(*list) + { + if(n->priority > (*list)->priority) + break; + list= &((*list)->next); + } + n->next = *list; + *list=n; + write_unlock(¬ifier_lock); + return 0; +} + +/** + * notifier_chain_unregister - Remove notifier from a notifier chain + * @nl: Pointer to root list pointer + * @n: New entry in notifier chain + * + * Removes a notifier from a notifier chain. + * + * Returns zero on success, or %-ENOENT on failure. + */ + +int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n) +{ + write_lock(¬ifier_lock); + while((*nl)!=NULL) + { + if((*nl)==n) + { + *nl=n->next; + write_unlock(¬ifier_lock); + return 0; + } + nl=&((*nl)->next); + } + write_unlock(¬ifier_lock); + return -ENOENT; +} + +/** + * notifier_call_chain - Call functions in a notifier chain + * @n: Pointer to root pointer of notifier chain + * @val: Value passed unmodified to notifier function + * @v: Pointer passed unmodified to notifier function + * + * Calls each function in a notifier chain in turn. + * + * If the return value of the notifier can be and'd + * with %NOTIFY_STOP_MASK, then notifier_call_chain + * will return immediately, with the return value of + * the notifier function which halted execution. + * Otherwise, the return value is the return value + * of the last notifier function called. + */ + +int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v) +{ + int ret=NOTIFY_DONE; + struct notifier_block *nb = *n; + + read_lock(¬ifier_lock); + while(nb) + { + ret=nb->notifier_call(nb,val,v); + if(ret&NOTIFY_STOP_MASK) + { + read_unlock(¬ifier_lock); + return ret; + } + nb=nb->next; + } + read_unlock(¬ifier_lock); + return ret; +} + +/** + * register_reboot_notifier - Register function to be called at reboot time + * @nb: Info about notifier function to be called + * + * Registers a function with the list of functions + * to be called at reboot time. + * + * Currently always returns zero, as notifier_chain_register + * always returns zero. + */ + int register_reboot_notifier(struct notifier_block * nb) { return notifier_chain_register(&reboot_notifier_list, nb); } +/** + * unregister_reboot_notifier - Unregister previously registered reboot notifier + * @nb: Hook to be unregistered + * + * Unregisters a previously registered reboot + * notifier function. + * + * Returns zero on success, or %-ENOENT on failure. + */ + int unregister_reboot_notifier(struct notifier_block * nb) { return notifier_chain_unregister(&reboot_notifier_list, nb); @@ -1109,3 +1220,10 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, return error; } +EXPORT_SYMBOL(notifier_chain_register); +EXPORT_SYMBOL(notifier_chain_unregister); +EXPORT_SYMBOL(notifier_call_chain); +EXPORT_SYMBOL(register_reboot_notifier); +EXPORT_SYMBOL(unregister_reboot_notifier); +EXPORT_SYMBOL(in_group_p); +EXPORT_SYMBOL(in_egroup_p); |