subr_autoconf.c revision 160509
197403Sobrien/*- 297403Sobrien * Copyright (c) 1992, 1993 397403Sobrien * The Regents of the University of California. All rights reserved. 497403Sobrien * 597403Sobrien * This software was developed by the Computer Systems Engineering group 697403Sobrien * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 797403Sobrien * contributed to Berkeley. 897403Sobrien * 997403Sobrien * Redistribution and use in source and binary forms, with or without 1097403Sobrien * modification, are permitted provided that the following conditions 1197403Sobrien * are met: 1297403Sobrien * 1. Redistributions of source code must retain the above copyright 1397403Sobrien * notice, this list of conditions and the following disclaimer. 1497403Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1597403Sobrien * notice, this list of conditions and the following disclaimer in the 1697403Sobrien * documentation and/or other materials provided with the distribution. 1797403Sobrien * 4. Neither the name of the University nor the names of its contributors 18169691Skan * may be used to endorse or promote products derived from this software 1997403Sobrien * without specific prior written permission. 2097403Sobrien * 2197403Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2297403Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2397403Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2497403Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2597403Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2697403Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2797403Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2897403Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2997403Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3097403Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3197403Sobrien * SUCH DAMAGE. 3297403Sobrien * 3397403Sobrien * @(#)subr_autoconf.c 8.1 (Berkeley) 6/10/93 3497403Sobrien * 3597403Sobrien */ 3697403Sobrien 3797403Sobrien#include <sys/cdefs.h> 3897403Sobrien__FBSDID("$FreeBSD: head/sys/kern/subr_autoconf.c 160509 2006-07-19 18:53:56Z jhb $"); 3997403Sobrien 4097403Sobrien#include <sys/param.h> 4197403Sobrien#include <sys/kernel.h> 4297403Sobrien#include <sys/lock.h> 4397403Sobrien#include <sys/mutex.h> 4497403Sobrien#include <sys/systm.h> 4597403Sobrien 4697403Sobrien/* 4797403Sobrien * Autoconfiguration subroutines. 4897403Sobrien */ 4997403Sobrien 5097403Sobrien/* 5197403Sobrien * "Interrupt driven config" functions. 5297403Sobrien */ 5397403Sobrienstatic TAILQ_HEAD(, intr_config_hook) intr_config_hook_list = 5497403Sobrien TAILQ_HEAD_INITIALIZER(intr_config_hook_list); 5597403Sobrienstatic struct mtx intr_config_hook_lock; 5697403SobrienMTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, "intr config", MTX_DEF); 5797403Sobrien 5897403Sobrien/* ARGSUSED */ 5997403Sobrienstatic void run_interrupt_driven_config_hooks(void *dummy); 6097403Sobrien 6197403Sobrienstatic void 6297403Sobrienrun_interrupt_driven_config_hooks(dummy) 6397403Sobrien void *dummy; 64132720Skan{ 6597403Sobrien struct intr_config_hook *hook_entry, *next_entry; 6697403Sobrien 6797403Sobrien mtx_lock(&intr_config_hook_lock); 6897403Sobrien TAILQ_FOREACH_SAFE(hook_entry, &intr_config_hook_list, ich_links, 6997403Sobrien next_entry) { 7097403Sobrien next_entry = TAILQ_NEXT(hook_entry, ich_links); 7197403Sobrien mtx_unlock(&intr_config_hook_lock); 7297403Sobrien (*hook_entry->ich_func)(hook_entry->ich_arg); 7397403Sobrien mtx_lock(&intr_config_hook_lock); 7497403Sobrien } 7597403Sobrien 7697403Sobrien while (!TAILQ_EMPTY(&intr_config_hook_list)) { 7797403Sobrien msleep(&intr_config_hook_list, &intr_config_hook_lock, PCONFIG, 7897403Sobrien "conifhk", 0); 7997403Sobrien } 8097403Sobrien mtx_unlock(&intr_config_hook_lock); 8197403Sobrien} 8297403SobrienSYSINIT(intr_config_hooks, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_FIRST, 8397403Sobrien run_interrupt_driven_config_hooks, NULL) 8497403Sobrien 8597403Sobrien/* 8697403Sobrien * Register a hook that will be called after "cold" 8797403Sobrien * autoconfiguration is complete and interrupts can 8897403Sobrien * be used to complete initialization. 8997403Sobrien */ 9097403Sobrienint 9197403Sobrienconfig_intrhook_establish(hook) 9297403Sobrien struct intr_config_hook *hook; 9397403Sobrien{ 94132720Skan struct intr_config_hook *hook_entry; 9597403Sobrien 9697403Sobrien mtx_lock(&intr_config_hook_lock); 9797403Sobrien TAILQ_FOREACH(hook_entry, &intr_config_hook_list, ich_links) 9897403Sobrien if (hook_entry == hook) 9997403Sobrien break; 10097403Sobrien if (hook_entry != NULL) { 10197403Sobrien mtx_unlock(&intr_config_hook_lock); 10297403Sobrien printf("config_intrhook_establish: establishing an " 10397403Sobrien "already established hook.\n"); 10497403Sobrien return (1); 10597403Sobrien } 10697403Sobrien TAILQ_INSERT_TAIL(&intr_config_hook_list, hook, ich_links); 10797403Sobrien mtx_unlock(&intr_config_hook_lock); 10897403Sobrien if (cold == 0) 10997403Sobrien /* XXX Sufficient for modules loaded after initial config??? */ 11097403Sobrien run_interrupt_driven_config_hooks(NULL); 11197403Sobrien return (0); 11297403Sobrien} 113 114void 115config_intrhook_disestablish(hook) 116 struct intr_config_hook *hook; 117{ 118 struct intr_config_hook *hook_entry; 119 120 mtx_lock(&intr_config_hook_lock); 121 TAILQ_FOREACH(hook_entry, &intr_config_hook_list, ich_links) 122 if (hook_entry == hook) 123 break; 124 if (hook_entry == NULL) 125 panic("config_intrhook_disestablish: disestablishing an " 126 "unestablished hook"); 127 128 TAILQ_REMOVE(&intr_config_hook_list, hook, ich_links); 129 130 /* Wakeup anyone watching the list */ 131 wakeup(&intr_config_hook_list); 132 mtx_unlock(&intr_config_hook_lock); 133} 134