subr_autoconf.c revision 116182
11541Srgrimes/*
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 * All advertising materials mentioning features or use of this software
101541Srgrimes * must display the following acknowledgement:
111541Srgrimes *	This product includes software developed by the University of
121541Srgrimes *	California, Lawrence Berkeley Laboratories.
131541Srgrimes *
141541Srgrimes * Redistribution and use in source and binary forms, with or without
151541Srgrimes * modification, are permitted provided that the following conditions
161541Srgrimes * are met:
171541Srgrimes * 1. Redistributions of source code must retain the above copyright
181541Srgrimes *    notice, this list of conditions and the following disclaimer.
191541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
201541Srgrimes *    notice, this list of conditions and the following disclaimer in the
211541Srgrimes *    documentation and/or other materials provided with the distribution.
221541Srgrimes * 3. All advertising materials mentioning features or use of this software
231541Srgrimes *    must display the following acknowledgement:
241541Srgrimes *	This product includes software developed by the University of
251541Srgrimes *	California, Berkeley and its contributors.
261541Srgrimes * 4. Neither the name of the University nor the names of its contributors
271541Srgrimes *    may be used to endorse or promote products derived from this software
281541Srgrimes *    without specific prior written permission.
291541Srgrimes *
301541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
311541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
321541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
331541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
341541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
351541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
361541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
371541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
381541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
391541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
401541Srgrimes * SUCH DAMAGE.
411541Srgrimes *
421541Srgrimes *	@(#)subr_autoconf.c	8.1 (Berkeley) 6/10/93
431541Srgrimes *
441541Srgrimes */
451541Srgrimes
46116182Sobrien#include <sys/cdefs.h>
47116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/subr_autoconf.c 116182 2003-06-11 00:56:59Z obrien $");
48116182Sobrien
491541Srgrimes#include <sys/param.h>
5029680Sgibbs#include <sys/kernel.h>
5129680Sgibbs#include <sys/systm.h>
521541Srgrimes
531541Srgrimes/*
541541Srgrimes * Autoconfiguration subroutines.
551541Srgrimes */
561541Srgrimes
571541Srgrimes/*
5829680Sgibbs * "Interrupt driven config" functions.
5929680Sgibbs */
6060938Sjakestatic TAILQ_HEAD(, intr_config_hook) intr_config_hook_list =
6129680Sgibbs	TAILQ_HEAD_INITIALIZER(intr_config_hook_list);
6229680Sgibbs
6329680Sgibbs
6429680Sgibbs/* ARGSUSED */
6592723Salfredstatic void run_interrupt_driven_config_hooks(void *dummy);
6629680Sgibbsstatic void
6729680Sgibbsrun_interrupt_driven_config_hooks(dummy)
6829680Sgibbs	void *dummy;
6929680Sgibbs{
7051684Sn_hibma	struct intr_config_hook *hook_entry, *next_entry;
7129680Sgibbs
7251684Sn_hibma	for (hook_entry = TAILQ_FIRST(&intr_config_hook_list);
7351684Sn_hibma	     hook_entry != NULL;
7451684Sn_hibma	     hook_entry = next_entry) {
7551684Sn_hibma		next_entry = TAILQ_NEXT(hook_entry, ich_links);
7651684Sn_hibma		(*hook_entry->ich_func)(hook_entry->ich_arg);
7729680Sgibbs	}
7829680Sgibbs
7951684Sn_hibma	while (!TAILQ_EMPTY(&intr_config_hook_list)) {
8029680Sgibbs		tsleep(&intr_config_hook_list, PCONFIG, "conifhk", 0);
8129680Sgibbs	}
8229680Sgibbs}
8329680SgibbsSYSINIT(intr_config_hooks, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_FIRST,
8429680Sgibbs	run_interrupt_driven_config_hooks, NULL)
8529680Sgibbs
8629680Sgibbs/*
8729680Sgibbs * Register a hook that will be called after "cold"
8829680Sgibbs * autoconfiguration is complete and interrupts can
8929680Sgibbs * be used to complete initialization.
9029680Sgibbs */
9129680Sgibbsint
9229680Sgibbsconfig_intrhook_establish(hook)
9329680Sgibbs	struct intr_config_hook *hook;
9429680Sgibbs{
9529680Sgibbs	struct intr_config_hook *hook_entry;
9629680Sgibbs
9751684Sn_hibma	for (hook_entry = TAILQ_FIRST(&intr_config_hook_list);
9851684Sn_hibma	     hook_entry != NULL;
9951684Sn_hibma	     hook_entry = TAILQ_NEXT(hook_entry, ich_links))
10029680Sgibbs		if (hook_entry == hook)
10129680Sgibbs			break;
10229680Sgibbs	if (hook_entry != NULL) {
10329680Sgibbs		printf("config_intrhook_establish: establishing an "
10429680Sgibbs		       "already established hook.\n");
10529680Sgibbs		return (1);
10629680Sgibbs	}
10729680Sgibbs	TAILQ_INSERT_TAIL(&intr_config_hook_list, hook, ich_links);
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
12051684Sn_hibma	for (hook_entry = TAILQ_FIRST(&intr_config_hook_list);
12151684Sn_hibma	     hook_entry != NULL;
12251684Sn_hibma	     hook_entry = TAILQ_NEXT(hook_entry, ich_links))
12329680Sgibbs		if (hook_entry == hook)
12429680Sgibbs			break;
12529680Sgibbs	if (hook_entry == NULL)
12629680Sgibbs		panic("config_intrhook_disestablish: disestablishing an "
12729680Sgibbs		      "unestablished hook");
12829680Sgibbs
12929680Sgibbs	TAILQ_REMOVE(&intr_config_hook_list, hook, ich_links);
13029680Sgibbs	/* Wakeup anyone watching the list */
13129680Sgibbs	wakeup(&intr_config_hook_list);
13229680Sgibbs}
133