Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/subr_autoconf.c
Show All 37 Lines | |||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_ddb.h" | #include "opt_ddb.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/linker.h> | #include <sys/linker.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | |||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
/* | /* | ||||
* Autoconfiguration subroutines. | * Autoconfiguration subroutines. | ||||
*/ | */ | ||||
/* | /* | ||||
* "Interrupt driven config" functions. | * "Interrupt driven config" functions. | ||||
*/ | */ | ||||
static TAILQ_HEAD(, intr_config_hook) intr_config_hook_list = | static TAILQ_HEAD(, intr_config_hook) intr_config_hook_list = | ||||
TAILQ_HEAD_INITIALIZER(intr_config_hook_list); | TAILQ_HEAD_INITIALIZER(intr_config_hook_list); | ||||
static struct intr_config_hook *next_to_notify; | static struct intr_config_hook *next_to_notify; | ||||
static struct mtx intr_config_hook_lock; | static struct mtx intr_config_hook_lock; | ||||
MTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, "intr config", MTX_DEF); | MTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, "intr config", MTX_DEF); | ||||
/* ARGSUSED */ | /* ARGSUSED */ | ||||
static void run_interrupt_driven_config_hooks(void); | static void run_interrupt_driven_config_hooks(void); | ||||
/* | /* | ||||
* Private data and a shim function for implementing config_interhook_oneshot(). | |||||
*/ | |||||
struct oneshot_config_hook { | |||||
struct intr_config_hook | |||||
och_hook; /* Must be first */ | |||||
ich_func_t och_func; | |||||
void *och_arg; | |||||
}; | |||||
static void | |||||
config_intrhook_oneshot_func(void *arg) | |||||
{ | |||||
struct oneshot_config_hook *ohook; | |||||
ohook = arg; | |||||
ohook->och_func(ohook->och_arg); | |||||
config_intrhook_disestablish(&ohook->och_hook); | |||||
free(ohook, M_DEVBUF); | |||||
} | |||||
/* | |||||
* If we wait too long for an interrupt-driven config hook to return, print | * If we wait too long for an interrupt-driven config hook to return, print | ||||
* a diagnostic. | * a diagnostic. | ||||
*/ | */ | ||||
#define WARNING_INTERVAL_SECS 60 | #define WARNING_INTERVAL_SECS 60 | ||||
static void | static void | ||||
run_interrupt_driven_config_hooks_warning(int warned) | run_interrupt_driven_config_hooks_warning(int warned) | ||||
{ | { | ||||
struct intr_config_hook *hook_entry; | struct intr_config_hook *hook_entry; | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | config_intrhook_establish(struct intr_config_hook *hook) | ||||
if (cold == 0) | if (cold == 0) | ||||
/* | /* | ||||
* XXX Call from a task since not all drivers expect | * XXX Call from a task since not all drivers expect | ||||
* to be re-entered at the time a hook is established. | * to be re-entered at the time a hook is established. | ||||
*/ | */ | ||||
/* XXX Sufficient for modules loaded after initial config??? */ | /* XXX Sufficient for modules loaded after initial config??? */ | ||||
run_interrupt_driven_config_hooks(); | run_interrupt_driven_config_hooks(); | ||||
return (0); | return (0); | ||||
} | |||||
/* | |||||
* Register a hook function that is automatically unregistered after it runs. | |||||
*/ | |||||
void | |||||
config_intrhook_oneshot(ich_func_t func, void *arg) | |||||
{ | |||||
struct oneshot_config_hook *ohook; | |||||
ohook = malloc(sizeof(*ohook), M_DEVBUF, M_WAITOK); | |||||
ohook->och_func = func; | |||||
ohook->och_arg = arg; | |||||
ohook->och_hook.ich_func = config_intrhook_oneshot_func; | |||||
ohook->och_hook.ich_arg = ohook; | |||||
config_intrhook_establish(&ohook->och_hook); | |||||
} | } | ||||
void | void | ||||
config_intrhook_disestablish(struct intr_config_hook *hook) | config_intrhook_disestablish(struct intr_config_hook *hook) | ||||
{ | { | ||||
struct intr_config_hook *hook_entry; | struct intr_config_hook *hook_entry; | ||||
mtx_lock(&intr_config_hook_lock); | mtx_lock(&intr_config_hook_lock); | ||||
Show All 39 Lines |