xref: /netbsd-src/sys/kern/subr_autoconf.c (revision 9c1da17e908379b8a470f1117a6395bd6a0ca559)
1 /* $NetBSD: subr_autoconf.c,v 1.95 2005/06/28 18:37:34 drochner Exp $ */
2 
3 /*
4  * Copyright (c) 1996, 2000 Christopher G. Demetriou
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *          This product includes software developed for the
18  *          NetBSD Project.  See http://www.NetBSD.org/ for
19  *          information about NetBSD.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
35  */
36 
37 /*
38  * Copyright (c) 1992, 1993
39  *	The Regents of the University of California.  All rights reserved.
40  *
41  * This software was developed by the Computer Systems Engineering group
42  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
43  * contributed to Berkeley.
44  *
45  * All advertising materials mentioning features or use of this software
46  * must display the following acknowledgement:
47  *	This product includes software developed by the University of
48  *	California, Lawrence Berkeley Laboratories.
49  *
50  * Redistribution and use in source and binary forms, with or without
51  * modification, are permitted provided that the following conditions
52  * are met:
53  * 1. Redistributions of source code must retain the above copyright
54  *    notice, this list of conditions and the following disclaimer.
55  * 2. Redistributions in binary form must reproduce the above copyright
56  *    notice, this list of conditions and the following disclaimer in the
57  *    documentation and/or other materials provided with the distribution.
58  * 3. Neither the name of the University nor the names of its contributors
59  *    may be used to endorse or promote products derived from this software
60  *    without specific prior written permission.
61  *
62  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72  * SUCH DAMAGE.
73  *
74  * from: Header: subr_autoconf.c,v 1.12 93/02/01 19:31:48 torek Exp  (LBL)
75  *
76  *	@(#)subr_autoconf.c	8.3 (Berkeley) 5/17/94
77  */
78 
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.95 2005/06/28 18:37:34 drochner Exp $");
81 
82 #include "opt_ddb.h"
83 
84 #include <sys/param.h>
85 #include <sys/device.h>
86 #include <sys/malloc.h>
87 #include <sys/systm.h>
88 #include <sys/kernel.h>
89 #include <sys/errno.h>
90 #include <sys/proc.h>
91 #include <sys/reboot.h>
92 #include <machine/limits.h>
93 
94 #include "opt_userconf.h"
95 #ifdef USERCONF
96 #include <sys/userconf.h>
97 #endif
98 
99 /*
100  * Autoconfiguration subroutines.
101  */
102 
103 /*
104  * ioconf.c exports exactly two names: cfdata and cfroots.  All system
105  * devices and drivers are found via these tables.
106  */
107 extern struct cfdata cfdata[];
108 extern const short cfroots[];
109 
110 /*
111  * List of all cfdriver structures.  We use this to detect duplicates
112  * when other cfdrivers are loaded.
113  */
114 struct cfdriverlist allcfdrivers = LIST_HEAD_INITIALIZER(&allcfdrivers);
115 extern struct cfdriver * const cfdriver_list_initial[];
116 
117 /*
118  * Initial list of cfattach's.
119  */
120 extern const struct cfattachinit cfattachinit[];
121 
122 /*
123  * List of cfdata tables.  We always have one such list -- the one
124  * built statically when the kernel was configured.
125  */
126 struct cftablelist allcftables;
127 static struct cftable initcftable;
128 
129 /*
130  * Database of device properties.
131  */
132 propdb_t dev_propdb;
133 
134 #define	ROOT ((struct device *)NULL)
135 
136 struct matchinfo {
137 	cfsubmatch_t fn_loc;
138 	struct	device *parent;
139 	const locdesc_t *ldesc;
140 	void	*aux;
141 	struct	cfdata *match;
142 	int	pri;
143 };
144 
145 static char *number(char *, int);
146 static void mapply(struct matchinfo *, struct cfdata *);
147 
148 struct deferred_config {
149 	TAILQ_ENTRY(deferred_config) dc_queue;
150 	struct device *dc_dev;
151 	void (*dc_func)(struct device *);
152 };
153 
154 TAILQ_HEAD(deferred_config_head, deferred_config);
155 
156 struct deferred_config_head deferred_config_queue;
157 struct deferred_config_head interrupt_config_queue;
158 
159 static void config_process_deferred(struct deferred_config_head *,
160 	struct device *);
161 
162 /* Hooks to finalize configuration once all real devices have been found. */
163 struct finalize_hook {
164 	TAILQ_ENTRY(finalize_hook) f_list;
165 	int (*f_func)(struct device *);
166 	struct device *f_dev;
167 };
168 static TAILQ_HEAD(, finalize_hook) config_finalize_list;
169 static int config_finalize_done;
170 
171 /* list of all devices */
172 struct devicelist alldevs;
173 
174 __volatile int config_pending;		/* semaphore for mountroot */
175 
176 #define	STREQ(s1, s2)			\
177 	(*(s1) == *(s2) && strcmp((s1), (s2)) == 0)
178 
179 static int config_initialized;		/* config_init() has been called. */
180 
181 static int config_do_twiddle;
182 
183 /*
184  * Initialize the autoconfiguration data structures.  Normally this
185  * is done by configure(), but some platforms need to do this very
186  * early (to e.g. initialize the console).
187  */
188 void
189 config_init(void)
190 {
191 	const struct cfattachinit *cfai;
192 	int i, j;
193 
194 	if (config_initialized)
195 		return;
196 
197 	/* allcfdrivers is statically initialized. */
198 	for (i = 0; cfdriver_list_initial[i] != NULL; i++) {
199 		if (config_cfdriver_attach(cfdriver_list_initial[i]) != 0)
200 			panic("configure: duplicate `%s' drivers",
201 			    cfdriver_list_initial[i]->cd_name);
202 	}
203 
204 	for (cfai = &cfattachinit[0]; cfai->cfai_name != NULL; cfai++) {
205 		for (j = 0; cfai->cfai_list[j] != NULL; j++) {
206 			if (config_cfattach_attach(cfai->cfai_name,
207 						   cfai->cfai_list[j]) != 0)
208 				panic("configure: duplicate `%s' attachment "
209 				    "of `%s' driver",
210 				    cfai->cfai_list[j]->ca_name,
211 				    cfai->cfai_name);
212 		}
213 	}
214 
215 	TAILQ_INIT(&allcftables);
216 	initcftable.ct_cfdata = cfdata;
217 	TAILQ_INSERT_TAIL(&allcftables, &initcftable, ct_list);
218 
219 	TAILQ_INIT(&deferred_config_queue);
220 	TAILQ_INIT(&interrupt_config_queue);
221 	TAILQ_INIT(&config_finalize_list);
222 	TAILQ_INIT(&alldevs);
223 
224 	config_initialized = 1;
225 }
226 
227 /*
228  * Configure the system's hardware.
229  */
230 void
231 configure(void)
232 {
233 	int errcnt;
234 
235 	/* Initialize data structures. */
236 	config_init();
237 
238 	/* Initialize the device property database. */
239 	dev_propdb = propdb_create("device properties");
240 	if (dev_propdb == NULL)
241 		panic("unable to create device property database");
242 
243 #ifdef USERCONF
244 	if (boothowto & RB_USERCONF)
245 		user_config();
246 #endif
247 
248 	if ((boothowto & (AB_SILENT|AB_VERBOSE)) == AB_SILENT) {
249 		config_do_twiddle = 1;
250 		printf_nolog("Detecting hardware...");
251 	}
252 
253 	/*
254 	 * Do the machine-dependent portion of autoconfiguration.  This
255 	 * sets the configuration machinery here in motion by "finding"
256 	 * the root bus.  When this function returns, we expect interrupts
257 	 * to be enabled.
258 	 */
259 	cpu_configure();
260 
261 	/*
262 	 * Now that we've found all the hardware, start the real time
263 	 * and statistics clocks.
264 	 */
265 	initclocks();
266 
267 	cold = 0;	/* clocks are running, we're warm now! */
268 
269 	/*
270 	 * Now callback to finish configuration for devices which want
271 	 * to do this once interrupts are enabled.
272 	 */
273 	config_process_deferred(&interrupt_config_queue, NULL);
274 
275 	errcnt = aprint_get_error_count();
276 	if ((boothowto & (AB_QUIET|AB_SILENT)) != 0 &&
277 	    (boothowto & AB_VERBOSE) == 0) {
278 		if (config_do_twiddle) {
279 			config_do_twiddle = 0;
280 			printf_nolog("done.\n");
281 		}
282 		if (errcnt != 0) {
283 			printf("WARNING: %d error%s while detecting hardware; "
284 			    "check system log.\n", errcnt,
285 			    errcnt == 1 ? "" : "s");
286 		}
287 	}
288 }
289 
290 /*
291  * Add a cfdriver to the system.
292  */
293 int
294 config_cfdriver_attach(struct cfdriver *cd)
295 {
296 	struct cfdriver *lcd;
297 
298 	/* Make sure this driver isn't already in the system. */
299 	LIST_FOREACH(lcd, &allcfdrivers, cd_list) {
300 		if (STREQ(lcd->cd_name, cd->cd_name))
301 			return (EEXIST);
302 	}
303 
304 	LIST_INIT(&cd->cd_attach);
305 	LIST_INSERT_HEAD(&allcfdrivers, cd, cd_list);
306 
307 	return (0);
308 }
309 
310 /*
311  * Remove a cfdriver from the system.
312  */
313 int
314 config_cfdriver_detach(struct cfdriver *cd)
315 {
316 	int i;
317 
318 	/* Make sure there are no active instances. */
319 	for (i = 0; i < cd->cd_ndevs; i++) {
320 		if (cd->cd_devs[i] != NULL)
321 			return (EBUSY);
322 	}
323 
324 	/* ...and no attachments loaded. */
325 	if (LIST_EMPTY(&cd->cd_attach) == 0)
326 		return (EBUSY);
327 
328 	LIST_REMOVE(cd, cd_list);
329 
330 	KASSERT(cd->cd_devs == NULL);
331 
332 	return (0);
333 }
334 
335 /*
336  * Look up a cfdriver by name.
337  */
338 struct cfdriver *
339 config_cfdriver_lookup(const char *name)
340 {
341 	struct cfdriver *cd;
342 
343 	LIST_FOREACH(cd, &allcfdrivers, cd_list) {
344 		if (STREQ(cd->cd_name, name))
345 			return (cd);
346 	}
347 
348 	return (NULL);
349 }
350 
351 /*
352  * Add a cfattach to the specified driver.
353  */
354 int
355 config_cfattach_attach(const char *driver, struct cfattach *ca)
356 {
357 	struct cfattach *lca;
358 	struct cfdriver *cd;
359 
360 	cd = config_cfdriver_lookup(driver);
361 	if (cd == NULL)
362 		return (ESRCH);
363 
364 	/* Make sure this attachment isn't already on this driver. */
365 	LIST_FOREACH(lca, &cd->cd_attach, ca_list) {
366 		if (STREQ(lca->ca_name, ca->ca_name))
367 			return (EEXIST);
368 	}
369 
370 	LIST_INSERT_HEAD(&cd->cd_attach, ca, ca_list);
371 
372 	return (0);
373 }
374 
375 /*
376  * Remove a cfattach from the specified driver.
377  */
378 int
379 config_cfattach_detach(const char *driver, struct cfattach *ca)
380 {
381 	struct cfdriver *cd;
382 	struct device *dev;
383 	int i;
384 
385 	cd = config_cfdriver_lookup(driver);
386 	if (cd == NULL)
387 		return (ESRCH);
388 
389 	/* Make sure there are no active instances. */
390 	for (i = 0; i < cd->cd_ndevs; i++) {
391 		if ((dev = cd->cd_devs[i]) == NULL)
392 			continue;
393 		if (dev->dv_cfattach == ca)
394 			return (EBUSY);
395 	}
396 
397 	LIST_REMOVE(ca, ca_list);
398 
399 	return (0);
400 }
401 
402 /*
403  * Look up a cfattach by name.
404  */
405 static struct cfattach *
406 config_cfattach_lookup_cd(struct cfdriver *cd, const char *atname)
407 {
408 	struct cfattach *ca;
409 
410 	LIST_FOREACH(ca, &cd->cd_attach, ca_list) {
411 		if (STREQ(ca->ca_name, atname))
412 			return (ca);
413 	}
414 
415 	return (NULL);
416 }
417 
418 /*
419  * Look up a cfattach by driver/attachment name.
420  */
421 struct cfattach *
422 config_cfattach_lookup(const char *name, const char *atname)
423 {
424 	struct cfdriver *cd;
425 
426 	cd = config_cfdriver_lookup(name);
427 	if (cd == NULL)
428 		return (NULL);
429 
430 	return (config_cfattach_lookup_cd(cd, atname));
431 }
432 
433 /*
434  * Apply the matching function and choose the best.  This is used
435  * a few times and we want to keep the code small.
436  */
437 static void
438 mapply(struct matchinfo *m, struct cfdata *cf)
439 {
440 	int pri;
441 
442 	if (m->fn_loc != NULL) {
443 		pri = (*m->fn_loc)(m->parent, cf, m->ldesc, m->aux);
444 	} else {
445 		struct cfattach *ca;
446 
447 		ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
448 		if (ca == NULL) {
449 			/* No attachment for this entry, oh well. */
450 			return;
451 		}
452 	        KASSERT(ca->ca_match != NULL);
453 		pri = (*ca->ca_match)(m->parent, cf, m->aux);
454 	}
455 	if (pri > m->pri) {
456 		m->match = cf;
457 		m->pri = pri;
458 	}
459 }
460 
461 /*
462  * Helper function: check whether the driver supports the interface attribute.
463  */
464 static int
465 cfdriver_has_iattr(const struct cfdriver *cd, const char *ia)
466 {
467 	const char * const *cpp;
468 
469 	if (cd->cd_attrs == NULL)
470 		return (0);
471 
472 	for (cpp = cd->cd_attrs; *cpp; cpp++) {
473 		if (STREQ(*cpp, ia)) {
474 			/* Match. */
475 			return (1);
476 		}
477 	}
478 	return (0);
479 }
480 
481 /*
482  * Determine if `parent' is a potential parent for a device spec based
483  * on `cfp'.
484  */
485 static int
486 cfparent_match(const struct device *parent, const struct cfparent *cfp)
487 {
488 	struct cfdriver *pcd;
489 
490 	/* We don't match root nodes here. */
491 	if (cfp == NULL)
492 		return (0);
493 
494 	pcd = parent->dv_cfdriver;
495 	KASSERT(pcd != NULL);
496 
497 	/*
498 	 * First, ensure this parent has the correct interface
499 	 * attribute.
500 	 */
501 	if (!cfdriver_has_iattr(pcd, cfp->cfp_iattr))
502 		return (0);
503 
504 	/*
505 	 * If no specific parent device instance was specified (i.e.
506 	 * we're attaching to the attribute only), we're done!
507 	 */
508 	if (cfp->cfp_parent == NULL)
509 		return (1);
510 
511 	/*
512 	 * Check the parent device's name.
513 	 */
514 	if (STREQ(pcd->cd_name, cfp->cfp_parent) == 0)
515 		return (0);	/* not the same parent */
516 
517 	/*
518 	 * Make sure the unit number matches.
519 	 */
520 	if (cfp->cfp_unit == DVUNIT_ANY ||	/* wildcard */
521 	    cfp->cfp_unit == parent->dv_unit)
522 		return (1);
523 
524 	/* Unit numbers don't match. */
525 	return (0);
526 }
527 
528 /*
529  * Helper for config_cfdata_attach(): check all devices whether it could be
530  * parent any attachment in the config data table passed, and rescan.
531  */
532 static void
533 rescan_with_cfdata(const struct cfdata *cf)
534 {
535 	struct device *d;
536 	const struct cfdata *cf1;
537 
538 	/*
539 	 * "alldevs" is likely longer than an LKM's cfdata, so make it
540 	 * the outer loop.
541 	 */
542 	TAILQ_FOREACH(d, &alldevs, dv_list) {
543 
544 		if (!(d->dv_cfattach->ca_rescan))
545 			continue;
546 
547 		for (cf1 = cf; cf1->cf_name; cf1++) {
548 
549 			if (!cfparent_match(d, cf1->cf_pspec))
550 				continue;
551 
552 			(*d->dv_cfattach->ca_rescan)(d,
553 				cf1->cf_pspec->cfp_iattr, cf1->cf_loc);
554 		}
555 	}
556 }
557 
558 /*
559  * Attach a supplemental config data table and rescan potential
560  * parent devices if required.
561  */
562 int
563 config_cfdata_attach(struct cfdata *cf, int scannow)
564 {
565 	struct cftable *ct;
566 
567 	ct = malloc(sizeof(struct cftable), M_DEVBUF, M_WAITOK);
568 	ct->ct_cfdata = cf;
569 	TAILQ_INSERT_TAIL(&allcftables, ct, ct_list);
570 
571 	if (scannow)
572 		rescan_with_cfdata(cf);
573 
574 	return (0);
575 }
576 
577 /*
578  * Helper for config_cfdata_detach: check whether a device is
579  * found through any attachment in the config data table.
580  */
581 static int
582 dev_in_cfdata(const struct device *d, const struct cfdata *cf)
583 {
584 	const struct cfdata *cf1;
585 
586 	for (cf1 = cf; cf1->cf_name; cf1++)
587 		if (d->dv_cfdata == cf1)
588 			return (1);
589 
590 	return (0);
591 }
592 
593 /*
594  * Detach a supplemental config data table. Detach all devices found
595  * through that table (and thus keeping references to it) before.
596  */
597 int
598 config_cfdata_detach(struct cfdata *cf)
599 {
600 	struct device *d;
601 	int error;
602 	struct cftable *ct;
603 
604 again:
605 	TAILQ_FOREACH(d, &alldevs, dv_list) {
606 		if (dev_in_cfdata(d, cf)) {
607 			error = config_detach(d, 0);
608 			if (error) {
609 				aprint_error("%s: unable to detach instance\n",
610 					d->dv_xname);
611 				return (error);
612 			}
613 			goto again;
614 		}
615 	}
616 
617 	TAILQ_FOREACH(ct, &allcftables, ct_list) {
618 		if (ct->ct_cfdata == cf) {
619 			TAILQ_REMOVE(&allcftables, ct, ct_list);
620 			free(ct, M_DEVBUF);
621 			return (0);
622 		}
623 	}
624 
625 	/* not found -- shouldn't happen */
626 	return (EINVAL);
627 }
628 
629 /*
630  * Invoke the "match" routine for a cfdata entry on behalf of
631  * an external caller, usually a "submatch" routine.
632  */
633 int
634 config_match(struct device *parent, struct cfdata *cf, void *aux)
635 {
636 	struct cfattach *ca;
637 
638 	ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
639 	if (ca == NULL) {
640 		/* No attachment for this entry, oh well. */
641 		return (0);
642 	}
643 
644 	return ((*ca->ca_match)(parent, cf, aux));
645 }
646 
647 /*
648  * Iterate over all potential children of some device, calling the given
649  * function (default being the child's match function) for each one.
650  * Nonzero returns are matches; the highest value returned is considered
651  * the best match.  Return the `found child' if we got a match, or NULL
652  * otherwise.  The `aux' pointer is simply passed on through.
653  *
654  * Note that this function is designed so that it can be used to apply
655  * an arbitrary function to all potential children (its return value
656  * can be ignored).
657  */
658 struct cfdata *
659 config_search_loc(cfsubmatch_t fn, struct device *parent,
660 		  const char *ifattr, const locdesc_t *ldesc, void *aux)
661 {
662 	struct cftable *ct;
663 	struct cfdata *cf;
664 	struct matchinfo m;
665 
666 	KASSERT(config_initialized);
667 	KASSERT(!ifattr || cfdriver_has_iattr(parent->dv_cfdriver, ifattr));
668 
669 	m.fn_loc = fn;
670 	m.parent = parent;
671 	m.ldesc = ldesc;
672 	m.aux = aux;
673 	m.match = NULL;
674 	m.pri = 0;
675 
676 	TAILQ_FOREACH(ct, &allcftables, ct_list) {
677 		for (cf = ct->ct_cfdata; cf->cf_name; cf++) {
678 
679 			/* We don't match root nodes here. */
680 			if (!cf->cf_pspec)
681 				continue;
682 
683 			/*
684 			 * Skip cf if no longer eligible, otherwise scan
685 			 * through parents for one matching `parent', and
686 			 * try match function.
687 			 */
688 			if (cf->cf_fstate == FSTATE_FOUND)
689 				continue;
690 			if (cf->cf_fstate == FSTATE_DNOTFOUND ||
691 			    cf->cf_fstate == FSTATE_DSTAR)
692 				continue;
693 
694 			/*
695 			 * If an interface attribute was specified,
696 			 * consider only children which attach to
697 			 * that attribute.
698 			 */
699 			if (ifattr && !STREQ(ifattr, cf->cf_pspec->cfp_iattr))
700 				continue;
701 
702 			if (cfparent_match(parent, cf->cf_pspec))
703 				mapply(&m, cf);
704 		}
705 	}
706 	return (m.match);
707 }
708 
709 /*
710  * Find the given root device.
711  * This is much like config_search, but there is no parent.
712  * Don't bother with multiple cfdata tables; the root node
713  * must always be in the initial table.
714  */
715 struct cfdata *
716 config_rootsearch(cfsubmatch_t fn, const char *rootname, void *aux)
717 {
718 	struct cfdata *cf;
719 	const short *p;
720 	struct matchinfo m;
721 
722 	m.fn_loc = fn;
723 	m.parent = ROOT;
724 	m.aux = aux;
725 	m.match = NULL;
726 	m.pri = 0;
727 	/*
728 	 * Look at root entries for matching name.  We do not bother
729 	 * with found-state here since only one root should ever be
730 	 * searched (and it must be done first).
731 	 */
732 	for (p = cfroots; *p >= 0; p++) {
733 		cf = &cfdata[*p];
734 		if (strcmp(cf->cf_name, rootname) == 0)
735 			mapply(&m, cf);
736 	}
737 	return (m.match);
738 }
739 
740 static const char * const msgs[3] = { "", " not configured\n", " unsupported\n" };
741 
742 /*
743  * The given `aux' argument describes a device that has been found
744  * on the given parent, but not necessarily configured.  Locate the
745  * configuration data for that device (using the submatch function
746  * provided, or using candidates' cd_match configuration driver
747  * functions) and attach it, and return true.  If the device was
748  * not configured, call the given `print' function and return 0.
749  */
750 struct device *
751 config_found_sm_loc(struct device *parent,
752 		const char *ifattr, const locdesc_t *ldesc, void *aux,
753 		cfprint_t print, cfsubmatch_t submatch)
754 {
755 	struct cfdata *cf;
756 
757 	if ((cf = config_search_loc(submatch, parent, ifattr, ldesc, aux)))
758 		return(config_attach_loc(parent, cf, ldesc, aux, print));
759 	if (print) {
760 		if (config_do_twiddle)
761 			twiddle();
762 		aprint_normal("%s", msgs[(*print)(aux, parent->dv_xname)]);
763 	}
764 	return (NULL);
765 }
766 
767 /*
768  * As above, but for root devices.
769  */
770 struct device *
771 config_rootfound(const char *rootname, void *aux)
772 {
773 	struct cfdata *cf;
774 
775 	if ((cf = config_rootsearch((cfsubmatch_t)NULL, rootname, aux)) != NULL)
776 		return (config_attach(ROOT, cf, aux, (cfprint_t)NULL));
777 	aprint_error("root device %s not configured\n", rootname);
778 	return (NULL);
779 }
780 
781 /* just like sprintf(buf, "%d") except that it works from the end */
782 static char *
783 number(char *ep, int n)
784 {
785 
786 	*--ep = 0;
787 	while (n >= 10) {
788 		*--ep = (n % 10) + '0';
789 		n /= 10;
790 	}
791 	*--ep = n + '0';
792 	return (ep);
793 }
794 
795 /*
796  * Expand the size of the cd_devs array if necessary.
797  */
798 void
799 config_makeroom(int n, struct cfdriver *cd)
800 {
801 	int old, new;
802 	void **nsp;
803 
804 	if (n < cd->cd_ndevs)
805 		return;
806 
807 	/*
808 	 * Need to expand the array.
809 	 */
810 	old = cd->cd_ndevs;
811 	if (old == 0)
812 		new = MINALLOCSIZE / sizeof(void *);
813 	else
814 		new = old * 2;
815 	while (new <= n)
816 		new *= 2;
817 	cd->cd_ndevs = new;
818 	nsp = malloc(new * sizeof(void *), M_DEVBUF,
819 	    cold ? M_NOWAIT : M_WAITOK);
820 	if (nsp == NULL)
821 		panic("config_attach: %sing dev array",
822 		    old != 0 ? "expand" : "creat");
823 	memset(nsp + old, 0, (new - old) * sizeof(void *));
824 	if (old != 0) {
825 		memcpy(nsp, cd->cd_devs, old * sizeof(void *));
826 		free(cd->cd_devs, M_DEVBUF);
827 	}
828 	cd->cd_devs = nsp;
829 }
830 
831 /*
832  * Attach a found device.  Allocates memory for device variables.
833  */
834 struct device *
835 config_attach_loc(struct device *parent, struct cfdata *cf,
836 	const locdesc_t *ldesc, void *aux, cfprint_t print)
837 {
838 	struct device *dev;
839 	struct cftable *ct;
840 	struct cfdriver *cd;
841 	struct cfattach *ca;
842 	size_t lname, lunit;
843 	const char *xunit;
844 	int myunit;
845 	char num[10];
846 
847 	cd = config_cfdriver_lookup(cf->cf_name);
848 	KASSERT(cd != NULL);
849 
850 	ca = config_cfattach_lookup_cd(cd, cf->cf_atname);
851 	KASSERT(ca != NULL);
852 
853 	if (ca->ca_devsize < sizeof(struct device))
854 		panic("config_attach");
855 
856 #ifndef __BROKEN_CONFIG_UNIT_USAGE
857 	if (cf->cf_fstate == FSTATE_STAR) {
858 		for (myunit = cf->cf_unit; myunit < cd->cd_ndevs; myunit++)
859 			if (cd->cd_devs[myunit] == NULL)
860 				break;
861 		/*
862 		 * myunit is now the unit of the first NULL device pointer,
863 		 * or max(cd->cd_ndevs,cf->cf_unit).
864 		 */
865 	} else {
866 		myunit = cf->cf_unit;
867 		KASSERT(cf->cf_fstate == FSTATE_NOTFOUND);
868 		cf->cf_fstate = FSTATE_FOUND;
869 	}
870 #else
871 	myunit = cf->cf_unit;
872 	if (cf->cf_fstate == FSTATE_STAR)
873 		cf->cf_unit++;
874 	else {
875 		KASSERT(cf->cf_fstate == FSTATE_NOTFOUND);
876 		cf->cf_fstate = FSTATE_FOUND;
877 	}
878 #endif /* ! __BROKEN_CONFIG_UNIT_USAGE */
879 
880 	/* compute length of name and decimal expansion of unit number */
881 	lname = strlen(cd->cd_name);
882 	xunit = number(&num[sizeof(num)], myunit);
883 	lunit = &num[sizeof(num)] - xunit;
884 	if (lname + lunit > sizeof(dev->dv_xname))
885 		panic("config_attach: device name too long");
886 
887 	/* get memory for all device vars */
888 	dev = (struct device *)malloc(ca->ca_devsize, M_DEVBUF,
889 	    cold ? M_NOWAIT : M_WAITOK);
890 	if (!dev)
891 	    panic("config_attach: memory allocation for device softc failed");
892 	memset(dev, 0, ca->ca_devsize);
893 	TAILQ_INSERT_TAIL(&alldevs, dev, dv_list);	/* link up */
894 	dev->dv_class = cd->cd_class;
895 	dev->dv_cfdata = cf;
896 	dev->dv_cfdriver = cd;
897 	dev->dv_cfattach = ca;
898 	dev->dv_unit = myunit;
899 	memcpy(dev->dv_xname, cd->cd_name, lname);
900 	memcpy(dev->dv_xname + lname, xunit, lunit);
901 	dev->dv_parent = parent;
902 	dev->dv_flags = DVF_ACTIVE;	/* always initially active */
903 	if (ldesc) {
904 		dev->dv_locators = malloc(ldesc->len * sizeof(int),
905 					  M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
906 		memcpy(dev->dv_locators, ldesc->locs, ldesc->len * sizeof(int));
907 	}
908 
909 	if (config_do_twiddle)
910 		twiddle();
911 	else
912 		aprint_naive("Found ");
913 	/*
914 	 * We want the next two printfs for normal, verbose, and quiet,
915 	 * but not silent (in which case, we're twiddling, instead).
916 	 */
917 	if (parent == ROOT) {
918 		aprint_naive("%s (root)", dev->dv_xname);
919 		aprint_normal("%s (root)", dev->dv_xname);
920 	} else {
921 		aprint_naive("%s at %s", dev->dv_xname, parent->dv_xname);
922 		aprint_normal("%s at %s", dev->dv_xname, parent->dv_xname);
923 		if (print)
924 			(void) (*print)(aux, NULL);
925 	}
926 
927 	/* put this device in the devices array */
928 	config_makeroom(dev->dv_unit, cd);
929 	if (cd->cd_devs[dev->dv_unit])
930 		panic("config_attach: duplicate %s", dev->dv_xname);
931 	cd->cd_devs[dev->dv_unit] = dev;
932 
933 	/*
934 	 * Before attaching, clobber any unfound devices that are
935 	 * otherwise identical.
936 	 */
937 	TAILQ_FOREACH(ct, &allcftables, ct_list) {
938 		for (cf = ct->ct_cfdata; cf->cf_name; cf++) {
939 			if (STREQ(cf->cf_name, cd->cd_name) &&
940 			    cf->cf_unit == dev->dv_unit) {
941 				if (cf->cf_fstate == FSTATE_NOTFOUND)
942 					cf->cf_fstate = FSTATE_FOUND;
943 #ifdef __BROKEN_CONFIG_UNIT_USAGE
944 				/*
945 				 * Bump the unit number on all starred cfdata
946 				 * entries for this device.
947 				 */
948 				if (cf->cf_fstate == FSTATE_STAR)
949 					cf->cf_unit++;
950 #endif /* __BROKEN_CONFIG_UNIT_USAGE */
951 			}
952 		}
953 	}
954 #ifdef __HAVE_DEVICE_REGISTER
955 	device_register(dev, aux);
956 #endif
957 	(*ca->ca_attach)(parent, dev, aux);
958 	config_process_deferred(&deferred_config_queue, dev);
959 	return (dev);
960 }
961 
962 /*
963  * As above, but for pseudo-devices.  Pseudo-devices attached in this
964  * way are silently inserted into the device tree, and their children
965  * attached.
966  *
967  * Note that because pseudo-devices are attached silently, any information
968  * the attach routine wishes to print should be prefixed with the device
969  * name by the attach routine.
970  */
971 struct device *
972 config_attach_pseudo(struct cfdata *cf)
973 {
974 	struct device *dev;
975 	struct cfdriver *cd;
976 	struct cfattach *ca;
977 	size_t lname, lunit;
978 	const char *xunit;
979 	int myunit;
980 	char num[10];
981 
982 	cd = config_cfdriver_lookup(cf->cf_name);
983 	if (cd == NULL)
984 		return (NULL);
985 
986 	ca = config_cfattach_lookup_cd(cd, cf->cf_atname);
987 	if (ca == NULL)
988 		return (NULL);
989 
990 	if (ca->ca_devsize < sizeof(struct device))
991 		panic("config_attach_pseudo");
992 
993 	/*
994 	 * We just ignore cf_fstate, instead doing everything with
995 	 * cf_unit.
996 	 *
997 	 * XXX Should we change this and use FSTATE_NOTFOUND and
998 	 * XXX FSTATE_STAR?
999 	 */
1000 
1001 	if (cf->cf_unit == DVUNIT_ANY) {
1002 		for (myunit = 0; myunit < cd->cd_ndevs; myunit++)
1003 			if (cd->cd_devs[myunit] == NULL)
1004 				break;
1005 		/*
1006 		 * myunit is now the unit of the first NULL device pointer.
1007 		 */
1008 	} else {
1009 		myunit = cf->cf_unit;
1010 		if (myunit < cd->cd_ndevs && cd->cd_devs[myunit] != NULL)
1011 			return (NULL);
1012 	}
1013 
1014 	/* compute length of name and decimal expansion of unit number */
1015 	lname = strlen(cd->cd_name);
1016 	xunit = number(&num[sizeof(num)], myunit);
1017 	lunit = &num[sizeof(num)] - xunit;
1018 	if (lname + lunit > sizeof(dev->dv_xname))
1019 		panic("config_attach_pseudo: device name too long");
1020 
1021 	/* get memory for all device vars */
1022 	dev = (struct device *)malloc(ca->ca_devsize, M_DEVBUF,
1023 	    cold ? M_NOWAIT : M_WAITOK);
1024 	if (!dev)
1025 		panic("config_attach_pseudo: memory allocation for device "
1026 		    "softc failed");
1027 	memset(dev, 0, ca->ca_devsize);
1028 	TAILQ_INSERT_TAIL(&alldevs, dev, dv_list);	/* link up */
1029 	dev->dv_class = cd->cd_class;
1030 	dev->dv_cfdata = cf;
1031 	dev->dv_cfdriver = cd;
1032 	dev->dv_cfattach = ca;
1033 	dev->dv_unit = myunit;
1034 	memcpy(dev->dv_xname, cd->cd_name, lname);
1035 	memcpy(dev->dv_xname + lname, xunit, lunit);
1036 	dev->dv_parent = ROOT;
1037 	dev->dv_flags = DVF_ACTIVE;	/* always initially active */
1038 
1039 	/* put this device in the devices array */
1040 	config_makeroom(dev->dv_unit, cd);
1041 	if (cd->cd_devs[dev->dv_unit])
1042 		panic("config_attach_pseudo: duplicate %s", dev->dv_xname);
1043 	cd->cd_devs[dev->dv_unit] = dev;
1044 
1045 #if 0	/* XXXJRT not yet */
1046 #ifdef __HAVE_DEVICE_REGISTER
1047 	device_register(dev, NULL);	/* like a root node */
1048 #endif
1049 #endif
1050 	(*ca->ca_attach)(ROOT, dev, NULL);
1051 	config_process_deferred(&deferred_config_queue, dev);
1052 	return (dev);
1053 }
1054 
1055 /*
1056  * Detach a device.  Optionally forced (e.g. because of hardware
1057  * removal) and quiet.  Returns zero if successful, non-zero
1058  * (an error code) otherwise.
1059  *
1060  * Note that this code wants to be run from a process context, so
1061  * that the detach can sleep to allow processes which have a device
1062  * open to run and unwind their stacks.
1063  */
1064 int
1065 config_detach(struct device *dev, int flags)
1066 {
1067 	struct cftable *ct;
1068 	struct cfdata *cf;
1069 	const struct cfattach *ca;
1070 	struct cfdriver *cd;
1071 #ifdef DIAGNOSTIC
1072 	struct device *d;
1073 #endif
1074 	int rv = 0, i;
1075 
1076 #ifdef DIAGNOSTIC
1077 	if (dev->dv_cfdata != NULL &&
1078 	    dev->dv_cfdata->cf_fstate != FSTATE_FOUND &&
1079 	    dev->dv_cfdata->cf_fstate != FSTATE_STAR)
1080 		panic("config_detach: bad device fstate");
1081 #endif
1082 	cd = dev->dv_cfdriver;
1083 	KASSERT(cd != NULL);
1084 
1085 	ca = dev->dv_cfattach;
1086 	KASSERT(ca != NULL);
1087 
1088 	/*
1089 	 * Ensure the device is deactivated.  If the device doesn't
1090 	 * have an activation entry point, we allow DVF_ACTIVE to
1091 	 * remain set.  Otherwise, if DVF_ACTIVE is still set, the
1092 	 * device is busy, and the detach fails.
1093 	 */
1094 	if (ca->ca_activate != NULL)
1095 		rv = config_deactivate(dev);
1096 
1097 	/*
1098 	 * Try to detach the device.  If that's not possible, then
1099 	 * we either panic() (for the forced but failed case), or
1100 	 * return an error.
1101 	 */
1102 	if (rv == 0) {
1103 		if (ca->ca_detach != NULL)
1104 			rv = (*ca->ca_detach)(dev, flags);
1105 		else
1106 			rv = EOPNOTSUPP;
1107 	}
1108 	if (rv != 0) {
1109 		if ((flags & DETACH_FORCE) == 0)
1110 			return (rv);
1111 		else
1112 			panic("config_detach: forced detach of %s failed (%d)",
1113 			    dev->dv_xname, rv);
1114 	}
1115 
1116 	/*
1117 	 * The device has now been successfully detached.
1118 	 */
1119 
1120 #ifdef DIAGNOSTIC
1121 	/*
1122 	 * Sanity: If you're successfully detached, you should have no
1123 	 * children.  (Note that because children must be attached
1124 	 * after parents, we only need to search the latter part of
1125 	 * the list.)
1126 	 */
1127 	for (d = TAILQ_NEXT(dev, dv_list); d != NULL;
1128 	    d = TAILQ_NEXT(d, dv_list)) {
1129 		if (d->dv_parent == dev) {
1130 			printf("config_detach: detached device %s"
1131 			    " has children %s\n", dev->dv_xname, d->dv_xname);
1132 			panic("config_detach");
1133 		}
1134 	}
1135 #endif
1136 
1137 	/* notify the parent that the child is gone */
1138 	if (dev->dv_parent) {
1139 		struct device *p = dev->dv_parent;
1140 		if (p->dv_cfattach->ca_childdetached)
1141 			(*p->dv_cfattach->ca_childdetached)(p, dev);
1142 	}
1143 
1144 	/*
1145 	 * Mark cfdata to show that the unit can be reused, if possible.
1146 	 */
1147 	TAILQ_FOREACH(ct, &allcftables, ct_list) {
1148 		for (cf = ct->ct_cfdata; cf->cf_name; cf++) {
1149 			if (STREQ(cf->cf_name, cd->cd_name)) {
1150 				if (cf->cf_fstate == FSTATE_FOUND &&
1151 				    cf->cf_unit == dev->dv_unit)
1152 					cf->cf_fstate = FSTATE_NOTFOUND;
1153 #ifdef __BROKEN_CONFIG_UNIT_USAGE
1154 				/*
1155 				 * Note that we can only re-use a starred
1156 				 * unit number if the unit being detached
1157 				 * had the last assigned unit number.
1158 				 */
1159 				if (cf->cf_fstate == FSTATE_STAR &&
1160 				    cf->cf_unit == dev->dv_unit + 1)
1161 					cf->cf_unit--;
1162 #endif /* __BROKEN_CONFIG_UNIT_USAGE */
1163 			}
1164 		}
1165 	}
1166 
1167 	/*
1168 	 * Unlink from device list.
1169 	 */
1170 	TAILQ_REMOVE(&alldevs, dev, dv_list);
1171 
1172 	/*
1173 	 * Remove from cfdriver's array, tell the world (unless it was
1174 	 * a pseudo-device), and free softc.
1175 	 */
1176 	cd->cd_devs[dev->dv_unit] = NULL;
1177 	if (dev->dv_cfdata != NULL && (flags & DETACH_QUIET) == 0)
1178 		aprint_normal("%s detached\n", dev->dv_xname);
1179 	if (dev->dv_locators)
1180 		free(dev->dv_locators, M_DEVBUF);
1181 	free(dev, M_DEVBUF);
1182 
1183 	/*
1184 	 * If the device now has no units in use, deallocate its softc array.
1185 	 */
1186 	for (i = 0; i < cd->cd_ndevs; i++)
1187 		if (cd->cd_devs[i] != NULL)
1188 			break;
1189 	if (i == cd->cd_ndevs) {		/* nothing found; deallocate */
1190 		free(cd->cd_devs, M_DEVBUF);
1191 		cd->cd_devs = NULL;
1192 		cd->cd_ndevs = 0;
1193 	}
1194 
1195 	/*
1196 	 * Return success.
1197 	 */
1198 	return (0);
1199 }
1200 
1201 int
1202 config_activate(struct device *dev)
1203 {
1204 	const struct cfattach *ca = dev->dv_cfattach;
1205 	int rv = 0, oflags = dev->dv_flags;
1206 
1207 	if (ca->ca_activate == NULL)
1208 		return (EOPNOTSUPP);
1209 
1210 	if ((dev->dv_flags & DVF_ACTIVE) == 0) {
1211 		dev->dv_flags |= DVF_ACTIVE;
1212 		rv = (*ca->ca_activate)(dev, DVACT_ACTIVATE);
1213 		if (rv)
1214 			dev->dv_flags = oflags;
1215 	}
1216 	return (rv);
1217 }
1218 
1219 int
1220 config_deactivate(struct device *dev)
1221 {
1222 	const struct cfattach *ca = dev->dv_cfattach;
1223 	int rv = 0, oflags = dev->dv_flags;
1224 
1225 	if (ca->ca_activate == NULL)
1226 		return (EOPNOTSUPP);
1227 
1228 	if (dev->dv_flags & DVF_ACTIVE) {
1229 		dev->dv_flags &= ~DVF_ACTIVE;
1230 		rv = (*ca->ca_activate)(dev, DVACT_DEACTIVATE);
1231 		if (rv)
1232 			dev->dv_flags = oflags;
1233 	}
1234 	return (rv);
1235 }
1236 
1237 /*
1238  * Defer the configuration of the specified device until all
1239  * of its parent's devices have been attached.
1240  */
1241 void
1242 config_defer(struct device *dev, void (*func)(struct device *))
1243 {
1244 	struct deferred_config *dc;
1245 
1246 	if (dev->dv_parent == NULL)
1247 		panic("config_defer: can't defer config of a root device");
1248 
1249 #ifdef DIAGNOSTIC
1250 	for (dc = TAILQ_FIRST(&deferred_config_queue); dc != NULL;
1251 	     dc = TAILQ_NEXT(dc, dc_queue)) {
1252 		if (dc->dc_dev == dev)
1253 			panic("config_defer: deferred twice");
1254 	}
1255 #endif
1256 
1257 	dc = malloc(sizeof(*dc), M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
1258 	if (dc == NULL)
1259 		panic("config_defer: unable to allocate callback");
1260 
1261 	dc->dc_dev = dev;
1262 	dc->dc_func = func;
1263 	TAILQ_INSERT_TAIL(&deferred_config_queue, dc, dc_queue);
1264 	config_pending_incr();
1265 }
1266 
1267 /*
1268  * Defer some autoconfiguration for a device until after interrupts
1269  * are enabled.
1270  */
1271 void
1272 config_interrupts(struct device *dev, void (*func)(struct device *))
1273 {
1274 	struct deferred_config *dc;
1275 
1276 	/*
1277 	 * If interrupts are enabled, callback now.
1278 	 */
1279 	if (cold == 0) {
1280 		(*func)(dev);
1281 		return;
1282 	}
1283 
1284 #ifdef DIAGNOSTIC
1285 	for (dc = TAILQ_FIRST(&interrupt_config_queue); dc != NULL;
1286 	     dc = TAILQ_NEXT(dc, dc_queue)) {
1287 		if (dc->dc_dev == dev)
1288 			panic("config_interrupts: deferred twice");
1289 	}
1290 #endif
1291 
1292 	dc = malloc(sizeof(*dc), M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
1293 	if (dc == NULL)
1294 		panic("config_interrupts: unable to allocate callback");
1295 
1296 	dc->dc_dev = dev;
1297 	dc->dc_func = func;
1298 	TAILQ_INSERT_TAIL(&interrupt_config_queue, dc, dc_queue);
1299 	config_pending_incr();
1300 }
1301 
1302 /*
1303  * Process a deferred configuration queue.
1304  */
1305 static void
1306 config_process_deferred(struct deferred_config_head *queue,
1307     struct device *parent)
1308 {
1309 	struct deferred_config *dc, *ndc;
1310 
1311 	for (dc = TAILQ_FIRST(queue); dc != NULL; dc = ndc) {
1312 		ndc = TAILQ_NEXT(dc, dc_queue);
1313 		if (parent == NULL || dc->dc_dev->dv_parent == parent) {
1314 			TAILQ_REMOVE(queue, dc, dc_queue);
1315 			(*dc->dc_func)(dc->dc_dev);
1316 			free(dc, M_DEVBUF);
1317 			config_pending_decr();
1318 		}
1319 	}
1320 }
1321 
1322 /*
1323  * Manipulate the config_pending semaphore.
1324  */
1325 void
1326 config_pending_incr(void)
1327 {
1328 
1329 	config_pending++;
1330 }
1331 
1332 void
1333 config_pending_decr(void)
1334 {
1335 
1336 #ifdef DIAGNOSTIC
1337 	if (config_pending == 0)
1338 		panic("config_pending_decr: config_pending == 0");
1339 #endif
1340 	config_pending--;
1341 	if (config_pending == 0)
1342 		wakeup(&config_pending);
1343 }
1344 
1345 /*
1346  * Register a "finalization" routine.  Finalization routines are
1347  * called iteratively once all real devices have been found during
1348  * autoconfiguration, for as long as any one finalizer has done
1349  * any work.
1350  */
1351 int
1352 config_finalize_register(struct device *dev, int (*fn)(struct device *))
1353 {
1354 	struct finalize_hook *f;
1355 
1356 	/*
1357 	 * If finalization has already been done, invoke the
1358 	 * callback function now.
1359 	 */
1360 	if (config_finalize_done) {
1361 		while ((*fn)(dev) != 0)
1362 			/* loop */ ;
1363 	}
1364 
1365 	/* Ensure this isn't already on the list. */
1366 	TAILQ_FOREACH(f, &config_finalize_list, f_list) {
1367 		if (f->f_func == fn && f->f_dev == dev)
1368 			return (EEXIST);
1369 	}
1370 
1371 	f = malloc(sizeof(*f), M_TEMP, M_WAITOK);
1372 	f->f_func = fn;
1373 	f->f_dev = dev;
1374 	TAILQ_INSERT_TAIL(&config_finalize_list, f, f_list);
1375 
1376 	return (0);
1377 }
1378 
1379 void
1380 config_finalize(void)
1381 {
1382 	struct finalize_hook *f;
1383 	int rv;
1384 
1385 	/* Run the hooks until none of them does any work. */
1386 	do {
1387 		rv = 0;
1388 		TAILQ_FOREACH(f, &config_finalize_list, f_list)
1389 			rv |= (*f->f_func)(f->f_dev);
1390 	} while (rv != 0);
1391 
1392 	config_finalize_done = 1;
1393 
1394 	/* Now free all the hooks. */
1395 	while ((f = TAILQ_FIRST(&config_finalize_list)) != NULL) {
1396 		TAILQ_REMOVE(&config_finalize_list, f, f_list);
1397 		free(f, M_TEMP);
1398 	}
1399 }
1400 
1401