Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_autoconf.c
Show First 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | if (running != 0) { | |||||||||||
mtx_unlock(&intr_config_hook_lock); | mtx_unlock(&intr_config_hook_lock); | |||||||||||
return; | return; | |||||||||||
} | } | |||||||||||
running = 1; | running = 1; | |||||||||||
while (next_to_notify != NULL) { | while (next_to_notify != NULL) { | |||||||||||
hook_entry = next_to_notify; | hook_entry = next_to_notify; | |||||||||||
next_to_notify = STAILQ_NEXT(hook_entry, ich_links); | next_to_notify = STAILQ_NEXT(hook_entry, ich_links); | |||||||||||
hook_entry->ich_state = ICHS_RUNNING; | ||||||||||||
mtx_unlock(&intr_config_hook_lock); | mtx_unlock(&intr_config_hook_lock); | |||||||||||
(*hook_entry->ich_func)(hook_entry->ich_arg); | (*hook_entry->ich_func)(hook_entry->ich_arg); | |||||||||||
mtx_lock(&intr_config_hook_lock); | mtx_lock(&intr_config_hook_lock); | |||||||||||
} | } | |||||||||||
running = 0; | running = 0; | |||||||||||
mtx_unlock(&intr_config_hook_lock); | mtx_unlock(&intr_config_hook_lock); | |||||||||||
} | } | |||||||||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if (hook_entry != NULL) { | |||||||||||
mtx_unlock(&intr_config_hook_lock); | mtx_unlock(&intr_config_hook_lock); | |||||||||||
printf("config_intrhook_establish: establishing an " | printf("config_intrhook_establish: establishing an " | |||||||||||
"already established hook.\n"); | "already established hook.\n"); | |||||||||||
return (1); | return (1); | |||||||||||
} | } | |||||||||||
STAILQ_INSERT_TAIL(&intr_config_hook_list, hook, ich_links); | STAILQ_INSERT_TAIL(&intr_config_hook_list, hook, ich_links); | |||||||||||
if (next_to_notify == NULL) | if (next_to_notify == NULL) | |||||||||||
next_to_notify = hook; | next_to_notify = hook; | |||||||||||
hook_entry->ich_state = ICHS_QUEUED; | ||||||||||||
mtx_unlock(&intr_config_hook_lock); | mtx_unlock(&intr_config_hook_lock); | |||||||||||
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(); | |||||||||||
Show All 11 Lines | config_intrhook_oneshot(ich_func_t func, void *arg) | |||||||||||
ohook = malloc(sizeof(*ohook), M_DEVBUF, M_WAITOK); | ohook = malloc(sizeof(*ohook), M_DEVBUF, M_WAITOK); | |||||||||||
ohook->och_func = func; | ohook->och_func = func; | |||||||||||
ohook->och_arg = arg; | ohook->och_arg = arg; | |||||||||||
ohook->och_hook.ich_func = config_intrhook_oneshot_func; | ohook->och_hook.ich_func = config_intrhook_oneshot_func; | |||||||||||
ohook->och_hook.ich_arg = ohook; | ohook->och_hook.ich_arg = ohook; | |||||||||||
config_intrhook_establish(&ohook->och_hook); | config_intrhook_establish(&ohook->och_hook); | |||||||||||
} | } | |||||||||||
void | static void | |||||||||||
config_intrhook_disestablish(struct intr_config_hook *hook) | config_intrhook_disestablish_locked(struct intr_config_hook *hook) | |||||||||||
{ | { | |||||||||||
struct intr_config_hook *hook_entry; | struct intr_config_hook *hook_entry; | |||||||||||
mtx_lock(&intr_config_hook_lock); | ||||||||||||
STAILQ_FOREACH(hook_entry, &intr_config_hook_list, ich_links) | STAILQ_FOREACH(hook_entry, &intr_config_hook_list, ich_links) | |||||||||||
if (hook_entry == hook) | if (hook_entry == hook) | |||||||||||
break; | break; | |||||||||||
if (hook_entry == NULL) | if (hook_entry == NULL) | |||||||||||
panic("config_intrhook_disestablish: disestablishing an " | panic("config_intrhook_disestablish: disestablishing an " | |||||||||||
"unestablished hook"); | "unestablished hook"); | |||||||||||
if (next_to_notify == hook) | if (next_to_notify == hook) | |||||||||||
next_to_notify = STAILQ_NEXT(hook, ich_links); | next_to_notify = STAILQ_NEXT(hook, ich_links); | |||||||||||
STAILQ_REMOVE(&intr_config_hook_list, hook, intr_config_hook, ich_links); | STAILQ_REMOVE(&intr_config_hook_list, hook, intr_config_hook, ich_links); | |||||||||||
TSRELEASE("config hooks"); | TSRELEASE("config hooks"); | |||||||||||
/* Wakeup anyone watching the list */ | /* Wakeup anyone watching the list */ | |||||||||||
hook->ich_state = ICHS_DONE; | ||||||||||||
wakeup(&intr_config_hook_list); | wakeup(&intr_config_hook_list); | |||||||||||
} | ||||||||||||
void | ||||||||||||
config_intrhook_disestablish(struct intr_config_hook *hook) | ||||||||||||
{ | ||||||||||||
mtx_lock(&intr_config_hook_lock); | ||||||||||||
config_intrhook_disestablish_locked(hook); | ||||||||||||
mtx_unlock(&intr_config_hook_lock); | mtx_unlock(&intr_config_hook_lock); | |||||||||||
} | ||||||||||||
int | ||||||||||||
config_intrhook_drain(struct intr_config_hook *hook) | ||||||||||||
{ | ||||||||||||
mtx_lock(&intr_config_hook_lock); | ||||||||||||
/* | ||||||||||||
* The config hook has completed, so just return. | ||||||||||||
*/ | ||||||||||||
if (hook->ich_state == ICHS_DONE) { | ||||||||||||
mtx_unlock(&intr_config_hook_lock); | ||||||||||||
return (ICHS_DONE); | ||||||||||||
} | ||||||||||||
/* | ||||||||||||
* The config hook is hasn't started running, just call disestablish. | ||||||||||||
jhbUnsubmitted Done Inline Actions
jhb: | ||||||||||||
*/ | ||||||||||||
if (hook->ich_state == ICHS_QUEUED) { | ||||||||||||
config_intrhook_disestablish_locked(hook); | ||||||||||||
mtx_unlock(&intr_config_hook_lock); | ||||||||||||
return (ICHS_QUEUED); | ||||||||||||
} | ||||||||||||
/* | ||||||||||||
* The config hook is running, so wait for it to complete and return. | ||||||||||||
*/ | ||||||||||||
while (hook->ich_state != ICHS_DONE) { | ||||||||||||
if (msleep(&intr_config_hook_list, &intr_config_hook_lock, | ||||||||||||
0, "confhd", hz) == EWOULDBLOCK) { | ||||||||||||
// XXX do I whine? | ||||||||||||
} | ||||||||||||
} | ||||||||||||
mtx_unlock(&intr_config_hook_lock); | ||||||||||||
return (ICHS_RUNNING); | ||||||||||||
} | } | |||||||||||
#ifdef DDB | #ifdef DDB | |||||||||||
#include <ddb/ddb.h> | #include <ddb/ddb.h> | |||||||||||
DB_SHOW_COMMAND(conifhk, db_show_conifhk) | DB_SHOW_COMMAND(conifhk, db_show_conifhk) | |||||||||||
{ | { | |||||||||||
struct intr_config_hook *hook_entry; | struct intr_config_hook *hook_entry; | |||||||||||
Show All 17 Lines |