1 /* $NetBSD: subr_autoconf.c,v 1.192 2010/01/07 22:39:52 dyoung Exp $ */
4 * Copyright (c) 1996, 2000 Christopher G. Demetriou
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
34 * --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
38 * Copyright (c) 1992, 1993
39 * The Regents of the University of California. All rights reserved.
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.
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.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
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.
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
74 * from: Header: subr_autoconf.c,v 1.12 93/02/01 19:31:48 torek Exp (LBL)
76 * @(#)subr_autoconf.c 8.3 (Berkeley) 5/17/94
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.192 2010/01/07 22:39:52 dyoung Exp $");
86 #include <sys/param.h>
87 #include <sys/device.h>
88 #include <sys/disklabel.h>
90 #include <sys/kauth.h>
91 #include <sys/malloc.h>
93 #include <sys/systm.h>
94 #include <sys/kernel.h>
95 #include <sys/errno.h>
97 #include <sys/reboot.h>
98 #include <sys/kthread.h>
100 #include <sys/dirent.h>
101 #include <sys/vnode.h>
102 #include <sys/mount.h>
103 #include <sys/namei.h>
104 #include <sys/unistd.h>
105 #include <sys/fcntl.h>
106 #include <sys/lockf.h>
107 #include <sys/callout.h>
108 #include <sys/devmon.h>
110 #include <sys/sysctl.h>
112 #include <sys/disk.h>
114 #include <machine/limits.h>
116 #if defined(__i386__) && defined(_KERNEL_OPT)
117 #include "opt_splash.h"
118 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
119 #include <dev/splash/splash.h>
120 extern struct splash_progress
*splash_progress_state
;
125 * Autoconfiguration subroutines.
129 * ioconf.c exports exactly two names: cfdata and cfroots. All system
130 * devices and drivers are found via these tables.
132 extern struct cfdata cfdata
[];
133 extern const short cfroots
[];
136 * List of all cfdriver structures. We use this to detect duplicates
137 * when other cfdrivers are loaded.
139 struct cfdriverlist allcfdrivers
= LIST_HEAD_INITIALIZER(&allcfdrivers
);
140 extern struct cfdriver
* const cfdriver_list_initial
[];
143 * Initial list of cfattach's.
145 extern const struct cfattachinit cfattachinit
[];
148 * List of cfdata tables. We always have one such list -- the one
149 * built statically when the kernel was configured.
151 struct cftablelist allcftables
= TAILQ_HEAD_INITIALIZER(allcftables
);
152 static struct cftable initcftable
;
154 #define ROOT ((device_t)NULL)
158 struct device
*parent
;
161 struct cfdata
*match
;
165 static char *number(char *, int);
166 static void mapply(struct matchinfo
*, cfdata_t
);
167 static device_t
config_devalloc(const device_t
, const cfdata_t
, const int *);
168 static void config_devdelete(device_t
);
169 static void config_devunlink(device_t
, struct devicelist
*);
170 static void config_makeroom(int, struct cfdriver
*);
171 static void config_devlink(device_t
);
172 static void config_alldevs_unlock(int);
173 static int config_alldevs_lock(void);
175 static void config_collect_garbage(struct devicelist
*);
176 static void config_dump_garbage(struct devicelist
*);
178 static void pmflock_debug(device_t
, const char *, int);
180 static device_t
deviter_next1(deviter_t
*);
181 static void deviter_reinit(deviter_t
*);
183 struct deferred_config
{
184 TAILQ_ENTRY(deferred_config
) dc_queue
;
186 void (*dc_func
)(device_t
);
189 TAILQ_HEAD(deferred_config_head
, deferred_config
);
191 struct deferred_config_head deferred_config_queue
=
192 TAILQ_HEAD_INITIALIZER(deferred_config_queue
);
193 struct deferred_config_head interrupt_config_queue
=
194 TAILQ_HEAD_INITIALIZER(interrupt_config_queue
);
195 int interrupt_config_threads
= 8;
197 static void config_process_deferred(struct deferred_config_head
*, device_t
);
199 /* Hooks to finalize configuration once all real devices have been found. */
200 struct finalize_hook
{
201 TAILQ_ENTRY(finalize_hook
) f_list
;
202 int (*f_func
)(device_t
);
205 static TAILQ_HEAD(, finalize_hook
) config_finalize_list
=
206 TAILQ_HEAD_INITIALIZER(config_finalize_list
);
207 static int config_finalize_done
;
209 /* list of all devices */
210 static struct devicelist alldevs
= TAILQ_HEAD_INITIALIZER(alldevs
);
211 static kmutex_t alldevs_mtx
;
212 static volatile bool alldevs_garbage
= false;
213 static volatile devgen_t alldevs_gen
= 1;
214 static volatile int alldevs_nread
= 0;
215 static volatile int alldevs_nwrite
= 0;
217 static int config_pending
; /* semaphore for mountroot */
218 static kmutex_t config_misc_lock
;
219 static kcondvar_t config_misc_cv
;
221 static int detachall
= 0;
223 #define STREQ(s1, s2) \
224 (*(s1) == *(s2) && strcmp((s1), (s2)) == 0)
226 static bool config_initialized
= false; /* config_init() has been called. */
228 static int config_do_twiddle
;
229 static callout_t config_twiddle_ch
;
231 static void sysctl_detach_setup(struct sysctllog
**);
234 * Initialize the autoconfiguration data structures. Normally this
235 * is done by configure(), but some platforms need to do this very
236 * early (to e.g. initialize the console).
241 const struct cfattachinit
*cfai
;
244 KASSERT(config_initialized
== false);
246 mutex_init(&alldevs_mtx
, MUTEX_DEFAULT
, IPL_HIGH
);
248 mutex_init(&config_misc_lock
, MUTEX_DEFAULT
, IPL_NONE
);
249 cv_init(&config_misc_cv
, "cfgmisc");
251 callout_init(&config_twiddle_ch
, CALLOUT_MPSAFE
);
253 /* allcfdrivers is statically initialized. */
254 for (i
= 0; cfdriver_list_initial
[i
] != NULL
; i
++) {
255 if (config_cfdriver_attach(cfdriver_list_initial
[i
]) != 0)
256 panic("configure: duplicate `%s' drivers",
257 cfdriver_list_initial
[i
]->cd_name
);
260 for (cfai
= &cfattachinit
[0]; cfai
->cfai_name
!= NULL
; cfai
++) {
261 for (j
= 0; cfai
->cfai_list
[j
] != NULL
; j
++) {
262 if (config_cfattach_attach(cfai
->cfai_name
,
263 cfai
->cfai_list
[j
]) != 0)
264 panic("configure: duplicate `%s' attachment "
266 cfai
->cfai_list
[j
]->ca_name
,
271 initcftable
.ct_cfdata
= cfdata
;
272 TAILQ_INSERT_TAIL(&allcftables
, &initcftable
, ct_list
);
274 config_initialized
= true;
281 if (!config_initialized
)
284 sysctl_detach_setup(NULL
);
288 config_deferred(device_t dev
)
290 config_process_deferred(&deferred_config_queue
, dev
);
291 config_process_deferred(&interrupt_config_queue
, dev
);
295 config_interrupts_thread(void *cookie
)
297 struct deferred_config
*dc
;
299 while ((dc
= TAILQ_FIRST(&interrupt_config_queue
)) != NULL
) {
300 TAILQ_REMOVE(&interrupt_config_queue
, dc
, dc_queue
);
301 (*dc
->dc_func
)(dc
->dc_dev
);
302 kmem_free(dc
, sizeof(*dc
));
303 config_pending_decr();
309 config_create_interruptthreads()
313 for (i
= 0; i
< interrupt_config_threads
; i
++) {
314 (void)kthread_create(PRI_NONE
, 0, NULL
,
315 config_interrupts_thread
, NULL
, NULL
, "config");
320 * Announce device attach/detach to userland listeners.
323 devmon_report_device(device_t dev
, bool isattach
)
326 prop_dictionary_t ev
;
329 device_t pdev
= device_parent(dev
);
331 ev
= prop_dictionary_create();
335 what
= (isattach
? "device-attach" : "device-detach");
336 parent
= (pdev
== NULL
? "root" : device_xname(pdev
));
337 if (!prop_dictionary_set_cstring(ev
, "device", device_xname(dev
)) ||
338 !prop_dictionary_set_cstring(ev
, "parent", parent
)) {
339 prop_object_release(ev
);
343 devmon_insert(what
, ev
);
348 * Add a cfdriver to the system.
351 config_cfdriver_attach(struct cfdriver
*cd
)
353 struct cfdriver
*lcd
;
355 /* Make sure this driver isn't already in the system. */
356 LIST_FOREACH(lcd
, &allcfdrivers
, cd_list
) {
357 if (STREQ(lcd
->cd_name
, cd
->cd_name
))
361 LIST_INIT(&cd
->cd_attach
);
362 LIST_INSERT_HEAD(&allcfdrivers
, cd
, cd_list
);
368 * Remove a cfdriver from the system.
371 config_cfdriver_detach(struct cfdriver
*cd
)
373 struct devicelist garbage
= TAILQ_HEAD_INITIALIZER(garbage
);
376 s
= config_alldevs_lock();
377 config_collect_garbage(&garbage
);
378 /* Make sure there are no active instances. */
379 for (i
= 0; i
< cd
->cd_ndevs
; i
++) {
380 if (cd
->cd_devs
[i
] != NULL
) {
385 config_alldevs_unlock(s
);
386 config_dump_garbage(&garbage
);
391 /* ...and no attachments loaded. */
392 if (LIST_EMPTY(&cd
->cd_attach
) == 0)
395 LIST_REMOVE(cd
, cd_list
);
397 KASSERT(cd
->cd_devs
== NULL
);
403 * Look up a cfdriver by name.
406 config_cfdriver_lookup(const char *name
)
410 LIST_FOREACH(cd
, &allcfdrivers
, cd_list
) {
411 if (STREQ(cd
->cd_name
, name
))
419 * Add a cfattach to the specified driver.
422 config_cfattach_attach(const char *driver
, struct cfattach
*ca
)
424 struct cfattach
*lca
;
427 cd
= config_cfdriver_lookup(driver
);
431 /* Make sure this attachment isn't already on this driver. */
432 LIST_FOREACH(lca
, &cd
->cd_attach
, ca_list
) {
433 if (STREQ(lca
->ca_name
, ca
->ca_name
))
437 LIST_INSERT_HEAD(&cd
->cd_attach
, ca
, ca_list
);
443 * Remove a cfattach from the specified driver.
446 config_cfattach_detach(const char *driver
, struct cfattach
*ca
)
448 struct devicelist garbage
= TAILQ_HEAD_INITIALIZER(garbage
);
453 cd
= config_cfdriver_lookup(driver
);
457 s
= config_alldevs_lock();
458 config_collect_garbage(&garbage
);
459 /* Make sure there are no active instances. */
460 for (i
= 0; i
< cd
->cd_ndevs
; i
++) {
461 if ((dev
= cd
->cd_devs
[i
]) == NULL
)
463 if (dev
->dv_cfattach
== ca
) {
468 config_alldevs_unlock(s
);
469 config_dump_garbage(&garbage
);
474 LIST_REMOVE(ca
, ca_list
);
480 * Look up a cfattach by name.
482 static struct cfattach
*
483 config_cfattach_lookup_cd(struct cfdriver
*cd
, const char *atname
)
487 LIST_FOREACH(ca
, &cd
->cd_attach
, ca_list
) {
488 if (STREQ(ca
->ca_name
, atname
))
496 * Look up a cfattach by driver/attachment name.
499 config_cfattach_lookup(const char *name
, const char *atname
)
503 cd
= config_cfdriver_lookup(name
);
507 return config_cfattach_lookup_cd(cd
, atname
);
511 * Apply the matching function and choose the best. This is used
512 * a few times and we want to keep the code small.
515 mapply(struct matchinfo
*m
, cfdata_t cf
)
520 pri
= (*m
->fn
)(m
->parent
, cf
, m
->locs
, m
->aux
);
522 pri
= config_match(m
->parent
, cf
, m
->aux
);
531 config_stdsubmatch(device_t parent
, cfdata_t cf
, const int *locs
, void *aux
)
533 const struct cfiattrdata
*ci
;
534 const struct cflocdesc
*cl
;
537 ci
= cfiattr_lookup(cf
->cf_pspec
->cfp_iattr
, parent
->dv_cfdriver
);
539 nlocs
= ci
->ci_loclen
;
540 KASSERT(!nlocs
|| locs
);
541 for (i
= 0; i
< nlocs
; i
++) {
542 cl
= &ci
->ci_locdesc
[i
];
543 /* !cld_defaultstr means no default value */
544 if ((!(cl
->cld_defaultstr
)
545 || (cf
->cf_loc
[i
] != cl
->cld_default
))
546 && cf
->cf_loc
[i
] != locs
[i
])
550 return config_match(parent
, cf
, aux
);
554 * Helper function: check whether the driver supports the interface attribute
555 * and return its descriptor structure.
557 static const struct cfiattrdata
*
558 cfdriver_get_iattr(const struct cfdriver
*cd
, const char *ia
)
560 const struct cfiattrdata
* const *cpp
;
562 if (cd
->cd_attrs
== NULL
)
565 for (cpp
= cd
->cd_attrs
; *cpp
; cpp
++) {
566 if (STREQ((*cpp
)->ci_name
, ia
)) {
575 * Lookup an interface attribute description by name.
576 * If the driver is given, consider only its supported attributes.
578 const struct cfiattrdata
*
579 cfiattr_lookup(const char *name
, const struct cfdriver
*cd
)
581 const struct cfdriver
*d
;
582 const struct cfiattrdata
*ia
;
585 return cfdriver_get_iattr(cd
, name
);
587 LIST_FOREACH(d
, &allcfdrivers
, cd_list
) {
588 ia
= cfdriver_get_iattr(d
, name
);
596 * Determine if `parent' is a potential parent for a device spec based
600 cfparent_match(const device_t parent
, const struct cfparent
*cfp
)
602 struct cfdriver
*pcd
;
604 /* We don't match root nodes here. */
608 pcd
= parent
->dv_cfdriver
;
609 KASSERT(pcd
!= NULL
);
612 * First, ensure this parent has the correct interface
615 if (!cfdriver_get_iattr(pcd
, cfp
->cfp_iattr
))
619 * If no specific parent device instance was specified (i.e.
620 * we're attaching to the attribute only), we're done!
622 if (cfp
->cfp_parent
== NULL
)
626 * Check the parent device's name.
628 if (STREQ(pcd
->cd_name
, cfp
->cfp_parent
) == 0)
629 return 0; /* not the same parent */
632 * Make sure the unit number matches.
634 if (cfp
->cfp_unit
== DVUNIT_ANY
|| /* wildcard */
635 cfp
->cfp_unit
== parent
->dv_unit
)
638 /* Unit numbers don't match. */
643 * Helper for config_cfdata_attach(): check all devices whether it could be
644 * parent any attachment in the config data table passed, and rescan.
647 rescan_with_cfdata(const struct cfdata
*cf
)
650 const struct cfdata
*cf1
;
655 * "alldevs" is likely longer than a modules's cfdata, so make it
658 for (d
= deviter_first(&di
, 0); d
!= NULL
; d
= deviter_next(&di
)) {
660 if (!(d
->dv_cfattach
->ca_rescan
))
663 for (cf1
= cf
; cf1
->cf_name
; cf1
++) {
665 if (!cfparent_match(d
, cf1
->cf_pspec
))
668 (*d
->dv_cfattach
->ca_rescan
)(d
,
669 cf1
->cf_pspec
->cfp_iattr
, cf1
->cf_loc
);
672 deviter_release(&di
);
676 * Attach a supplemental config data table and rescan potential
677 * parent devices if required.
680 config_cfdata_attach(cfdata_t cf
, int scannow
)
684 ct
= kmem_alloc(sizeof(*ct
), KM_SLEEP
);
686 TAILQ_INSERT_TAIL(&allcftables
, ct
, ct_list
);
689 rescan_with_cfdata(cf
);
695 * Helper for config_cfdata_detach: check whether a device is
696 * found through any attachment in the config data table.
699 dev_in_cfdata(const struct device
*d
, const struct cfdata
*cf
)
701 const struct cfdata
*cf1
;
703 for (cf1
= cf
; cf1
->cf_name
; cf1
++)
704 if (d
->dv_cfdata
== cf1
)
711 * Detach a supplemental config data table. Detach all devices found
712 * through that table (and thus keeping references to it) before.
715 config_cfdata_detach(cfdata_t cf
)
722 for (d
= deviter_first(&di
, DEVITER_F_RW
); d
!= NULL
;
723 d
= deviter_next(&di
)) {
724 if (!dev_in_cfdata(d
, cf
))
726 if ((error
= config_detach(d
, 0)) != 0)
729 deviter_release(&di
);
731 aprint_error_dev(d
, "unable to detach instance\n");
735 TAILQ_FOREACH(ct
, &allcftables
, ct_list
) {
736 if (ct
->ct_cfdata
== cf
) {
737 TAILQ_REMOVE(&allcftables
, ct
, ct_list
);
738 kmem_free(ct
, sizeof(*ct
));
743 /* not found -- shouldn't happen */
748 * Invoke the "match" routine for a cfdata entry on behalf of
749 * an external caller, usually a "submatch" routine.
752 config_match(device_t parent
, cfdata_t cf
, void *aux
)
756 ca
= config_cfattach_lookup(cf
->cf_name
, cf
->cf_atname
);
758 /* No attachment for this entry, oh well. */
762 return (*ca
->ca_match
)(parent
, cf
, aux
);
766 * Iterate over all potential children of some device, calling the given
767 * function (default being the child's match function) for each one.
768 * Nonzero returns are matches; the highest value returned is considered
769 * the best match. Return the `found child' if we got a match, or NULL
770 * otherwise. The `aux' pointer is simply passed on through.
772 * Note that this function is designed so that it can be used to apply
773 * an arbitrary function to all potential children (its return value
777 config_search_loc(cfsubmatch_t fn
, device_t parent
,
778 const char *ifattr
, const int *locs
, void *aux
)
784 KASSERT(config_initialized
);
785 KASSERT(!ifattr
|| cfdriver_get_iattr(parent
->dv_cfdriver
, ifattr
));
794 TAILQ_FOREACH(ct
, &allcftables
, ct_list
) {
795 for (cf
= ct
->ct_cfdata
; cf
->cf_name
; cf
++) {
797 /* We don't match root nodes here. */
802 * Skip cf if no longer eligible, otherwise scan
803 * through parents for one matching `parent', and
804 * try match function.
806 if (cf
->cf_fstate
== FSTATE_FOUND
)
808 if (cf
->cf_fstate
== FSTATE_DNOTFOUND
||
809 cf
->cf_fstate
== FSTATE_DSTAR
)
813 * If an interface attribute was specified,
814 * consider only children which attach to
817 if (ifattr
&& !STREQ(ifattr
, cf
->cf_pspec
->cfp_iattr
))
820 if (cfparent_match(parent
, cf
->cf_pspec
))
828 config_search_ia(cfsubmatch_t fn
, device_t parent
, const char *ifattr
,
832 return config_search_loc(fn
, parent
, ifattr
, NULL
, aux
);
836 * Find the given root device.
837 * This is much like config_search, but there is no parent.
838 * Don't bother with multiple cfdata tables; the root node
839 * must always be in the initial table.
842 config_rootsearch(cfsubmatch_t fn
, const char *rootname
, void *aux
)
855 * Look at root entries for matching name. We do not bother
856 * with found-state here since only one root should ever be
857 * searched (and it must be done first).
859 for (p
= cfroots
; *p
>= 0; p
++) {
861 if (strcmp(cf
->cf_name
, rootname
) == 0)
867 static const char * const msgs
[3] = { "", " not configured\n", " unsupported\n" };
870 * The given `aux' argument describes a device that has been found
871 * on the given parent, but not necessarily configured. Locate the
872 * configuration data for that device (using the submatch function
873 * provided, or using candidates' cd_match configuration driver
874 * functions) and attach it, and return true. If the device was
875 * not configured, call the given `print' function and return 0.
878 config_found_sm_loc(device_t parent
,
879 const char *ifattr
, const int *locs
, void *aux
,
880 cfprint_t print
, cfsubmatch_t submatch
)
884 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
885 if (splash_progress_state
)
886 splash_progress_update(splash_progress_state
);
889 if ((cf
= config_search_loc(submatch
, parent
, ifattr
, locs
, aux
)))
890 return(config_attach_loc(parent
, cf
, locs
, aux
, print
));
892 if (config_do_twiddle
&& cold
)
894 aprint_normal("%s", msgs
[(*print
)(aux
, device_xname(parent
))]);
897 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
898 if (splash_progress_state
)
899 splash_progress_update(splash_progress_state
);
906 config_found_ia(device_t parent
, const char *ifattr
, void *aux
,
910 return config_found_sm_loc(parent
, ifattr
, NULL
, aux
, print
, NULL
);
914 config_found(device_t parent
, void *aux
, cfprint_t print
)
917 return config_found_sm_loc(parent
, NULL
, NULL
, aux
, print
, NULL
);
921 * As above, but for root devices.
924 config_rootfound(const char *rootname
, void *aux
)
928 if ((cf
= config_rootsearch((cfsubmatch_t
)NULL
, rootname
, aux
)) != NULL
)
929 return config_attach(ROOT
, cf
, aux
, (cfprint_t
)NULL
);
930 aprint_error("root device %s not configured\n", rootname
);
934 /* just like sprintf(buf, "%d") except that it works from the end */
936 number(char *ep
, int n
)
941 *--ep
= (n
% 10) + '0';
949 * Expand the size of the cd_devs array if necessary.
951 * The caller must hold alldevs_mtx. config_makeroom() may release and
952 * re-acquire alldevs_mtx, so callers should re-check conditions such
953 * as alldevs_nwrite == 0 and alldevs_nread == 0 when config_makeroom()
957 config_makeroom(int n
, struct cfdriver
*cd
)
964 for (new = MAX(4, cd
->cd_ndevs
); new <= n
; new += new)
967 while (n
>= cd
->cd_ndevs
) {
969 * Need to expand the array.
974 /* Release alldevs_mtx around allocation, which may
977 mutex_exit(&alldevs_mtx
);
978 nsp
= kmem_alloc(sizeof(device_t
[new]), KM_SLEEP
);
980 panic("%s: could not expand cd_devs", __func__
);
981 mutex_enter(&alldevs_mtx
);
983 /* If another thread moved the array while we did
984 * not hold alldevs_mtx, try again.
986 if (cd
->cd_devs
!= osp
) {
987 kmem_free(nsp
, sizeof(device_t
[new]));
991 memset(nsp
+ old
, 0, sizeof(device_t
[new - old
]));
993 memcpy(nsp
, cd
->cd_devs
, sizeof(device_t
[old
]));
998 kmem_free(osp
, sizeof(device_t
[old
]));
1004 * Put dev into the devices list.
1007 config_devlink(device_t dev
)
1011 s
= config_alldevs_lock();
1013 KASSERT(device_cfdriver(dev
)->cd_devs
[dev
->dv_unit
] == dev
);
1015 dev
->dv_add_gen
= alldevs_gen
;
1016 /* It is safe to add a device to the tail of the list while
1017 * readers and writers are in the list.
1019 TAILQ_INSERT_TAIL(&alldevs
, dev
, dv_list
);
1020 config_alldevs_unlock(s
);
1024 config_devfree(device_t dev
)
1026 int priv
= (dev
->dv_flags
& DVF_PRIV_ALLOC
);
1028 if (dev
->dv_cfattach
->ca_devsize
> 0)
1029 kmem_free(dev
->dv_private
, dev
->dv_cfattach
->ca_devsize
);
1031 kmem_free(dev
, sizeof(*dev
));
1035 * Caller must hold alldevs_mtx.
1038 config_devunlink(device_t dev
, struct devicelist
*garbage
)
1040 struct device_garbage
*dg
= &dev
->dv_garbage
;
1041 cfdriver_t cd
= device_cfdriver(dev
);
1044 KASSERT(mutex_owned(&alldevs_mtx
));
1046 /* Unlink from device list. Link to garbage list. */
1047 TAILQ_REMOVE(&alldevs
, dev
, dv_list
);
1048 TAILQ_INSERT_TAIL(garbage
, dev
, dv_list
);
1050 /* Remove from cfdriver's array. */
1051 cd
->cd_devs
[dev
->dv_unit
] = NULL
;
1054 * If the device now has no units in use, unlink its softc array.
1056 for (i
= 0; i
< cd
->cd_ndevs
; i
++) {
1057 if (cd
->cd_devs
[i
] != NULL
)
1060 /* Nothing found. Unlink, now. Deallocate, later. */
1061 if (i
== cd
->cd_ndevs
) {
1062 dg
->dg_ndevs
= cd
->cd_ndevs
;
1063 dg
->dg_devs
= cd
->cd_devs
;
1070 config_devdelete(device_t dev
)
1072 struct device_garbage
*dg
= &dev
->dv_garbage
;
1073 device_lock_t dvl
= device_getlock(dev
);
1075 if (dg
->dg_devs
!= NULL
)
1076 kmem_free(dg
->dg_devs
, sizeof(device_t
[dg
->dg_ndevs
]));
1078 cv_destroy(&dvl
->dvl_cv
);
1079 mutex_destroy(&dvl
->dvl_mtx
);
1081 KASSERT(dev
->dv_properties
!= NULL
);
1082 prop_object_release(dev
->dv_properties
);
1084 if (dev
->dv_activity_handlers
)
1085 panic("%s with registered handlers", __func__
);
1087 if (dev
->dv_locators
) {
1088 size_t amount
= *--dev
->dv_locators
;
1089 kmem_free(dev
->dv_locators
, amount
);
1092 config_devfree(dev
);
1096 config_unit_nextfree(cfdriver_t cd
, cfdata_t cf
)
1100 if (cf
->cf_fstate
== FSTATE_STAR
) {
1101 for (unit
= cf
->cf_unit
; unit
< cd
->cd_ndevs
; unit
++)
1102 if (cd
->cd_devs
[unit
] == NULL
)
1105 * unit is now the unit of the first NULL device pointer,
1106 * or max(cd->cd_ndevs,cf->cf_unit).
1110 if (unit
< cd
->cd_ndevs
&& cd
->cd_devs
[unit
] != NULL
)
1117 config_unit_alloc(device_t dev
, cfdriver_t cd
, cfdata_t cf
)
1119 struct devicelist garbage
= TAILQ_HEAD_INITIALIZER(garbage
);
1122 s
= config_alldevs_lock();
1124 config_collect_garbage(&garbage
);
1125 unit
= config_unit_nextfree(cd
, cf
);
1128 if (unit
< cd
->cd_ndevs
) {
1129 cd
->cd_devs
[unit
] = dev
;
1130 dev
->dv_unit
= unit
;
1133 config_makeroom(unit
, cd
);
1135 config_alldevs_unlock(s
);
1136 config_dump_garbage(&garbage
);
1142 config_devalloc(const device_t parent
, const cfdata_t cf
, const int *locs
)
1144 struct devicelist garbage
= TAILQ_HEAD_INITIALIZER(garbage
);
1147 size_t lname
, lunit
;
1153 const struct cfiattrdata
*ia
;
1156 cd
= config_cfdriver_lookup(cf
->cf_name
);
1160 ca
= config_cfattach_lookup_cd(cd
, cf
->cf_atname
);
1164 if ((ca
->ca_flags
& DVF_PRIV_ALLOC
) == 0 &&
1165 ca
->ca_devsize
< sizeof(struct device
))
1166 panic("config_devalloc: %s", cf
->cf_atname
);
1168 /* get memory for all device vars */
1169 KASSERT((ca
->ca_flags
& DVF_PRIV_ALLOC
) || ca
->ca_devsize
>= sizeof(struct device
));
1170 if (ca
->ca_devsize
> 0) {
1171 dev_private
= kmem_zalloc(ca
->ca_devsize
, KM_SLEEP
);
1172 if (dev_private
== NULL
)
1173 panic("config_devalloc: memory allocation for device softc failed");
1175 KASSERT(ca
->ca_flags
& DVF_PRIV_ALLOC
);
1179 if ((ca
->ca_flags
& DVF_PRIV_ALLOC
) != 0) {
1180 dev
= kmem_zalloc(sizeof(*dev
), KM_SLEEP
);
1185 panic("config_devalloc: memory allocation for device_t failed");
1187 myunit
= config_unit_alloc(dev
, cd
, cf
);
1189 config_devfree(dev
);
1193 /* compute length of name and decimal expansion of unit number */
1194 lname
= strlen(cd
->cd_name
);
1195 xunit
= number(&num
[sizeof(num
)], myunit
);
1196 lunit
= &num
[sizeof(num
)] - xunit
;
1197 if (lname
+ lunit
> sizeof(dev
->dv_xname
))
1198 panic("config_devalloc: device name too long");
1200 dvl
= device_getlock(dev
);
1202 mutex_init(&dvl
->dvl_mtx
, MUTEX_DEFAULT
, IPL_NONE
);
1203 cv_init(&dvl
->dvl_cv
, "pmfsusp");
1205 dev
->dv_class
= cd
->cd_class
;
1206 dev
->dv_cfdata
= cf
;
1207 dev
->dv_cfdriver
= cd
;
1208 dev
->dv_cfattach
= ca
;
1209 dev
->dv_activity_count
= 0;
1210 dev
->dv_activity_handlers
= NULL
;
1211 dev
->dv_private
= dev_private
;
1212 memcpy(dev
->dv_xname
, cd
->cd_name
, lname
);
1213 memcpy(dev
->dv_xname
+ lname
, xunit
, lunit
);
1214 dev
->dv_parent
= parent
;
1216 dev
->dv_depth
= parent
->dv_depth
+ 1;
1219 dev
->dv_flags
= DVF_ACTIVE
; /* always initially active */
1220 dev
->dv_flags
|= ca
->ca_flags
; /* inherit flags from class */
1222 KASSERT(parent
); /* no locators at root */
1223 ia
= cfiattr_lookup(cf
->cf_pspec
->cfp_iattr
,
1224 parent
->dv_cfdriver
);
1226 kmem_alloc(sizeof(int [ia
->ci_loclen
+ 1]), KM_SLEEP
);
1227 *dev
->dv_locators
++ = sizeof(int [ia
->ci_loclen
+ 1]);
1228 memcpy(dev
->dv_locators
, locs
, sizeof(int [ia
->ci_loclen
]));
1230 dev
->dv_properties
= prop_dictionary_create();
1231 KASSERT(dev
->dv_properties
!= NULL
);
1233 prop_dictionary_set_cstring_nocopy(dev
->dv_properties
,
1234 "device-driver", dev
->dv_cfdriver
->cd_name
);
1235 prop_dictionary_set_uint16(dev
->dv_properties
,
1236 "device-unit", dev
->dv_unit
);
1242 * Attach a found device.
1245 config_attach_loc(device_t parent
, cfdata_t cf
,
1246 const int *locs
, void *aux
, cfprint_t print
)
1250 const char *drvname
;
1252 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
1253 if (splash_progress_state
)
1254 splash_progress_update(splash_progress_state
);
1257 dev
= config_devalloc(parent
, cf
, locs
);
1259 panic("config_attach: allocation of device softc failed");
1261 /* XXX redundant - see below? */
1262 if (cf
->cf_fstate
!= FSTATE_STAR
) {
1263 KASSERT(cf
->cf_fstate
== FSTATE_NOTFOUND
);
1264 cf
->cf_fstate
= FSTATE_FOUND
;
1267 config_devlink(dev
);
1269 if (config_do_twiddle
&& cold
)
1272 aprint_naive("Found ");
1274 * We want the next two printfs for normal, verbose, and quiet,
1275 * but not silent (in which case, we're twiddling, instead).
1277 if (parent
== ROOT
) {
1278 aprint_naive("%s (root)", device_xname(dev
));
1279 aprint_normal("%s (root)", device_xname(dev
));
1281 aprint_naive("%s at %s", device_xname(dev
), device_xname(parent
));
1282 aprint_normal("%s at %s", device_xname(dev
), device_xname(parent
));
1284 (void) (*print
)(aux
, NULL
);
1288 * Before attaching, clobber any unfound devices that are
1289 * otherwise identical.
1290 * XXX code above is redundant?
1292 drvname
= dev
->dv_cfdriver
->cd_name
;
1293 TAILQ_FOREACH(ct
, &allcftables
, ct_list
) {
1294 for (cf
= ct
->ct_cfdata
; cf
->cf_name
; cf
++) {
1295 if (STREQ(cf
->cf_name
, drvname
) &&
1296 cf
->cf_unit
== dev
->dv_unit
) {
1297 if (cf
->cf_fstate
== FSTATE_NOTFOUND
)
1298 cf
->cf_fstate
= FSTATE_FOUND
;
1302 #ifdef __HAVE_DEVICE_REGISTER
1303 device_register(dev
, aux
);
1306 /* Let userland know */
1307 devmon_report_device(dev
, true);
1309 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
1310 if (splash_progress_state
)
1311 splash_progress_update(splash_progress_state
);
1313 (*dev
->dv_cfattach
->ca_attach
)(parent
, dev
, aux
);
1314 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
1315 if (splash_progress_state
)
1316 splash_progress_update(splash_progress_state
);
1319 if (!device_pmf_is_registered(dev
))
1320 aprint_debug_dev(dev
, "WARNING: power management not supported\n");
1322 config_process_deferred(&deferred_config_queue
, dev
);
1327 config_attach(device_t parent
, cfdata_t cf
, void *aux
, cfprint_t print
)
1330 return config_attach_loc(parent
, cf
, NULL
, aux
, print
);
1334 * As above, but for pseudo-devices. Pseudo-devices attached in this
1335 * way are silently inserted into the device tree, and their children
1338 * Note that because pseudo-devices are attached silently, any information
1339 * the attach routine wishes to print should be prefixed with the device
1340 * name by the attach routine.
1343 config_attach_pseudo(cfdata_t cf
)
1347 dev
= config_devalloc(ROOT
, cf
, NULL
);
1351 /* XXX mark busy in cfdata */
1353 if (cf
->cf_fstate
!= FSTATE_STAR
) {
1354 KASSERT(cf
->cf_fstate
== FSTATE_NOTFOUND
);
1355 cf
->cf_fstate
= FSTATE_FOUND
;
1358 config_devlink(dev
);
1360 #if 0 /* XXXJRT not yet */
1361 #ifdef __HAVE_DEVICE_REGISTER
1362 device_register(dev
, NULL
); /* like a root node */
1365 (*dev
->dv_cfattach
->ca_attach
)(ROOT
, dev
, NULL
);
1366 config_process_deferred(&deferred_config_queue
, dev
);
1371 * Caller must hold alldevs_mtx.
1374 config_collect_garbage(struct devicelist
*garbage
)
1378 KASSERT(!cpu_intr_p());
1379 KASSERT(!cpu_softintr_p());
1380 KASSERT(mutex_owned(&alldevs_mtx
));
1382 while (alldevs_nwrite
== 0 && alldevs_nread
== 0 && alldevs_garbage
) {
1383 TAILQ_FOREACH(dv
, &alldevs
, dv_list
) {
1384 if (dv
->dv_del_gen
!= 0)
1388 alldevs_garbage
= false;
1391 config_devunlink(dv
, garbage
);
1393 KASSERT(mutex_owned(&alldevs_mtx
));
1397 config_dump_garbage(struct devicelist
*garbage
)
1401 while ((dv
= TAILQ_FIRST(garbage
)) != NULL
) {
1402 TAILQ_REMOVE(garbage
, dv
, dv_list
);
1403 config_devdelete(dv
);
1408 * Detach a device. Optionally forced (e.g. because of hardware
1409 * removal) and quiet. Returns zero if successful, non-zero
1410 * (an error code) otherwise.
1412 * Note that this code wants to be run from a process context, so
1413 * that the detach can sleep to allow processes which have a device
1414 * open to run and unwind their stacks.
1417 config_detach(device_t dev
, int flags
)
1419 struct devicelist garbage
= TAILQ_HEAD_INITIALIZER(garbage
);
1422 const struct cfattach
*ca
;
1423 struct cfdriver
*cd
;
1430 cf
= dev
->dv_cfdata
;
1431 if (cf
!= NULL
&& cf
->cf_fstate
!= FSTATE_FOUND
&&
1432 cf
->cf_fstate
!= FSTATE_STAR
)
1433 panic("config_detach: %s: bad device fstate %d",
1434 device_xname(dev
), cf
? cf
->cf_fstate
: -1);
1436 cd
= dev
->dv_cfdriver
;
1437 KASSERT(cd
!= NULL
);
1439 ca
= dev
->dv_cfattach
;
1440 KASSERT(ca
!= NULL
);
1442 s
= config_alldevs_lock();
1443 if (dev
->dv_del_gen
!= 0) {
1444 config_alldevs_unlock(s
);
1446 printf("%s: %s is already detached\n", __func__
,
1448 #endif /* DIAGNOSTIC */
1452 config_alldevs_unlock(s
);
1455 (flags
& (DETACH_SHUTDOWN
|DETACH_FORCE
)) == DETACH_SHUTDOWN
&&
1456 (dev
->dv_flags
& DVF_DETACH_SHUTDOWN
) == 0) {
1458 } else if (ca
->ca_detach
!= NULL
) {
1459 rv
= (*ca
->ca_detach
)(dev
, flags
);
1464 * If it was not possible to detach the device, then we either
1465 * panic() (for the forced but failed case), or return an error.
1467 * If it was possible to detach the device, ensure that the
1468 * device is deactivated.
1471 dev
->dv_flags
&= ~DVF_ACTIVE
;
1472 else if ((flags
& DETACH_FORCE
) == 0)
1475 panic("config_detach: forced detach of %s failed (%d)",
1476 device_xname(dev
), rv
);
1480 * The device has now been successfully detached.
1483 /* Let userland know */
1484 devmon_report_device(dev
, false);
1488 * Sanity: If you're successfully detached, you should have no
1489 * children. (Note that because children must be attached
1490 * after parents, we only need to search the latter part of
1493 for (d
= TAILQ_NEXT(dev
, dv_list
); d
!= NULL
;
1494 d
= TAILQ_NEXT(d
, dv_list
)) {
1495 if (d
->dv_parent
== dev
&& d
->dv_del_gen
== 0) {
1496 printf("config_detach: detached device %s"
1497 " has children %s\n", device_xname(dev
), device_xname(d
));
1498 panic("config_detach");
1503 /* notify the parent that the child is gone */
1504 if (dev
->dv_parent
) {
1505 device_t p
= dev
->dv_parent
;
1506 if (p
->dv_cfattach
->ca_childdetached
)
1507 (*p
->dv_cfattach
->ca_childdetached
)(p
, dev
);
1511 * Mark cfdata to show that the unit can be reused, if possible.
1513 TAILQ_FOREACH(ct
, &allcftables
, ct_list
) {
1514 for (cf
= ct
->ct_cfdata
; cf
->cf_name
; cf
++) {
1515 if (STREQ(cf
->cf_name
, cd
->cd_name
)) {
1516 if (cf
->cf_fstate
== FSTATE_FOUND
&&
1517 cf
->cf_unit
== dev
->dv_unit
)
1518 cf
->cf_fstate
= FSTATE_NOTFOUND
;
1523 if (dev
->dv_cfdata
!= NULL
&& (flags
& DETACH_QUIET
) == 0)
1524 aprint_normal_dev(dev
, "detached\n");
1527 s
= config_alldevs_lock();
1528 KASSERT(alldevs_nwrite
!= 0);
1530 if (rv
== 0 && dev
->dv_del_gen
== 0) {
1531 dev
->dv_del_gen
= alldevs_gen
;
1532 alldevs_garbage
= true;
1534 config_collect_garbage(&garbage
);
1535 config_alldevs_unlock(s
);
1536 config_dump_garbage(&garbage
);
1542 config_detach_children(device_t parent
, int flags
)
1548 for (dv
= deviter_first(&di
, DEVITER_F_RW
); dv
!= NULL
;
1549 dv
= deviter_next(&di
)) {
1550 if (device_parent(dv
) != parent
)
1552 if ((error
= config_detach(dv
, flags
)) != 0)
1555 deviter_release(&di
);
1560 shutdown_first(struct shutdown_state
*s
)
1562 if (!s
->initialized
) {
1563 deviter_init(&s
->di
, DEVITER_F_SHUTDOWN
|DEVITER_F_LEAVES_FIRST
);
1564 s
->initialized
= true;
1566 return shutdown_next(s
);
1570 shutdown_next(struct shutdown_state
*s
)
1574 while ((dv
= deviter_next(&s
->di
)) != NULL
&& !device_is_active(dv
))
1578 s
->initialized
= false;
1584 config_detach_all(int how
)
1586 static struct shutdown_state s
;
1588 bool progress
= false;
1590 if ((how
& RB_NOSYNC
) != 0)
1593 for (curdev
= shutdown_first(&s
); curdev
!= NULL
;
1594 curdev
= shutdown_next(&s
)) {
1595 aprint_debug(" detaching %s, ", device_xname(curdev
));
1596 if (config_detach(curdev
, DETACH_SHUTDOWN
) == 0) {
1598 aprint_debug("success.");
1600 aprint_debug("failed.");
1606 device_is_ancestor_of(device_t ancestor
, device_t descendant
)
1610 for (dv
= descendant
; dv
!= NULL
; dv
= device_parent(dv
)) {
1611 if (device_parent(dv
) == ancestor
)
1618 config_deactivate(device_t dev
)
1621 const struct cfattach
*ca
;
1622 device_t descendant
;
1623 int s
, rv
= 0, oflags
;
1625 for (descendant
= deviter_first(&di
, DEVITER_F_ROOT_FIRST
);
1627 descendant
= deviter_next(&di
)) {
1628 if (dev
!= descendant
&&
1629 !device_is_ancestor_of(dev
, descendant
))
1632 if ((descendant
->dv_flags
& DVF_ACTIVE
) == 0)
1635 ca
= descendant
->dv_cfattach
;
1636 oflags
= descendant
->dv_flags
;
1638 descendant
->dv_flags
&= ~DVF_ACTIVE
;
1639 if (ca
->ca_activate
== NULL
)
1642 rv
= (*ca
->ca_activate
)(descendant
, DVACT_DEACTIVATE
);
1645 descendant
->dv_flags
= oflags
;
1647 deviter_release(&di
);
1652 * Defer the configuration of the specified device until all
1653 * of its parent's devices have been attached.
1656 config_defer(device_t dev
, void (*func
)(device_t
))
1658 struct deferred_config
*dc
;
1660 if (dev
->dv_parent
== NULL
)
1661 panic("config_defer: can't defer config of a root device");
1664 TAILQ_FOREACH(dc
, &deferred_config_queue
, dc_queue
) {
1665 if (dc
->dc_dev
== dev
)
1666 panic("config_defer: deferred twice");
1670 dc
= kmem_alloc(sizeof(*dc
), KM_SLEEP
);
1672 panic("config_defer: unable to allocate callback");
1676 TAILQ_INSERT_TAIL(&deferred_config_queue
, dc
, dc_queue
);
1677 config_pending_incr();
1681 * Defer some autoconfiguration for a device until after interrupts
1685 config_interrupts(device_t dev
, void (*func
)(device_t
))
1687 struct deferred_config
*dc
;
1690 * If interrupts are enabled, callback now.
1698 TAILQ_FOREACH(dc
, &interrupt_config_queue
, dc_queue
) {
1699 if (dc
->dc_dev
== dev
)
1700 panic("config_interrupts: deferred twice");
1704 dc
= kmem_alloc(sizeof(*dc
), KM_SLEEP
);
1706 panic("config_interrupts: unable to allocate callback");
1710 TAILQ_INSERT_TAIL(&interrupt_config_queue
, dc
, dc_queue
);
1711 config_pending_incr();
1715 * Process a deferred configuration queue.
1718 config_process_deferred(struct deferred_config_head
*queue
,
1721 struct deferred_config
*dc
, *ndc
;
1723 for (dc
= TAILQ_FIRST(queue
); dc
!= NULL
; dc
= ndc
) {
1724 ndc
= TAILQ_NEXT(dc
, dc_queue
);
1725 if (parent
== NULL
|| dc
->dc_dev
->dv_parent
== parent
) {
1726 TAILQ_REMOVE(queue
, dc
, dc_queue
);
1727 (*dc
->dc_func
)(dc
->dc_dev
);
1728 kmem_free(dc
, sizeof(*dc
));
1729 config_pending_decr();
1735 * Manipulate the config_pending semaphore.
1738 config_pending_incr(void)
1741 mutex_enter(&config_misc_lock
);
1743 mutex_exit(&config_misc_lock
);
1747 config_pending_decr(void)
1751 if (config_pending
== 0)
1752 panic("config_pending_decr: config_pending == 0");
1754 mutex_enter(&config_misc_lock
);
1756 if (config_pending
== 0)
1757 cv_broadcast(&config_misc_cv
);
1758 mutex_exit(&config_misc_lock
);
1762 * Register a "finalization" routine. Finalization routines are
1763 * called iteratively once all real devices have been found during
1764 * autoconfiguration, for as long as any one finalizer has done
1768 config_finalize_register(device_t dev
, int (*fn
)(device_t
))
1770 struct finalize_hook
*f
;
1773 * If finalization has already been done, invoke the
1774 * callback function now.
1776 if (config_finalize_done
) {
1777 while ((*fn
)(dev
) != 0)
1781 /* Ensure this isn't already on the list. */
1782 TAILQ_FOREACH(f
, &config_finalize_list
, f_list
) {
1783 if (f
->f_func
== fn
&& f
->f_dev
== dev
)
1787 f
= kmem_alloc(sizeof(*f
), KM_SLEEP
);
1790 TAILQ_INSERT_TAIL(&config_finalize_list
, f
, f_list
);
1796 config_finalize(void)
1798 struct finalize_hook
*f
;
1799 struct pdevinit
*pdev
;
1800 extern struct pdevinit pdevinit
[];
1804 * Now that device driver threads have been created, wait for
1805 * them to finish any deferred autoconfiguration.
1807 mutex_enter(&config_misc_lock
);
1808 while (config_pending
!= 0)
1809 cv_wait(&config_misc_cv
, &config_misc_lock
);
1810 mutex_exit(&config_misc_lock
);
1812 KERNEL_LOCK(1, NULL
);
1814 /* Attach pseudo-devices. */
1815 for (pdev
= pdevinit
; pdev
->pdev_attach
!= NULL
; pdev
++)
1816 (*pdev
->pdev_attach
)(pdev
->pdev_count
);
1818 /* Run the hooks until none of them does any work. */
1821 TAILQ_FOREACH(f
, &config_finalize_list
, f_list
)
1822 rv
|= (*f
->f_func
)(f
->f_dev
);
1825 config_finalize_done
= 1;
1827 /* Now free all the hooks. */
1828 while ((f
= TAILQ_FIRST(&config_finalize_list
)) != NULL
) {
1829 TAILQ_REMOVE(&config_finalize_list
, f
, f_list
);
1830 kmem_free(f
, sizeof(*f
));
1833 KERNEL_UNLOCK_ONE(NULL
);
1835 errcnt
= aprint_get_error_count();
1836 if ((boothowto
& (AB_QUIET
|AB_SILENT
)) != 0 &&
1837 (boothowto
& AB_VERBOSE
) == 0) {
1838 mutex_enter(&config_misc_lock
);
1839 if (config_do_twiddle
) {
1840 config_do_twiddle
= 0;
1841 printf_nolog(" done.\n");
1843 mutex_exit(&config_misc_lock
);
1845 printf("WARNING: %d error%s while detecting hardware; "
1846 "check system log.\n", errcnt
,
1847 errcnt
== 1 ? "" : "s");
1853 config_twiddle_init()
1856 if ((boothowto
& (AB_SILENT
|AB_VERBOSE
)) == AB_SILENT
) {
1857 config_do_twiddle
= 1;
1859 callout_setfunc(&config_twiddle_ch
, config_twiddle_fn
, NULL
);
1863 config_twiddle_fn(void *cookie
)
1866 mutex_enter(&config_misc_lock
);
1867 if (config_do_twiddle
) {
1869 callout_schedule(&config_twiddle_ch
, mstohz(100));
1871 mutex_exit(&config_misc_lock
);
1875 config_alldevs_lock(void)
1880 mutex_enter(&alldevs_mtx
);
1885 config_alldevs_unlock(int s
)
1887 mutex_exit(&alldevs_mtx
);
1894 * Look up a device instance for a given driver.
1897 device_lookup(cfdriver_t cd
, int unit
)
1899 struct devicelist garbage
= TAILQ_HEAD_INITIALIZER(garbage
);
1903 s
= config_alldevs_lock();
1904 KASSERT(mutex_owned(&alldevs_mtx
));
1905 if (unit
< 0 || unit
>= cd
->cd_ndevs
)
1907 else if ((dv
= cd
->cd_devs
[unit
]) != NULL
&& dv
->dv_del_gen
!= 0)
1909 config_alldevs_unlock(s
);
1910 config_dump_garbage(&garbage
);
1916 * device_lookup_private:
1918 * Look up a softc instance for a given driver.
1921 device_lookup_private(cfdriver_t cd
, int unit
)
1925 if ((dv
= device_lookup(cd
, unit
)) == NULL
)
1928 return dv
->dv_private
;
1932 * Accessor functions for the device_t type.
1935 device_class(device_t dev
)
1938 return dev
->dv_class
;
1942 device_cfdata(device_t dev
)
1945 return dev
->dv_cfdata
;
1949 device_cfdriver(device_t dev
)
1952 return dev
->dv_cfdriver
;
1956 device_cfattach(device_t dev
)
1959 return dev
->dv_cfattach
;
1963 device_unit(device_t dev
)
1966 return dev
->dv_unit
;
1970 device_xname(device_t dev
)
1973 return dev
->dv_xname
;
1977 device_parent(device_t dev
)
1980 return dev
->dv_parent
;
1984 device_activation(device_t dev
, devact_level_t level
)
1988 active_flags
= DVF_ACTIVE
;
1990 case DEVACT_LEVEL_FULL
:
1991 active_flags
|= DVF_CLASS_SUSPENDED
;
1993 case DEVACT_LEVEL_DRIVER
:
1994 active_flags
|= DVF_DRIVER_SUSPENDED
;
1996 case DEVACT_LEVEL_BUS
:
1997 active_flags
|= DVF_BUS_SUSPENDED
;
2001 return (dev
->dv_flags
& active_flags
) == DVF_ACTIVE
;
2005 device_is_active(device_t dev
)
2009 active_flags
= DVF_ACTIVE
;
2010 active_flags
|= DVF_CLASS_SUSPENDED
;
2011 active_flags
|= DVF_DRIVER_SUSPENDED
;
2012 active_flags
|= DVF_BUS_SUSPENDED
;
2014 return (dev
->dv_flags
& active_flags
) == DVF_ACTIVE
;
2018 device_is_enabled(device_t dev
)
2020 return (dev
->dv_flags
& DVF_ACTIVE
) == DVF_ACTIVE
;
2024 device_has_power(device_t dev
)
2028 active_flags
= DVF_ACTIVE
| DVF_BUS_SUSPENDED
;
2030 return (dev
->dv_flags
& active_flags
) == DVF_ACTIVE
;
2034 device_locator(device_t dev
, u_int locnum
)
2037 KASSERT(dev
->dv_locators
!= NULL
);
2038 return dev
->dv_locators
[locnum
];
2042 device_private(device_t dev
)
2046 * The reason why device_private(NULL) is allowed is to simplify the
2047 * work of a lot of userspace request handlers (i.e., c/bdev
2048 * handlers) which grab cfdriver_t->cd_units[n].
2049 * It avoids having them test for it to be NULL and only then calling
2052 return dev
== NULL
? NULL
: dev
->dv_private
;
2056 device_properties(device_t dev
)
2059 return dev
->dv_properties
;
2065 * Returns true if the device is an instance of the specified
2069 device_is_a(device_t dev
, const char *dname
)
2072 return strcmp(dev
->dv_cfdriver
->cd_name
, dname
) == 0;
2076 * device_find_by_xname:
2078 * Returns the device of the given name or NULL if it doesn't exist.
2081 device_find_by_xname(const char *name
)
2086 for (dv
= deviter_first(&di
, 0); dv
!= NULL
; dv
= deviter_next(&di
)) {
2087 if (strcmp(device_xname(dv
), name
) == 0)
2090 deviter_release(&di
);
2096 * device_find_by_driver_unit:
2098 * Returns the device of the given driver name and unit or
2099 * NULL if it doesn't exist.
2102 device_find_by_driver_unit(const char *name
, int unit
)
2104 struct cfdriver
*cd
;
2106 if ((cd
= config_cfdriver_lookup(name
)) == NULL
)
2108 return device_lookup(cd
, unit
);
2112 * Power management related functions.
2116 device_pmf_is_registered(device_t dev
)
2118 return (dev
->dv_flags
& DVF_POWER_HANDLERS
) != 0;
2122 device_pmf_driver_suspend(device_t dev PMF_FN_ARGS
)
2124 if ((dev
->dv_flags
& DVF_DRIVER_SUSPENDED
) != 0)
2126 if ((dev
->dv_flags
& DVF_CLASS_SUSPENDED
) == 0)
2128 if (pmf_qual_depth(PMF_FN_CALL1
) <= DEVACT_LEVEL_DRIVER
&&
2129 dev
->dv_driver_suspend
!= NULL
&&
2130 !(*dev
->dv_driver_suspend
)(dev PMF_FN_CALL
))
2133 dev
->dv_flags
|= DVF_DRIVER_SUSPENDED
;
2138 device_pmf_driver_resume(device_t dev PMF_FN_ARGS
)
2140 if ((dev
->dv_flags
& DVF_DRIVER_SUSPENDED
) == 0)
2142 if ((dev
->dv_flags
& DVF_BUS_SUSPENDED
) != 0)
2144 if (pmf_qual_depth(PMF_FN_CALL1
) <= DEVACT_LEVEL_DRIVER
&&
2145 dev
->dv_driver_resume
!= NULL
&&
2146 !(*dev
->dv_driver_resume
)(dev PMF_FN_CALL
))
2149 dev
->dv_flags
&= ~DVF_DRIVER_SUSPENDED
;
2154 device_pmf_driver_shutdown(device_t dev
, int how
)
2157 if (*dev
->dv_driver_shutdown
!= NULL
&&
2158 !(*dev
->dv_driver_shutdown
)(dev
, how
))
2164 device_pmf_driver_register(device_t dev
,
2165 bool (*suspend
)(device_t PMF_FN_PROTO
),
2166 bool (*resume
)(device_t PMF_FN_PROTO
),
2167 bool (*shutdown
)(device_t
, int))
2169 dev
->dv_driver_suspend
= suspend
;
2170 dev
->dv_driver_resume
= resume
;
2171 dev
->dv_driver_shutdown
= shutdown
;
2172 dev
->dv_flags
|= DVF_POWER_HANDLERS
;
2179 if (curlwp
->l_name
!= NULL
)
2180 return curlwp
->l_name
;
2182 return curlwp
->l_proc
->p_comm
;
2186 device_pmf_driver_deregister(device_t dev
)
2188 device_lock_t dvl
= device_getlock(dev
);
2190 dev
->dv_driver_suspend
= NULL
;
2191 dev
->dv_driver_resume
= NULL
;
2193 mutex_enter(&dvl
->dvl_mtx
);
2194 dev
->dv_flags
&= ~DVF_POWER_HANDLERS
;
2195 while (dvl
->dvl_nlock
> 0 || dvl
->dvl_nwait
> 0) {
2196 /* Wake a thread that waits for the lock. That
2197 * thread will fail to acquire the lock, and then
2198 * it will wake the next thread that waits for the
2199 * lock, or else it will wake us.
2201 cv_signal(&dvl
->dvl_cv
);
2202 pmflock_debug(dev
, __func__
, __LINE__
);
2203 cv_wait(&dvl
->dvl_cv
, &dvl
->dvl_mtx
);
2204 pmflock_debug(dev
, __func__
, __LINE__
);
2206 mutex_exit(&dvl
->dvl_mtx
);
2210 device_pmf_driver_child_register(device_t dev
)
2212 device_t parent
= device_parent(dev
);
2214 if (parent
== NULL
|| parent
->dv_driver_child_register
== NULL
)
2216 return (*parent
->dv_driver_child_register
)(dev
);
2220 device_pmf_driver_set_child_register(device_t dev
,
2221 bool (*child_register
)(device_t
))
2223 dev
->dv_driver_child_register
= child_register
;
2227 pmflock_debug(device_t dev
, const char *func
, int line
)
2229 device_lock_t dvl
= device_getlock(dev
);
2231 aprint_debug_dev(dev
, "%s.%d, %s dvl_nlock %d dvl_nwait %d dv_flags %x\n",
2232 func
, line
, curlwp_name(), dvl
->dvl_nlock
, dvl
->dvl_nwait
,
2237 device_pmf_lock1(device_t dev
)
2239 device_lock_t dvl
= device_getlock(dev
);
2241 while (device_pmf_is_registered(dev
) &&
2242 dvl
->dvl_nlock
> 0 && dvl
->dvl_holder
!= curlwp
) {
2244 pmflock_debug(dev
, __func__
, __LINE__
);
2245 cv_wait(&dvl
->dvl_cv
, &dvl
->dvl_mtx
);
2246 pmflock_debug(dev
, __func__
, __LINE__
);
2249 if (!device_pmf_is_registered(dev
)) {
2250 pmflock_debug(dev
, __func__
, __LINE__
);
2251 /* We could not acquire the lock, but some other thread may
2252 * wait for it, also. Wake that thread.
2254 cv_signal(&dvl
->dvl_cv
);
2258 dvl
->dvl_holder
= curlwp
;
2259 pmflock_debug(dev
, __func__
, __LINE__
);
2264 device_pmf_lock(device_t dev
)
2267 device_lock_t dvl
= device_getlock(dev
);
2269 mutex_enter(&dvl
->dvl_mtx
);
2270 rc
= device_pmf_lock1(dev
);
2271 mutex_exit(&dvl
->dvl_mtx
);
2277 device_pmf_unlock(device_t dev
)
2279 device_lock_t dvl
= device_getlock(dev
);
2281 KASSERT(dvl
->dvl_nlock
> 0);
2282 mutex_enter(&dvl
->dvl_mtx
);
2283 if (--dvl
->dvl_nlock
== 0)
2284 dvl
->dvl_holder
= NULL
;
2285 cv_signal(&dvl
->dvl_cv
);
2286 pmflock_debug(dev
, __func__
, __LINE__
);
2287 mutex_exit(&dvl
->dvl_mtx
);
2291 device_getlock(device_t dev
)
2293 return &dev
->dv_lock
;
2297 device_pmf_bus_private(device_t dev
)
2299 return dev
->dv_bus_private
;
2303 device_pmf_bus_suspend(device_t dev PMF_FN_ARGS
)
2305 if ((dev
->dv_flags
& DVF_BUS_SUSPENDED
) != 0)
2307 if ((dev
->dv_flags
& DVF_CLASS_SUSPENDED
) == 0 ||
2308 (dev
->dv_flags
& DVF_DRIVER_SUSPENDED
) == 0)
2310 if (pmf_qual_depth(PMF_FN_CALL1
) <= DEVACT_LEVEL_BUS
&&
2311 dev
->dv_bus_suspend
!= NULL
&&
2312 !(*dev
->dv_bus_suspend
)(dev PMF_FN_CALL
))
2315 dev
->dv_flags
|= DVF_BUS_SUSPENDED
;
2320 device_pmf_bus_resume(device_t dev PMF_FN_ARGS
)
2322 if ((dev
->dv_flags
& DVF_BUS_SUSPENDED
) == 0)
2324 if (pmf_qual_depth(PMF_FN_CALL1
) <= DEVACT_LEVEL_BUS
&&
2325 dev
->dv_bus_resume
!= NULL
&&
2326 !(*dev
->dv_bus_resume
)(dev PMF_FN_CALL
))
2329 dev
->dv_flags
&= ~DVF_BUS_SUSPENDED
;
2334 device_pmf_bus_shutdown(device_t dev
, int how
)
2337 if (*dev
->dv_bus_shutdown
!= NULL
&&
2338 !(*dev
->dv_bus_shutdown
)(dev
, how
))
2344 device_pmf_bus_register(device_t dev
, void *priv
,
2345 bool (*suspend
)(device_t PMF_FN_PROTO
),
2346 bool (*resume
)(device_t PMF_FN_PROTO
),
2347 bool (*shutdown
)(device_t
, int), void (*deregister
)(device_t
))
2349 dev
->dv_bus_private
= priv
;
2350 dev
->dv_bus_resume
= resume
;
2351 dev
->dv_bus_suspend
= suspend
;
2352 dev
->dv_bus_shutdown
= shutdown
;
2353 dev
->dv_bus_deregister
= deregister
;
2357 device_pmf_bus_deregister(device_t dev
)
2359 if (dev
->dv_bus_deregister
== NULL
)
2361 (*dev
->dv_bus_deregister
)(dev
);
2362 dev
->dv_bus_private
= NULL
;
2363 dev
->dv_bus_suspend
= NULL
;
2364 dev
->dv_bus_resume
= NULL
;
2365 dev
->dv_bus_deregister
= NULL
;
2369 device_pmf_class_private(device_t dev
)
2371 return dev
->dv_class_private
;
2375 device_pmf_class_suspend(device_t dev PMF_FN_ARGS
)
2377 if ((dev
->dv_flags
& DVF_CLASS_SUSPENDED
) != 0)
2379 if (pmf_qual_depth(PMF_FN_CALL1
) <= DEVACT_LEVEL_CLASS
&&
2380 dev
->dv_class_suspend
!= NULL
&&
2381 !(*dev
->dv_class_suspend
)(dev PMF_FN_CALL
))
2384 dev
->dv_flags
|= DVF_CLASS_SUSPENDED
;
2389 device_pmf_class_resume(device_t dev PMF_FN_ARGS
)
2391 if ((dev
->dv_flags
& DVF_CLASS_SUSPENDED
) == 0)
2393 if ((dev
->dv_flags
& DVF_BUS_SUSPENDED
) != 0 ||
2394 (dev
->dv_flags
& DVF_DRIVER_SUSPENDED
) != 0)
2396 if (pmf_qual_depth(PMF_FN_CALL1
) <= DEVACT_LEVEL_CLASS
&&
2397 dev
->dv_class_resume
!= NULL
&&
2398 !(*dev
->dv_class_resume
)(dev PMF_FN_CALL
))
2401 dev
->dv_flags
&= ~DVF_CLASS_SUSPENDED
;
2406 device_pmf_class_register(device_t dev
, void *priv
,
2407 bool (*suspend
)(device_t PMF_FN_PROTO
),
2408 bool (*resume
)(device_t PMF_FN_PROTO
),
2409 void (*deregister
)(device_t
))
2411 dev
->dv_class_private
= priv
;
2412 dev
->dv_class_suspend
= suspend
;
2413 dev
->dv_class_resume
= resume
;
2414 dev
->dv_class_deregister
= deregister
;
2418 device_pmf_class_deregister(device_t dev
)
2420 if (dev
->dv_class_deregister
== NULL
)
2422 (*dev
->dv_class_deregister
)(dev
);
2423 dev
->dv_class_private
= NULL
;
2424 dev
->dv_class_suspend
= NULL
;
2425 dev
->dv_class_resume
= NULL
;
2426 dev
->dv_class_deregister
= NULL
;
2430 device_active(device_t dev
, devactive_t type
)
2434 if (dev
->dv_activity_count
== 0)
2437 for (i
= 0; i
< dev
->dv_activity_count
; ++i
) {
2438 if (dev
->dv_activity_handlers
[i
] == NULL
)
2440 (*dev
->dv_activity_handlers
[i
])(dev
, type
);
2447 device_active_register(device_t dev
, void (*handler
)(device_t
, devactive_t
))
2449 void (**new_handlers
)(device_t
, devactive_t
);
2450 void (**old_handlers
)(device_t
, devactive_t
);
2451 size_t i
, old_size
, new_size
;
2454 old_handlers
= dev
->dv_activity_handlers
;
2455 old_size
= dev
->dv_activity_count
;
2457 for (i
= 0; i
< old_size
; ++i
) {
2458 KASSERT(old_handlers
[i
] != handler
);
2459 if (old_handlers
[i
] == NULL
) {
2460 old_handlers
[i
] = handler
;
2465 new_size
= old_size
+ 4;
2466 new_handlers
= kmem_alloc(sizeof(void *[new_size
]), KM_SLEEP
);
2468 memcpy(new_handlers
, old_handlers
, sizeof(void *[old_size
]));
2469 new_handlers
[old_size
] = handler
;
2470 memset(new_handlers
+ old_size
+ 1, 0,
2471 sizeof(int [new_size
- (old_size
+1)]));
2474 dev
->dv_activity_count
= new_size
;
2475 dev
->dv_activity_handlers
= new_handlers
;
2478 if (old_handlers
!= NULL
)
2479 kmem_free(old_handlers
, sizeof(void * [old_size
]));
2485 device_active_deregister(device_t dev
, void (*handler
)(device_t
, devactive_t
))
2487 void (**old_handlers
)(device_t
, devactive_t
);
2491 old_handlers
= dev
->dv_activity_handlers
;
2492 old_size
= dev
->dv_activity_count
;
2494 for (i
= 0; i
< old_size
; ++i
) {
2495 if (old_handlers
[i
] == handler
)
2497 if (old_handlers
[i
] == NULL
)
2498 return; /* XXX panic? */
2502 return; /* XXX panic? */
2504 for (; i
< old_size
- 1; ++i
) {
2505 if ((old_handlers
[i
] = old_handlers
[i
+ 1]) != NULL
)
2510 dev
->dv_activity_count
= 0;
2511 dev
->dv_activity_handlers
= NULL
;
2513 kmem_free(old_handlers
, sizeof(void *[old_size
]));
2517 old_handlers
[i
] = NULL
;
2520 /* Return true iff the device_t `dev' exists at generation `gen'. */
2522 device_exists_at(device_t dv
, devgen_t gen
)
2524 return (dv
->dv_del_gen
== 0 || dv
->dv_del_gen
> gen
) &&
2525 dv
->dv_add_gen
<= gen
;
2529 deviter_visits(const deviter_t
*di
, device_t dv
)
2531 return device_exists_at(dv
, di
->di_gen
);
2537 * deviter_t: a device iterator. Holds state for a "walk" visiting
2538 * each device_t's in the device tree.
2540 * deviter_init(di, flags): initialize the device iterator `di'
2541 * to "walk" the device tree. deviter_next(di) will return
2542 * the first device_t in the device tree, or NULL if there are
2545 * `flags' is one or more of DEVITER_F_RW, indicating that the
2546 * caller intends to modify the device tree by calling
2547 * config_detach(9) on devices in the order that the iterator
2548 * returns them; DEVITER_F_ROOT_FIRST, asking for the devices
2549 * nearest the "root" of the device tree to be returned, first;
2550 * DEVITER_F_LEAVES_FIRST, asking for the devices furthest from
2551 * the root of the device tree, first; and DEVITER_F_SHUTDOWN,
2552 * indicating both that deviter_init() should not respect any
2553 * locks on the device tree, and that deviter_next(di) may run
2554 * in more than one LWP before the walk has finished.
2556 * Only one DEVITER_F_RW iterator may be in the device tree at
2559 * DEVITER_F_SHUTDOWN implies DEVITER_F_RW.
2561 * Results are undefined if the flags DEVITER_F_ROOT_FIRST and
2562 * DEVITER_F_LEAVES_FIRST are used in combination.
2564 * deviter_first(di, flags): initialize the device iterator `di'
2565 * and return the first device_t in the device tree, or NULL
2566 * if there are no devices. The statement
2568 * dv = deviter_first(di);
2573 * dv = deviter_next(di);
2575 * deviter_next(di): return the next device_t in the device tree,
2576 * or NULL if there are no more devices. deviter_next(di)
2577 * is undefined if `di' was not initialized with deviter_init() or
2580 * deviter_release(di): stops iteration (subsequent calls to
2581 * deviter_next() will return NULL), releases any locks and
2582 * resources held by the device iterator.
2584 * Device iteration does not return device_t's in any particular
2585 * order. An iterator will never return the same device_t twice.
2586 * Device iteration is guaranteed to complete---i.e., if deviter_next(di)
2587 * is called repeatedly on the same `di', it will eventually return
2588 * NULL. It is ok to attach/detach devices during device iteration.
2591 deviter_init(deviter_t
*di
, deviter_flags_t flags
)
2596 memset(di
, 0, sizeof(*di
));
2598 s
= config_alldevs_lock();
2599 if ((flags
& DEVITER_F_SHUTDOWN
) != 0)
2600 flags
|= DEVITER_F_RW
;
2602 if ((flags
& DEVITER_F_RW
) != 0)
2606 di
->di_gen
= alldevs_gen
++;
2607 config_alldevs_unlock(s
);
2609 di
->di_flags
= flags
;
2611 switch (di
->di_flags
& (DEVITER_F_LEAVES_FIRST
|DEVITER_F_ROOT_FIRST
)) {
2612 case DEVITER_F_LEAVES_FIRST
:
2613 TAILQ_FOREACH(dv
, &alldevs
, dv_list
) {
2614 if (!deviter_visits(di
, dv
))
2616 di
->di_curdepth
= MAX(di
->di_curdepth
, dv
->dv_depth
);
2619 case DEVITER_F_ROOT_FIRST
:
2620 TAILQ_FOREACH(dv
, &alldevs
, dv_list
) {
2621 if (!deviter_visits(di
, dv
))
2623 di
->di_maxdepth
= MAX(di
->di_maxdepth
, dv
->dv_depth
);
2634 deviter_reinit(deviter_t
*di
)
2636 if ((di
->di_flags
& DEVITER_F_RW
) != 0)
2637 di
->di_prev
= TAILQ_LAST(&alldevs
, devicelist
);
2639 di
->di_prev
= TAILQ_FIRST(&alldevs
);
2643 deviter_first(deviter_t
*di
, deviter_flags_t flags
)
2645 deviter_init(di
, flags
);
2646 return deviter_next(di
);
2650 deviter_next2(deviter_t
*di
)
2659 if ((di
->di_flags
& DEVITER_F_RW
) != 0)
2660 di
->di_prev
= TAILQ_PREV(dv
, devicelist
, dv_list
);
2662 di
->di_prev
= TAILQ_NEXT(dv
, dv_list
);
2668 deviter_next1(deviter_t
*di
)
2673 dv
= deviter_next2(di
);
2674 } while (dv
!= NULL
&& !deviter_visits(di
, dv
));
2680 deviter_next(deviter_t
*di
)
2684 switch (di
->di_flags
& (DEVITER_F_LEAVES_FIRST
|DEVITER_F_ROOT_FIRST
)) {
2686 return deviter_next1(di
);
2687 case DEVITER_F_LEAVES_FIRST
:
2688 while (di
->di_curdepth
>= 0) {
2689 if ((dv
= deviter_next1(di
)) == NULL
) {
2692 } else if (dv
->dv_depth
== di
->di_curdepth
)
2696 case DEVITER_F_ROOT_FIRST
:
2697 while (di
->di_curdepth
<= di
->di_maxdepth
) {
2698 if ((dv
= deviter_next1(di
)) == NULL
) {
2701 } else if (dv
->dv_depth
== di
->di_curdepth
)
2711 deviter_release(deviter_t
*di
)
2713 bool rw
= (di
->di_flags
& DEVITER_F_RW
) != 0;
2716 s
= config_alldevs_lock();
2721 /* XXX wake a garbage-collection thread */
2722 config_alldevs_unlock(s
);
2726 ifattr_match(const char *snull
, const char *t
)
2728 return (snull
== NULL
) || strcmp(snull
, t
) == 0;
2732 null_childdetached(device_t self
, device_t child
)
2738 sysctl_detach_setup(struct sysctllog
**clog
)
2740 const struct sysctlnode
*node
= NULL
;
2742 sysctl_createv(clog
, 0, NULL
, &node
,
2744 CTLTYPE_NODE
, "kern", NULL
,
2751 sysctl_createv(clog
, 0, &node
, NULL
,
2752 CTLFLAG_PERMANENT
| CTLFLAG_READWRITE
,
2753 CTLTYPE_INT
, "detachall",
2754 SYSCTL_DESCR("Detach all devices at shutdown"),
2755 NULL
, 0, &detachall
, 0,
2756 CTL_CREATE
, CTL_EOL
);