subr_autoconf.c revision 160509
1139804Simp/*- 21541Srgrimes * Copyright (c) 1992, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * This software was developed by the Computer Systems Engineering group 61541Srgrimes * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 71541Srgrimes * contributed to Berkeley. 81541Srgrimes * 91541Srgrimes * Redistribution and use in source and binary forms, with or without 101541Srgrimes * modification, are permitted provided that the following conditions 111541Srgrimes * are met: 121541Srgrimes * 1. Redistributions of source code must retain the above copyright 131541Srgrimes * notice, this list of conditions and the following disclaimer. 141541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 151541Srgrimes * notice, this list of conditions and the following disclaimer in the 161541Srgrimes * documentation and/or other materials provided with the distribution. 171541Srgrimes * 4. Neither the name of the University nor the names of its contributors 181541Srgrimes * may be used to endorse or promote products derived from this software 191541Srgrimes * without specific prior written permission. 201541Srgrimes * 211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311541Srgrimes * SUCH DAMAGE. 321541Srgrimes * 331541Srgrimes * @(#)subr_autoconf.c 8.1 (Berkeley) 6/10/93 341541Srgrimes * 351541Srgrimes */ 361541Srgrimes 37116182Sobrien#include <sys/cdefs.h> 38116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/subr_autoconf.c 160509 2006-07-19 18:53:56Z jhb $"); 39116182Sobrien 401541Srgrimes#include <sys/param.h> 4129680Sgibbs#include <sys/kernel.h> 42160509Sjhb#include <sys/lock.h> 43160509Sjhb#include <sys/mutex.h> 4429680Sgibbs#include <sys/systm.h> 451541Srgrimes 461541Srgrimes/* 471541Srgrimes * Autoconfiguration subroutines. 481541Srgrimes */ 491541Srgrimes 501541Srgrimes/* 5129680Sgibbs * "Interrupt driven config" functions. 5229680Sgibbs */ 5360938Sjakestatic TAILQ_HEAD(, intr_config_hook) intr_config_hook_list = 5429680Sgibbs TAILQ_HEAD_INITIALIZER(intr_config_hook_list); 55160509Sjhbstatic struct mtx intr_config_hook_lock; 56160509SjhbMTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, "intr config", MTX_DEF); 5729680Sgibbs 5829680Sgibbs/* ARGSUSED */ 5992723Salfredstatic void run_interrupt_driven_config_hooks(void *dummy); 60160509Sjhb 6129680Sgibbsstatic void 6229680Sgibbsrun_interrupt_driven_config_hooks(dummy) 6329680Sgibbs void *dummy; 6429680Sgibbs{ 6551684Sn_hibma struct intr_config_hook *hook_entry, *next_entry; 6629680Sgibbs 67160509Sjhb mtx_lock(&intr_config_hook_lock); 68160509Sjhb TAILQ_FOREACH_SAFE(hook_entry, &intr_config_hook_list, ich_links, 69160509Sjhb next_entry) { 7051684Sn_hibma next_entry = TAILQ_NEXT(hook_entry, ich_links); 71160509Sjhb mtx_unlock(&intr_config_hook_lock); 7251684Sn_hibma (*hook_entry->ich_func)(hook_entry->ich_arg); 73160509Sjhb mtx_lock(&intr_config_hook_lock); 7429680Sgibbs } 7529680Sgibbs 7651684Sn_hibma while (!TAILQ_EMPTY(&intr_config_hook_list)) { 77160509Sjhb msleep(&intr_config_hook_list, &intr_config_hook_lock, PCONFIG, 78160509Sjhb "conifhk", 0); 7929680Sgibbs } 80160509Sjhb mtx_unlock(&intr_config_hook_lock); 8129680Sgibbs} 8229680SgibbsSYSINIT(intr_config_hooks, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_FIRST, 8329680Sgibbs run_interrupt_driven_config_hooks, NULL) 8429680Sgibbs 8529680Sgibbs/* 8629680Sgibbs * Register a hook that will be called after "cold" 8729680Sgibbs * autoconfiguration is complete and interrupts can 8829680Sgibbs * be used to complete initialization. 8929680Sgibbs */ 9029680Sgibbsint 9129680Sgibbsconfig_intrhook_establish(hook) 9229680Sgibbs struct intr_config_hook *hook; 9329680Sgibbs{ 9429680Sgibbs struct intr_config_hook *hook_entry; 9529680Sgibbs 96160509Sjhb mtx_lock(&intr_config_hook_lock); 97160509Sjhb TAILQ_FOREACH(hook_entry, &intr_config_hook_list, ich_links) 9829680Sgibbs if (hook_entry == hook) 9929680Sgibbs break; 10029680Sgibbs if (hook_entry != NULL) { 101160509Sjhb mtx_unlock(&intr_config_hook_lock); 10229680Sgibbs printf("config_intrhook_establish: establishing an " 10329680Sgibbs "already established hook.\n"); 10429680Sgibbs return (1); 10529680Sgibbs } 10629680Sgibbs TAILQ_INSERT_TAIL(&intr_config_hook_list, hook, ich_links); 107160509Sjhb mtx_unlock(&intr_config_hook_lock); 10829680Sgibbs if (cold == 0) 10945739Speter /* XXX Sufficient for modules loaded after initial config??? */ 11029680Sgibbs run_interrupt_driven_config_hooks(NULL); 11129680Sgibbs return (0); 11229680Sgibbs} 11329680Sgibbs 11429680Sgibbsvoid 11529680Sgibbsconfig_intrhook_disestablish(hook) 11629680Sgibbs struct intr_config_hook *hook; 11729680Sgibbs{ 11829680Sgibbs struct intr_config_hook *hook_entry; 11929680Sgibbs 120160509Sjhb mtx_lock(&intr_config_hook_lock); 121160509Sjhb TAILQ_FOREACH(hook_entry, &intr_config_hook_list, ich_links) 12229680Sgibbs if (hook_entry == hook) 12329680Sgibbs break; 12429680Sgibbs if (hook_entry == NULL) 12529680Sgibbs panic("config_intrhook_disestablish: disestablishing an " 12629680Sgibbs "unestablished hook"); 12729680Sgibbs 12829680Sgibbs TAILQ_REMOVE(&intr_config_hook_list, hook, ich_links); 129160509Sjhb 13029680Sgibbs /* Wakeup anyone watching the list */ 13129680Sgibbs wakeup(&intr_config_hook_list); 132160509Sjhb mtx_unlock(&intr_config_hook_lock); 13329680Sgibbs} 134