subr_autoconf.c revision 1.282 1 /* $NetBSD: subr_autoconf.c,v 1.282 2021/06/12 12:12:11 riastradh 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 #define __SUBR_AUTOCONF_PRIVATE /* see <sys/device.h> */
80
81 #include <sys/cdefs.h>
82 __KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.282 2021/06/12 12:12:11 riastradh Exp $");
83
84 #ifdef _KERNEL_OPT
85 #include "opt_ddb.h"
86 #include "drvctl.h"
87 #endif
88
89 #include <sys/param.h>
90 #include <sys/device.h>
91 #include <sys/disklabel.h>
92 #include <sys/conf.h>
93 #include <sys/kauth.h>
94 #include <sys/kmem.h>
95 #include <sys/systm.h>
96 #include <sys/kernel.h>
97 #include <sys/errno.h>
98 #include <sys/proc.h>
99 #include <sys/reboot.h>
100 #include <sys/kthread.h>
101 #include <sys/buf.h>
102 #include <sys/dirent.h>
103 #include <sys/mount.h>
104 #include <sys/namei.h>
105 #include <sys/unistd.h>
106 #include <sys/fcntl.h>
107 #include <sys/lockf.h>
108 #include <sys/callout.h>
109 #include <sys/devmon.h>
110 #include <sys/cpu.h>
111 #include <sys/sysctl.h>
112 #include <sys/stdarg.h>
113
114 #include <sys/disk.h>
115
116 #include <sys/rndsource.h>
117
118 #include <machine/limits.h>
119
120 /*
121 * Autoconfiguration subroutines.
122 */
123
124 /*
125 * Device autoconfiguration timings are mixed into the entropy pool.
126 */
127 static krndsource_t rnd_autoconf_source;
128
129 /*
130 * ioconf.c exports exactly two names: cfdata and cfroots. All system
131 * devices and drivers are found via these tables.
132 */
133 extern struct cfdata cfdata[];
134 extern const short cfroots[];
135
136 /*
137 * List of all cfdriver structures. We use this to detect duplicates
138 * when other cfdrivers are loaded.
139 */
140 struct cfdriverlist allcfdrivers = LIST_HEAD_INITIALIZER(&allcfdrivers);
141 extern struct cfdriver * const cfdriver_list_initial[];
142
143 /*
144 * Initial list of cfattach's.
145 */
146 extern const struct cfattachinit cfattachinit[];
147
148 /*
149 * List of cfdata tables. We always have one such list -- the one
150 * built statically when the kernel was configured.
151 */
152 struct cftablelist allcftables = TAILQ_HEAD_INITIALIZER(allcftables);
153 static struct cftable initcftable;
154
155 #define ROOT ((device_t)NULL)
156
157 struct matchinfo {
158 cfsubmatch_t fn;
159 device_t parent;
160 const int *locs;
161 void *aux;
162 struct cfdata *match;
163 int pri;
164 };
165
166 struct alldevs_foray {
167 int af_s;
168 struct devicelist af_garbage;
169 };
170
171 static char *number(char *, int);
172 static void mapply(struct matchinfo *, cfdata_t);
173 static void config_devdelete(device_t);
174 static void config_devunlink(device_t, struct devicelist *);
175 static void config_makeroom(int, struct cfdriver *);
176 static void config_devlink(device_t);
177 static void config_alldevs_enter(struct alldevs_foray *);
178 static void config_alldevs_exit(struct alldevs_foray *);
179 static void config_add_attrib_dict(device_t);
180
181 static void config_collect_garbage(struct devicelist *);
182 static void config_dump_garbage(struct devicelist *);
183
184 static void pmflock_debug(device_t, const char *, int);
185
186 static device_t deviter_next1(deviter_t *);
187 static void deviter_reinit(deviter_t *);
188
189 struct deferred_config {
190 TAILQ_ENTRY(deferred_config) dc_queue;
191 device_t dc_dev;
192 void (*dc_func)(device_t);
193 };
194
195 TAILQ_HEAD(deferred_config_head, deferred_config);
196
197 static struct deferred_config_head deferred_config_queue =
198 TAILQ_HEAD_INITIALIZER(deferred_config_queue);
199 static struct deferred_config_head interrupt_config_queue =
200 TAILQ_HEAD_INITIALIZER(interrupt_config_queue);
201 static int interrupt_config_threads = 8;
202 static struct deferred_config_head mountroot_config_queue =
203 TAILQ_HEAD_INITIALIZER(mountroot_config_queue);
204 static int mountroot_config_threads = 2;
205 static lwp_t **mountroot_config_lwpids;
206 static size_t mountroot_config_lwpids_size;
207 bool root_is_mounted = false;
208
209 static void config_process_deferred(struct deferred_config_head *, device_t);
210
211 /* Hooks to finalize configuration once all real devices have been found. */
212 struct finalize_hook {
213 TAILQ_ENTRY(finalize_hook) f_list;
214 int (*f_func)(device_t);
215 device_t f_dev;
216 };
217 static TAILQ_HEAD(, finalize_hook) config_finalize_list =
218 TAILQ_HEAD_INITIALIZER(config_finalize_list);
219 static int config_finalize_done;
220
221 /* list of all devices */
222 static struct devicelist alldevs = TAILQ_HEAD_INITIALIZER(alldevs);
223 static kmutex_t alldevs_lock __cacheline_aligned;
224 static devgen_t alldevs_gen = 1;
225 static int alldevs_nread = 0;
226 static int alldevs_nwrite = 0;
227 static bool alldevs_garbage = false;
228
229 static struct devicelist config_pending =
230 TAILQ_HEAD_INITIALIZER(config_pending);
231 static kmutex_t config_misc_lock;
232 static kcondvar_t config_misc_cv;
233
234 static bool detachall = false;
235
236 #define STREQ(s1, s2) \
237 (*(s1) == *(s2) && strcmp((s1), (s2)) == 0)
238
239 static bool config_initialized = false; /* config_init() has been called. */
240
241 static int config_do_twiddle;
242 static callout_t config_twiddle_ch;
243
244 static void sysctl_detach_setup(struct sysctllog **);
245
246 int no_devmon_insert(const char *, prop_dictionary_t);
247 int (*devmon_insert_vec)(const char *, prop_dictionary_t) = no_devmon_insert;
248
249 typedef int (*cfdriver_fn)(struct cfdriver *);
250 static int
251 frob_cfdrivervec(struct cfdriver * const *cfdriverv,
252 cfdriver_fn drv_do, cfdriver_fn drv_undo,
253 const char *style, bool dopanic)
254 {
255 void (*pr)(const char *, ...) __printflike(1, 2) =
256 dopanic ? panic : printf;
257 int i, error = 0, e2 __diagused;
258
259 for (i = 0; cfdriverv[i] != NULL; i++) {
260 if ((error = drv_do(cfdriverv[i])) != 0) {
261 pr("configure: `%s' driver %s failed: %d",
262 cfdriverv[i]->cd_name, style, error);
263 goto bad;
264 }
265 }
266
267 KASSERT(error == 0);
268 return 0;
269
270 bad:
271 printf("\n");
272 for (i--; i >= 0; i--) {
273 e2 = drv_undo(cfdriverv[i]);
274 KASSERT(e2 == 0);
275 }
276
277 return error;
278 }
279
280 typedef int (*cfattach_fn)(const char *, struct cfattach *);
281 static int
282 frob_cfattachvec(const struct cfattachinit *cfattachv,
283 cfattach_fn att_do, cfattach_fn att_undo,
284 const char *style, bool dopanic)
285 {
286 const struct cfattachinit *cfai = NULL;
287 void (*pr)(const char *, ...) __printflike(1, 2) =
288 dopanic ? panic : printf;
289 int j = 0, error = 0, e2 __diagused;
290
291 for (cfai = &cfattachv[0]; cfai->cfai_name != NULL; cfai++) {
292 for (j = 0; cfai->cfai_list[j] != NULL; j++) {
293 if ((error = att_do(cfai->cfai_name,
294 cfai->cfai_list[j])) != 0) {
295 pr("configure: attachment `%s' "
296 "of `%s' driver %s failed: %d",
297 cfai->cfai_list[j]->ca_name,
298 cfai->cfai_name, style, error);
299 goto bad;
300 }
301 }
302 }
303
304 KASSERT(error == 0);
305 return 0;
306
307 bad:
308 /*
309 * Rollback in reverse order. dunno if super-important, but
310 * do that anyway. Although the code looks a little like
311 * someone did a little integration (in the math sense).
312 */
313 printf("\n");
314 if (cfai) {
315 bool last;
316
317 for (last = false; last == false; ) {
318 if (cfai == &cfattachv[0])
319 last = true;
320 for (j--; j >= 0; j--) {
321 e2 = att_undo(cfai->cfai_name,
322 cfai->cfai_list[j]);
323 KASSERT(e2 == 0);
324 }
325 if (!last) {
326 cfai--;
327 for (j = 0; cfai->cfai_list[j] != NULL; j++)
328 ;
329 }
330 }
331 }
332
333 return error;
334 }
335
336 /*
337 * Initialize the autoconfiguration data structures. Normally this
338 * is done by configure(), but some platforms need to do this very
339 * early (to e.g. initialize the console).
340 */
341 void
342 config_init(void)
343 {
344
345 KASSERT(config_initialized == false);
346
347 mutex_init(&alldevs_lock, MUTEX_DEFAULT, IPL_VM);
348
349 mutex_init(&config_misc_lock, MUTEX_DEFAULT, IPL_NONE);
350 cv_init(&config_misc_cv, "cfgmisc");
351
352 callout_init(&config_twiddle_ch, CALLOUT_MPSAFE);
353
354 frob_cfdrivervec(cfdriver_list_initial,
355 config_cfdriver_attach, NULL, "bootstrap", true);
356 frob_cfattachvec(cfattachinit,
357 config_cfattach_attach, NULL, "bootstrap", true);
358
359 initcftable.ct_cfdata = cfdata;
360 TAILQ_INSERT_TAIL(&allcftables, &initcftable, ct_list);
361
362 rnd_attach_source(&rnd_autoconf_source, "autoconf", RND_TYPE_UNKNOWN,
363 RND_FLAG_COLLECT_TIME);
364
365 config_initialized = true;
366 }
367
368 /*
369 * Init or fini drivers and attachments. Either all or none
370 * are processed (via rollback). It would be nice if this were
371 * atomic to outside consumers, but with the current state of
372 * locking ...
373 */
374 int
375 config_init_component(struct cfdriver * const *cfdriverv,
376 const struct cfattachinit *cfattachv, struct cfdata *cfdatav)
377 {
378 int error;
379
380 KASSERT(KERNEL_LOCKED_P());
381
382 if ((error = frob_cfdrivervec(cfdriverv,
383 config_cfdriver_attach, config_cfdriver_detach, "init", false))!= 0)
384 return error;
385 if ((error = frob_cfattachvec(cfattachv,
386 config_cfattach_attach, config_cfattach_detach,
387 "init", false)) != 0) {
388 frob_cfdrivervec(cfdriverv,
389 config_cfdriver_detach, NULL, "init rollback", true);
390 return error;
391 }
392 if ((error = config_cfdata_attach(cfdatav, 1)) != 0) {
393 frob_cfattachvec(cfattachv,
394 config_cfattach_detach, NULL, "init rollback", true);
395 frob_cfdrivervec(cfdriverv,
396 config_cfdriver_detach, NULL, "init rollback", true);
397 return error;
398 }
399
400 return 0;
401 }
402
403 int
404 config_fini_component(struct cfdriver * const *cfdriverv,
405 const struct cfattachinit *cfattachv, struct cfdata *cfdatav)
406 {
407 int error;
408
409 KASSERT(KERNEL_LOCKED_P());
410
411 if ((error = config_cfdata_detach(cfdatav)) != 0)
412 return error;
413 if ((error = frob_cfattachvec(cfattachv,
414 config_cfattach_detach, config_cfattach_attach,
415 "fini", false)) != 0) {
416 if (config_cfdata_attach(cfdatav, 0) != 0)
417 panic("config_cfdata fini rollback failed");
418 return error;
419 }
420 if ((error = frob_cfdrivervec(cfdriverv,
421 config_cfdriver_detach, config_cfdriver_attach,
422 "fini", false)) != 0) {
423 frob_cfattachvec(cfattachv,
424 config_cfattach_attach, NULL, "fini rollback", true);
425 if (config_cfdata_attach(cfdatav, 0) != 0)
426 panic("config_cfdata fini rollback failed");
427 return error;
428 }
429
430 return 0;
431 }
432
433 void
434 config_init_mi(void)
435 {
436
437 if (!config_initialized)
438 config_init();
439
440 sysctl_detach_setup(NULL);
441 }
442
443 void
444 config_deferred(device_t dev)
445 {
446
447 KASSERT(KERNEL_LOCKED_P());
448
449 config_process_deferred(&deferred_config_queue, dev);
450 config_process_deferred(&interrupt_config_queue, dev);
451 config_process_deferred(&mountroot_config_queue, dev);
452 }
453
454 static void
455 config_interrupts_thread(void *cookie)
456 {
457 struct deferred_config *dc;
458 device_t dev;
459
460 mutex_enter(&config_misc_lock);
461 while ((dc = TAILQ_FIRST(&interrupt_config_queue)) != NULL) {
462 TAILQ_REMOVE(&interrupt_config_queue, dc, dc_queue);
463 mutex_exit(&config_misc_lock);
464
465 dev = dc->dc_dev;
466 (*dc->dc_func)(dev);
467 if (!device_pmf_is_registered(dev))
468 aprint_debug_dev(dev,
469 "WARNING: power management not supported\n");
470 config_pending_decr(dev);
471 kmem_free(dc, sizeof(*dc));
472
473 mutex_enter(&config_misc_lock);
474 dev->dv_flags &= ~DVF_ATTACH_INPROGRESS;
475 }
476 mutex_exit(&config_misc_lock);
477
478 kthread_exit(0);
479 }
480
481 void
482 config_create_interruptthreads(void)
483 {
484 int i;
485
486 for (i = 0; i < interrupt_config_threads; i++) {
487 (void)kthread_create(PRI_NONE, 0/*XXXSMP */, NULL,
488 config_interrupts_thread, NULL, NULL, "configintr");
489 }
490 }
491
492 static void
493 config_mountroot_thread(void *cookie)
494 {
495 struct deferred_config *dc;
496
497 mutex_enter(&config_misc_lock);
498 while ((dc = TAILQ_FIRST(&mountroot_config_queue)) != NULL) {
499 TAILQ_REMOVE(&mountroot_config_queue, dc, dc_queue);
500 mutex_exit(&config_misc_lock);
501
502 (*dc->dc_func)(dc->dc_dev);
503 kmem_free(dc, sizeof(*dc));
504
505 mutex_enter(&config_misc_lock);
506 }
507 mutex_exit(&config_misc_lock);
508
509 kthread_exit(0);
510 }
511
512 void
513 config_create_mountrootthreads(void)
514 {
515 int i;
516
517 if (!root_is_mounted)
518 root_is_mounted = true;
519
520 mountroot_config_lwpids_size = sizeof(mountroot_config_lwpids) *
521 mountroot_config_threads;
522 mountroot_config_lwpids = kmem_alloc(mountroot_config_lwpids_size,
523 KM_NOSLEEP);
524 KASSERT(mountroot_config_lwpids);
525 for (i = 0; i < mountroot_config_threads; i++) {
526 mountroot_config_lwpids[i] = 0;
527 (void)kthread_create(PRI_NONE, KTHREAD_MUSTJOIN/* XXXSMP */,
528 NULL, config_mountroot_thread, NULL,
529 &mountroot_config_lwpids[i],
530 "configroot");
531 }
532 }
533
534 void
535 config_finalize_mountroot(void)
536 {
537 int i, error;
538
539 for (i = 0; i < mountroot_config_threads; i++) {
540 if (mountroot_config_lwpids[i] == 0)
541 continue;
542
543 error = kthread_join(mountroot_config_lwpids[i]);
544 if (error)
545 printf("%s: thread %x joined with error %d\n",
546 __func__, i, error);
547 }
548 kmem_free(mountroot_config_lwpids, mountroot_config_lwpids_size);
549 }
550
551 /*
552 * Announce device attach/detach to userland listeners.
553 */
554
555 int
556 no_devmon_insert(const char *name, prop_dictionary_t p)
557 {
558
559 return ENODEV;
560 }
561
562 static void
563 devmon_report_device(device_t dev, bool isattach)
564 {
565 prop_dictionary_t ev, dict = device_properties(dev);
566 const char *parent;
567 const char *what;
568 const char *where;
569 device_t pdev = device_parent(dev);
570
571 /* If currently no drvctl device, just return */
572 if (devmon_insert_vec == no_devmon_insert)
573 return;
574
575 ev = prop_dictionary_create();
576 if (ev == NULL)
577 return;
578
579 what = (isattach ? "device-attach" : "device-detach");
580 parent = (pdev == NULL ? "root" : device_xname(pdev));
581 if (prop_dictionary_get_string(dict, "location", &where)) {
582 prop_dictionary_set_string(ev, "location", where);
583 aprint_debug("ev: %s %s at %s in [%s]\n",
584 what, device_xname(dev), parent, where);
585 }
586 if (!prop_dictionary_set_string(ev, "device", device_xname(dev)) ||
587 !prop_dictionary_set_string(ev, "parent", parent)) {
588 prop_object_release(ev);
589 return;
590 }
591
592 if ((*devmon_insert_vec)(what, ev) != 0)
593 prop_object_release(ev);
594 }
595
596 /*
597 * Add a cfdriver to the system.
598 */
599 int
600 config_cfdriver_attach(struct cfdriver *cd)
601 {
602 struct cfdriver *lcd;
603
604 /* Make sure this driver isn't already in the system. */
605 LIST_FOREACH(lcd, &allcfdrivers, cd_list) {
606 if (STREQ(lcd->cd_name, cd->cd_name))
607 return EEXIST;
608 }
609
610 LIST_INIT(&cd->cd_attach);
611 LIST_INSERT_HEAD(&allcfdrivers, cd, cd_list);
612
613 return 0;
614 }
615
616 /*
617 * Remove a cfdriver from the system.
618 */
619 int
620 config_cfdriver_detach(struct cfdriver *cd)
621 {
622 struct alldevs_foray af;
623 int i, rc = 0;
624
625 config_alldevs_enter(&af);
626 /* Make sure there are no active instances. */
627 for (i = 0; i < cd->cd_ndevs; i++) {
628 if (cd->cd_devs[i] != NULL) {
629 rc = EBUSY;
630 break;
631 }
632 }
633 config_alldevs_exit(&af);
634
635 if (rc != 0)
636 return rc;
637
638 /* ...and no attachments loaded. */
639 if (LIST_EMPTY(&cd->cd_attach) == 0)
640 return EBUSY;
641
642 LIST_REMOVE(cd, cd_list);
643
644 KASSERT(cd->cd_devs == NULL);
645
646 return 0;
647 }
648
649 /*
650 * Look up a cfdriver by name.
651 */
652 struct cfdriver *
653 config_cfdriver_lookup(const char *name)
654 {
655 struct cfdriver *cd;
656
657 LIST_FOREACH(cd, &allcfdrivers, cd_list) {
658 if (STREQ(cd->cd_name, name))
659 return cd;
660 }
661
662 return NULL;
663 }
664
665 /*
666 * Add a cfattach to the specified driver.
667 */
668 int
669 config_cfattach_attach(const char *driver, struct cfattach *ca)
670 {
671 struct cfattach *lca;
672 struct cfdriver *cd;
673
674 cd = config_cfdriver_lookup(driver);
675 if (cd == NULL)
676 return ESRCH;
677
678 /* Make sure this attachment isn't already on this driver. */
679 LIST_FOREACH(lca, &cd->cd_attach, ca_list) {
680 if (STREQ(lca->ca_name, ca->ca_name))
681 return EEXIST;
682 }
683
684 LIST_INSERT_HEAD(&cd->cd_attach, ca, ca_list);
685
686 return 0;
687 }
688
689 /*
690 * Remove a cfattach from the specified driver.
691 */
692 int
693 config_cfattach_detach(const char *driver, struct cfattach *ca)
694 {
695 struct alldevs_foray af;
696 struct cfdriver *cd;
697 device_t dev;
698 int i, rc = 0;
699
700 cd = config_cfdriver_lookup(driver);
701 if (cd == NULL)
702 return ESRCH;
703
704 config_alldevs_enter(&af);
705 /* Make sure there are no active instances. */
706 for (i = 0; i < cd->cd_ndevs; i++) {
707 if ((dev = cd->cd_devs[i]) == NULL)
708 continue;
709 if (dev->dv_cfattach == ca) {
710 rc = EBUSY;
711 break;
712 }
713 }
714 config_alldevs_exit(&af);
715
716 if (rc != 0)
717 return rc;
718
719 LIST_REMOVE(ca, ca_list);
720
721 return 0;
722 }
723
724 /*
725 * Look up a cfattach by name.
726 */
727 static struct cfattach *
728 config_cfattach_lookup_cd(struct cfdriver *cd, const char *atname)
729 {
730 struct cfattach *ca;
731
732 LIST_FOREACH(ca, &cd->cd_attach, ca_list) {
733 if (STREQ(ca->ca_name, atname))
734 return ca;
735 }
736
737 return NULL;
738 }
739
740 /*
741 * Look up a cfattach by driver/attachment name.
742 */
743 struct cfattach *
744 config_cfattach_lookup(const char *name, const char *atname)
745 {
746 struct cfdriver *cd;
747
748 cd = config_cfdriver_lookup(name);
749 if (cd == NULL)
750 return NULL;
751
752 return config_cfattach_lookup_cd(cd, atname);
753 }
754
755 /*
756 * Apply the matching function and choose the best. This is used
757 * a few times and we want to keep the code small.
758 */
759 static void
760 mapply(struct matchinfo *m, cfdata_t cf)
761 {
762 int pri;
763
764 if (m->fn != NULL) {
765 pri = (*m->fn)(m->parent, cf, m->locs, m->aux);
766 } else {
767 pri = config_match(m->parent, cf, m->aux);
768 }
769 if (pri > m->pri) {
770 m->match = cf;
771 m->pri = pri;
772 }
773 }
774
775 int
776 config_stdsubmatch(device_t parent, cfdata_t cf, const int *locs, void *aux)
777 {
778 const struct cfiattrdata *ci;
779 const struct cflocdesc *cl;
780 int nlocs, i;
781
782 ci = cfiattr_lookup(cfdata_ifattr(cf), parent->dv_cfdriver);
783 KASSERT(ci);
784 nlocs = ci->ci_loclen;
785 KASSERT(!nlocs || locs);
786 for (i = 0; i < nlocs; i++) {
787 cl = &ci->ci_locdesc[i];
788 if (cl->cld_defaultstr != NULL &&
789 cf->cf_loc[i] == cl->cld_default)
790 continue;
791 if (cf->cf_loc[i] == locs[i])
792 continue;
793 return 0;
794 }
795
796 return config_match(parent, cf, aux);
797 }
798
799 /*
800 * Helper function: check whether the driver supports the interface attribute
801 * and return its descriptor structure.
802 */
803 static const struct cfiattrdata *
804 cfdriver_get_iattr(const struct cfdriver *cd, const char *ia)
805 {
806 const struct cfiattrdata * const *cpp;
807
808 if (cd->cd_attrs == NULL)
809 return 0;
810
811 for (cpp = cd->cd_attrs; *cpp; cpp++) {
812 if (STREQ((*cpp)->ci_name, ia)) {
813 /* Match. */
814 return *cpp;
815 }
816 }
817 return 0;
818 }
819
820 #if defined(DIAGNOSTIC)
821 static int
822 cfdriver_iattr_count(const struct cfdriver *cd)
823 {
824 const struct cfiattrdata * const *cpp;
825 int i;
826
827 if (cd->cd_attrs == NULL)
828 return 0;
829
830 for (i = 0, cpp = cd->cd_attrs; *cpp; cpp++) {
831 i++;
832 }
833 return i;
834 }
835 #endif /* DIAGNOSTIC */
836
837 /*
838 * Lookup an interface attribute description by name.
839 * If the driver is given, consider only its supported attributes.
840 */
841 const struct cfiattrdata *
842 cfiattr_lookup(const char *name, const struct cfdriver *cd)
843 {
844 const struct cfdriver *d;
845 const struct cfiattrdata *ia;
846
847 if (cd)
848 return cfdriver_get_iattr(cd, name);
849
850 LIST_FOREACH(d, &allcfdrivers, cd_list) {
851 ia = cfdriver_get_iattr(d, name);
852 if (ia)
853 return ia;
854 }
855 return 0;
856 }
857
858 /*
859 * Determine if `parent' is a potential parent for a device spec based
860 * on `cfp'.
861 */
862 static int
863 cfparent_match(const device_t parent, const struct cfparent *cfp)
864 {
865 struct cfdriver *pcd;
866
867 /* We don't match root nodes here. */
868 if (cfp == NULL)
869 return 0;
870
871 pcd = parent->dv_cfdriver;
872 KASSERT(pcd != NULL);
873
874 /*
875 * First, ensure this parent has the correct interface
876 * attribute.
877 */
878 if (!cfdriver_get_iattr(pcd, cfp->cfp_iattr))
879 return 0;
880
881 /*
882 * If no specific parent device instance was specified (i.e.
883 * we're attaching to the attribute only), we're done!
884 */
885 if (cfp->cfp_parent == NULL)
886 return 1;
887
888 /*
889 * Check the parent device's name.
890 */
891 if (STREQ(pcd->cd_name, cfp->cfp_parent) == 0)
892 return 0; /* not the same parent */
893
894 /*
895 * Make sure the unit number matches.
896 */
897 if (cfp->cfp_unit == DVUNIT_ANY || /* wildcard */
898 cfp->cfp_unit == parent->dv_unit)
899 return 1;
900
901 /* Unit numbers don't match. */
902 return 0;
903 }
904
905 /*
906 * Helper for config_cfdata_attach(): check all devices whether it could be
907 * parent any attachment in the config data table passed, and rescan.
908 */
909 static void
910 rescan_with_cfdata(const struct cfdata *cf)
911 {
912 device_t d;
913 const struct cfdata *cf1;
914 deviter_t di;
915
916 KASSERT(KERNEL_LOCKED_P());
917
918 /*
919 * "alldevs" is likely longer than a modules's cfdata, so make it
920 * the outer loop.
921 */
922 for (d = deviter_first(&di, 0); d != NULL; d = deviter_next(&di)) {
923
924 if (!(d->dv_cfattach->ca_rescan))
925 continue;
926
927 for (cf1 = cf; cf1->cf_name; cf1++) {
928
929 if (!cfparent_match(d, cf1->cf_pspec))
930 continue;
931
932 (*d->dv_cfattach->ca_rescan)(d,
933 cfdata_ifattr(cf1), cf1->cf_loc);
934
935 config_deferred(d);
936 }
937 }
938 deviter_release(&di);
939 }
940
941 /*
942 * Attach a supplemental config data table and rescan potential
943 * parent devices if required.
944 */
945 int
946 config_cfdata_attach(cfdata_t cf, int scannow)
947 {
948 struct cftable *ct;
949
950 KASSERT(KERNEL_LOCKED_P());
951
952 ct = kmem_alloc(sizeof(*ct), KM_SLEEP);
953 ct->ct_cfdata = cf;
954 TAILQ_INSERT_TAIL(&allcftables, ct, ct_list);
955
956 if (scannow)
957 rescan_with_cfdata(cf);
958
959 return 0;
960 }
961
962 /*
963 * Helper for config_cfdata_detach: check whether a device is
964 * found through any attachment in the config data table.
965 */
966 static int
967 dev_in_cfdata(device_t d, cfdata_t cf)
968 {
969 const struct cfdata *cf1;
970
971 for (cf1 = cf; cf1->cf_name; cf1++)
972 if (d->dv_cfdata == cf1)
973 return 1;
974
975 return 0;
976 }
977
978 /*
979 * Detach a supplemental config data table. Detach all devices found
980 * through that table (and thus keeping references to it) before.
981 */
982 int
983 config_cfdata_detach(cfdata_t cf)
984 {
985 device_t d;
986 int error = 0;
987 struct cftable *ct;
988 deviter_t di;
989
990 for (d = deviter_first(&di, DEVITER_F_RW); d != NULL;
991 d = deviter_next(&di)) {
992 if (!dev_in_cfdata(d, cf))
993 continue;
994 if ((error = config_detach(d, 0)) != 0)
995 break;
996 }
997 deviter_release(&di);
998 if (error) {
999 aprint_error_dev(d, "unable to detach instance\n");
1000 return error;
1001 }
1002
1003 TAILQ_FOREACH(ct, &allcftables, ct_list) {
1004 if (ct->ct_cfdata == cf) {
1005 TAILQ_REMOVE(&allcftables, ct, ct_list);
1006 kmem_free(ct, sizeof(*ct));
1007 return 0;
1008 }
1009 }
1010
1011 /* not found -- shouldn't happen */
1012 return EINVAL;
1013 }
1014
1015 /*
1016 * Invoke the "match" routine for a cfdata entry on behalf of
1017 * an external caller, usually a direct config "submatch" routine.
1018 */
1019 int
1020 config_match(device_t parent, cfdata_t cf, void *aux)
1021 {
1022 struct cfattach *ca;
1023
1024 KASSERT(KERNEL_LOCKED_P());
1025
1026 ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
1027 if (ca == NULL) {
1028 /* No attachment for this entry, oh well. */
1029 return 0;
1030 }
1031
1032 return (*ca->ca_match)(parent, cf, aux);
1033 }
1034
1035 /*
1036 * Invoke the "probe" routine for a cfdata entry on behalf of
1037 * an external caller, usually an indirect config "search" routine.
1038 */
1039 int
1040 config_probe(device_t parent, cfdata_t cf, void *aux)
1041 {
1042 /*
1043 * This is currently a synonym for config_match(), but this
1044 * is an implementation detail; "match" and "probe" routines
1045 * have different behaviors.
1046 *
1047 * XXX config_probe() should return a bool, because there is
1048 * XXX no match score for probe -- it's either there or it's
1049 * XXX not, but some ports abuse the return value as a way
1050 * XXX to attach "critical" devices before "non-critical"
1051 * XXX devices.
1052 */
1053 return config_match(parent, cf, aux);
1054 }
1055
1056 static void
1057 config_get_cfargs(cfarg_t tag,
1058 cfsubmatch_t *fnp, /* output */
1059 const char **ifattrp, /* output */
1060 const int **locsp, /* output */
1061 devhandle_t *handlep, /* output */
1062 va_list ap)
1063 {
1064 cfsubmatch_t fn = NULL;
1065 const char *ifattr = NULL;
1066 const int *locs = NULL;
1067 devhandle_t handle;
1068
1069 devhandle_invalidate(&handle);
1070
1071 while (tag != CFARG_EOL) {
1072 switch (tag) {
1073 /*
1074 * CFARG_SUBMATCH and CFARG_SEARCH are synonyms, but this
1075 * is merely an implementation detail. They are distinct
1076 * from the caller's point of view.
1077 */
1078 case CFARG_SUBMATCH:
1079 case CFARG_SEARCH:
1080 /* Only allow one function to be specified. */
1081 if (fn != NULL) {
1082 panic("%s: caller specified both "
1083 "SUBMATCH and SEARCH", __func__);
1084 }
1085 fn = va_arg(ap, cfsubmatch_t);
1086 break;
1087
1088 case CFARG_IATTR:
1089 ifattr = va_arg(ap, const char *);
1090 break;
1091
1092 case CFARG_LOCATORS:
1093 locs = va_arg(ap, const int *);
1094 break;
1095
1096 case CFARG_DEVHANDLE:
1097 handle = va_arg(ap, devhandle_t);
1098 break;
1099
1100 default:
1101 panic("%s: unknown cfarg tag: %d\n",
1102 __func__, tag);
1103 }
1104 tag = va_arg(ap, cfarg_t);
1105 }
1106
1107 if (fnp != NULL)
1108 *fnp = fn;
1109 if (ifattrp != NULL)
1110 *ifattrp = ifattr;
1111 if (locsp != NULL)
1112 *locsp = locs;
1113 if (handlep != NULL)
1114 *handlep = handle;
1115 }
1116
1117 /*
1118 * Iterate over all potential children of some device, calling the given
1119 * function (default being the child's match function) for each one.
1120 * Nonzero returns are matches; the highest value returned is considered
1121 * the best match. Return the `found child' if we got a match, or NULL
1122 * otherwise. The `aux' pointer is simply passed on through.
1123 *
1124 * Note that this function is designed so that it can be used to apply
1125 * an arbitrary function to all potential children (its return value
1126 * can be ignored).
1127 */
1128 cfdata_t
1129 config_vsearch(device_t parent, void *aux, cfarg_t tag, va_list ap)
1130 {
1131 cfsubmatch_t fn;
1132 const char *ifattr;
1133 const int *locs;
1134 struct cftable *ct;
1135 cfdata_t cf;
1136 struct matchinfo m;
1137
1138 config_get_cfargs(tag, &fn, &ifattr, &locs, NULL, ap);
1139
1140 KASSERT(config_initialized);
1141 KASSERT(!ifattr || cfdriver_get_iattr(parent->dv_cfdriver, ifattr));
1142 KASSERT(ifattr || cfdriver_iattr_count(parent->dv_cfdriver) < 2);
1143
1144 m.fn = fn;
1145 m.parent = parent;
1146 m.locs = locs;
1147 m.aux = aux;
1148 m.match = NULL;
1149 m.pri = 0;
1150
1151 TAILQ_FOREACH(ct, &allcftables, ct_list) {
1152 for (cf = ct->ct_cfdata; cf->cf_name; cf++) {
1153
1154 /* We don't match root nodes here. */
1155 if (!cf->cf_pspec)
1156 continue;
1157
1158 /*
1159 * Skip cf if no longer eligible, otherwise scan
1160 * through parents for one matching `parent', and
1161 * try match function.
1162 */
1163 if (cf->cf_fstate == FSTATE_FOUND)
1164 continue;
1165 if (cf->cf_fstate == FSTATE_DNOTFOUND ||
1166 cf->cf_fstate == FSTATE_DSTAR)
1167 continue;
1168
1169 /*
1170 * If an interface attribute was specified,
1171 * consider only children which attach to
1172 * that attribute.
1173 */
1174 if (ifattr && !STREQ(ifattr, cfdata_ifattr(cf)))
1175 continue;
1176
1177 if (cfparent_match(parent, cf->cf_pspec))
1178 mapply(&m, cf);
1179 }
1180 }
1181 return m.match;
1182 }
1183
1184 cfdata_t
1185 config_search(device_t parent, void *aux, cfarg_t tag, ...)
1186 {
1187 cfdata_t cf;
1188 va_list ap;
1189
1190 va_start(ap, tag);
1191 cf = config_vsearch(parent, aux, tag, ap);
1192 va_end(ap);
1193
1194 return cf;
1195 }
1196
1197 /*
1198 * Find the given root device.
1199 * This is much like config_search, but there is no parent.
1200 * Don't bother with multiple cfdata tables; the root node
1201 * must always be in the initial table.
1202 */
1203 cfdata_t
1204 config_rootsearch(cfsubmatch_t fn, const char *rootname, void *aux)
1205 {
1206 cfdata_t cf;
1207 const short *p;
1208 struct matchinfo m;
1209
1210 m.fn = fn;
1211 m.parent = ROOT;
1212 m.aux = aux;
1213 m.match = NULL;
1214 m.pri = 0;
1215 m.locs = 0;
1216 /*
1217 * Look at root entries for matching name. We do not bother
1218 * with found-state here since only one root should ever be
1219 * searched (and it must be done first).
1220 */
1221 for (p = cfroots; *p >= 0; p++) {
1222 cf = &cfdata[*p];
1223 if (strcmp(cf->cf_name, rootname) == 0)
1224 mapply(&m, cf);
1225 }
1226 return m.match;
1227 }
1228
1229 static const char * const msgs[] = {
1230 [QUIET] = "",
1231 [UNCONF] = " not configured\n",
1232 [UNSUPP] = " unsupported\n",
1233 };
1234
1235 /*
1236 * The given `aux' argument describes a device that has been found
1237 * on the given parent, but not necessarily configured. Locate the
1238 * configuration data for that device (using the submatch function
1239 * provided, or using candidates' cd_match configuration driver
1240 * functions) and attach it, and return its device_t. If the device was
1241 * not configured, call the given `print' function and return NULL.
1242 */
1243 device_t
1244 config_vfound(device_t parent, void *aux, cfprint_t print, cfarg_t tag,
1245 va_list ap)
1246 {
1247 cfdata_t cf;
1248 va_list nap;
1249
1250 va_copy(nap, ap);
1251 cf = config_vsearch(parent, aux, tag, nap);
1252 va_end(nap);
1253
1254 if (cf != NULL) {
1255 return config_vattach(parent, cf, aux, print, tag, ap);
1256 }
1257
1258 if (print) {
1259 if (config_do_twiddle && cold)
1260 twiddle();
1261
1262 const int pret = (*print)(aux, device_xname(parent));
1263 KASSERT(pret >= 0);
1264 KASSERT(pret < __arraycount(msgs));
1265 KASSERT(msgs[pret] != NULL);
1266 aprint_normal("%s", msgs[pret]);
1267 }
1268
1269 /*
1270 * This has the effect of mixing in a single timestamp to the
1271 * entropy pool. Experiments indicate the estimator will almost
1272 * always attribute one bit of entropy to this sample; analysis
1273 * of device attach/detach timestamps on FreeBSD indicates 4
1274 * bits of entropy/sample so this seems appropriately conservative.
1275 */
1276 rnd_add_uint32(&rnd_autoconf_source, 0);
1277 return NULL;
1278 }
1279
1280 device_t
1281 config_found(device_t parent, void *aux, cfprint_t print, cfarg_t tag, ...)
1282 {
1283 device_t dev;
1284 va_list ap;
1285
1286 va_start(ap, tag);
1287 dev = config_vfound(parent, aux, print, tag, ap);
1288 va_end(ap);
1289
1290 return dev;
1291 }
1292
1293 /*
1294 * As above, but for root devices.
1295 */
1296 device_t
1297 config_rootfound(const char *rootname, void *aux)
1298 {
1299 cfdata_t cf;
1300 device_t dev = NULL;
1301
1302 KERNEL_LOCK(1, NULL);
1303 if ((cf = config_rootsearch(NULL, rootname, aux)) != NULL)
1304 dev = config_attach(ROOT, cf, aux, NULL, CFARG_EOL);
1305 else
1306 aprint_error("root device %s not configured\n", rootname);
1307 KERNEL_UNLOCK_ONE(NULL);
1308 return dev;
1309 }
1310
1311 /* just like sprintf(buf, "%d") except that it works from the end */
1312 static char *
1313 number(char *ep, int n)
1314 {
1315
1316 *--ep = 0;
1317 while (n >= 10) {
1318 *--ep = (n % 10) + '0';
1319 n /= 10;
1320 }
1321 *--ep = n + '0';
1322 return ep;
1323 }
1324
1325 /*
1326 * Expand the size of the cd_devs array if necessary.
1327 *
1328 * The caller must hold alldevs_lock. config_makeroom() may release and
1329 * re-acquire alldevs_lock, so callers should re-check conditions such
1330 * as alldevs_nwrite == 0 and alldevs_nread == 0 when config_makeroom()
1331 * returns.
1332 */
1333 static void
1334 config_makeroom(int n, struct cfdriver *cd)
1335 {
1336 int ondevs, nndevs;
1337 device_t *osp, *nsp;
1338
1339 KASSERT(mutex_owned(&alldevs_lock));
1340 alldevs_nwrite++;
1341
1342 for (nndevs = MAX(4, cd->cd_ndevs); nndevs <= n; nndevs += nndevs)
1343 ;
1344
1345 while (n >= cd->cd_ndevs) {
1346 /*
1347 * Need to expand the array.
1348 */
1349 ondevs = cd->cd_ndevs;
1350 osp = cd->cd_devs;
1351
1352 /*
1353 * Release alldevs_lock around allocation, which may
1354 * sleep.
1355 */
1356 mutex_exit(&alldevs_lock);
1357 nsp = kmem_alloc(sizeof(device_t) * nndevs, KM_SLEEP);
1358 mutex_enter(&alldevs_lock);
1359
1360 /*
1361 * If another thread moved the array while we did
1362 * not hold alldevs_lock, try again.
1363 */
1364 if (cd->cd_devs != osp) {
1365 mutex_exit(&alldevs_lock);
1366 kmem_free(nsp, sizeof(device_t) * nndevs);
1367 mutex_enter(&alldevs_lock);
1368 continue;
1369 }
1370
1371 memset(nsp + ondevs, 0, sizeof(device_t) * (nndevs - ondevs));
1372 if (ondevs != 0)
1373 memcpy(nsp, cd->cd_devs, sizeof(device_t) * ondevs);
1374
1375 cd->cd_ndevs = nndevs;
1376 cd->cd_devs = nsp;
1377 if (ondevs != 0) {
1378 mutex_exit(&alldevs_lock);
1379 kmem_free(osp, sizeof(device_t) * ondevs);
1380 mutex_enter(&alldevs_lock);
1381 }
1382 }
1383 KASSERT(mutex_owned(&alldevs_lock));
1384 alldevs_nwrite--;
1385 }
1386
1387 /*
1388 * Put dev into the devices list.
1389 */
1390 static void
1391 config_devlink(device_t dev)
1392 {
1393
1394 mutex_enter(&alldevs_lock);
1395
1396 KASSERT(device_cfdriver(dev)->cd_devs[dev->dv_unit] == dev);
1397
1398 dev->dv_add_gen = alldevs_gen;
1399 /* It is safe to add a device to the tail of the list while
1400 * readers and writers are in the list.
1401 */
1402 TAILQ_INSERT_TAIL(&alldevs, dev, dv_list);
1403 mutex_exit(&alldevs_lock);
1404 }
1405
1406 static void
1407 config_devfree(device_t dev)
1408 {
1409 KASSERT(dev->dv_flags & DVF_PRIV_ALLOC);
1410
1411 if (dev->dv_cfattach->ca_devsize > 0)
1412 kmem_free(dev->dv_private, dev->dv_cfattach->ca_devsize);
1413 kmem_free(dev, sizeof(*dev));
1414 }
1415
1416 /*
1417 * Caller must hold alldevs_lock.
1418 */
1419 static void
1420 config_devunlink(device_t dev, struct devicelist *garbage)
1421 {
1422 struct device_garbage *dg = &dev->dv_garbage;
1423 cfdriver_t cd = device_cfdriver(dev);
1424 int i;
1425
1426 KASSERT(mutex_owned(&alldevs_lock));
1427
1428 /* Unlink from device list. Link to garbage list. */
1429 TAILQ_REMOVE(&alldevs, dev, dv_list);
1430 TAILQ_INSERT_TAIL(garbage, dev, dv_list);
1431
1432 /* Remove from cfdriver's array. */
1433 cd->cd_devs[dev->dv_unit] = NULL;
1434
1435 /*
1436 * If the device now has no units in use, unlink its softc array.
1437 */
1438 for (i = 0; i < cd->cd_ndevs; i++) {
1439 if (cd->cd_devs[i] != NULL)
1440 break;
1441 }
1442 /* Nothing found. Unlink, now. Deallocate, later. */
1443 if (i == cd->cd_ndevs) {
1444 dg->dg_ndevs = cd->cd_ndevs;
1445 dg->dg_devs = cd->cd_devs;
1446 cd->cd_devs = NULL;
1447 cd->cd_ndevs = 0;
1448 }
1449 }
1450
1451 static void
1452 config_devdelete(device_t dev)
1453 {
1454 struct device_garbage *dg = &dev->dv_garbage;
1455 device_lock_t dvl = device_getlock(dev);
1456
1457 if (dg->dg_devs != NULL)
1458 kmem_free(dg->dg_devs, sizeof(device_t) * dg->dg_ndevs);
1459
1460 cv_destroy(&dvl->dvl_cv);
1461 mutex_destroy(&dvl->dvl_mtx);
1462
1463 KASSERT(dev->dv_properties != NULL);
1464 prop_object_release(dev->dv_properties);
1465
1466 if (dev->dv_activity_handlers)
1467 panic("%s with registered handlers", __func__);
1468
1469 if (dev->dv_locators) {
1470 size_t amount = *--dev->dv_locators;
1471 kmem_free(dev->dv_locators, amount);
1472 }
1473
1474 config_devfree(dev);
1475 }
1476
1477 static int
1478 config_unit_nextfree(cfdriver_t cd, cfdata_t cf)
1479 {
1480 int unit;
1481
1482 if (cf->cf_fstate == FSTATE_STAR) {
1483 for (unit = cf->cf_unit; unit < cd->cd_ndevs; unit++)
1484 if (cd->cd_devs[unit] == NULL)
1485 break;
1486 /*
1487 * unit is now the unit of the first NULL device pointer,
1488 * or max(cd->cd_ndevs,cf->cf_unit).
1489 */
1490 } else {
1491 unit = cf->cf_unit;
1492 if (unit < cd->cd_ndevs && cd->cd_devs[unit] != NULL)
1493 unit = -1;
1494 }
1495 return unit;
1496 }
1497
1498 static int
1499 config_unit_alloc(device_t dev, cfdriver_t cd, cfdata_t cf)
1500 {
1501 struct alldevs_foray af;
1502 int unit;
1503
1504 config_alldevs_enter(&af);
1505 for (;;) {
1506 unit = config_unit_nextfree(cd, cf);
1507 if (unit == -1)
1508 break;
1509 if (unit < cd->cd_ndevs) {
1510 cd->cd_devs[unit] = dev;
1511 dev->dv_unit = unit;
1512 break;
1513 }
1514 config_makeroom(unit, cd);
1515 }
1516 config_alldevs_exit(&af);
1517
1518 return unit;
1519 }
1520
1521 static device_t
1522 config_vdevalloc(const device_t parent, const cfdata_t cf, cfarg_t tag,
1523 va_list ap)
1524 {
1525 cfdriver_t cd;
1526 cfattach_t ca;
1527 size_t lname, lunit;
1528 const char *xunit;
1529 int myunit;
1530 char num[10];
1531 device_t dev;
1532 void *dev_private;
1533 const struct cfiattrdata *ia;
1534 device_lock_t dvl;
1535 const int *locs;
1536
1537 cd = config_cfdriver_lookup(cf->cf_name);
1538 if (cd == NULL)
1539 return NULL;
1540
1541 ca = config_cfattach_lookup_cd(cd, cf->cf_atname);
1542 if (ca == NULL)
1543 return NULL;
1544
1545 /* get memory for all device vars */
1546 KASSERT(ca->ca_flags & DVF_PRIV_ALLOC);
1547 if (ca->ca_devsize > 0) {
1548 dev_private = kmem_zalloc(ca->ca_devsize, KM_SLEEP);
1549 } else {
1550 dev_private = NULL;
1551 }
1552 dev = kmem_zalloc(sizeof(*dev), KM_SLEEP);
1553
1554 /*
1555 * If a handle was supplied to config_attach(), we'll get it
1556 * assigned automatically here. If not, then we'll get the
1557 * default invalid handle.
1558 */
1559 config_get_cfargs(tag, NULL, NULL, &locs, &dev->dv_handle, ap);
1560
1561 dev->dv_class = cd->cd_class;
1562 dev->dv_cfdata = cf;
1563 dev->dv_cfdriver = cd;
1564 dev->dv_cfattach = ca;
1565 dev->dv_activity_count = 0;
1566 dev->dv_activity_handlers = NULL;
1567 dev->dv_private = dev_private;
1568 dev->dv_flags = ca->ca_flags; /* inherit flags from class */
1569
1570 myunit = config_unit_alloc(dev, cd, cf);
1571 if (myunit == -1) {
1572 config_devfree(dev);
1573 return NULL;
1574 }
1575
1576 /* compute length of name and decimal expansion of unit number */
1577 lname = strlen(cd->cd_name);
1578 xunit = number(&num[sizeof(num)], myunit);
1579 lunit = &num[sizeof(num)] - xunit;
1580 if (lname + lunit > sizeof(dev->dv_xname))
1581 panic("config_vdevalloc: device name too long");
1582
1583 dvl = device_getlock(dev);
1584
1585 mutex_init(&dvl->dvl_mtx, MUTEX_DEFAULT, IPL_NONE);
1586 cv_init(&dvl->dvl_cv, "pmfsusp");
1587
1588 memcpy(dev->dv_xname, cd->cd_name, lname);
1589 memcpy(dev->dv_xname + lname, xunit, lunit);
1590 dev->dv_parent = parent;
1591 if (parent != NULL)
1592 dev->dv_depth = parent->dv_depth + 1;
1593 else
1594 dev->dv_depth = 0;
1595 dev->dv_flags |= DVF_ACTIVE; /* always initially active */
1596 if (locs) {
1597 KASSERT(parent); /* no locators at root */
1598 ia = cfiattr_lookup(cfdata_ifattr(cf), parent->dv_cfdriver);
1599 dev->dv_locators =
1600 kmem_alloc(sizeof(int) * (ia->ci_loclen + 1), KM_SLEEP);
1601 *dev->dv_locators++ = sizeof(int) * (ia->ci_loclen + 1);
1602 memcpy(dev->dv_locators, locs, sizeof(int) * ia->ci_loclen);
1603 }
1604 dev->dv_properties = prop_dictionary_create();
1605 KASSERT(dev->dv_properties != NULL);
1606
1607 prop_dictionary_set_string_nocopy(dev->dv_properties,
1608 "device-driver", dev->dv_cfdriver->cd_name);
1609 prop_dictionary_set_uint16(dev->dv_properties,
1610 "device-unit", dev->dv_unit);
1611 if (parent != NULL) {
1612 prop_dictionary_set_string(dev->dv_properties,
1613 "device-parent", device_xname(parent));
1614 }
1615
1616 if (dev->dv_cfdriver->cd_attrs != NULL)
1617 config_add_attrib_dict(dev);
1618
1619 return dev;
1620 }
1621
1622 static device_t
1623 config_devalloc(const device_t parent, const cfdata_t cf, cfarg_t tag, ...)
1624 {
1625 device_t dev;
1626 va_list ap;
1627
1628 va_start(ap, tag);
1629 dev = config_vdevalloc(parent, cf, tag, ap);
1630 va_end(ap);
1631
1632 return dev;
1633 }
1634
1635 /*
1636 * Create an array of device attach attributes and add it
1637 * to the device's dv_properties dictionary.
1638 *
1639 * <key>interface-attributes</key>
1640 * <array>
1641 * <dict>
1642 * <key>attribute-name</key>
1643 * <string>foo</string>
1644 * <key>locators</key>
1645 * <array>
1646 * <dict>
1647 * <key>loc-name</key>
1648 * <string>foo-loc1</string>
1649 * </dict>
1650 * <dict>
1651 * <key>loc-name</key>
1652 * <string>foo-loc2</string>
1653 * <key>default</key>
1654 * <string>foo-loc2-default</string>
1655 * </dict>
1656 * ...
1657 * </array>
1658 * </dict>
1659 * ...
1660 * </array>
1661 */
1662
1663 static void
1664 config_add_attrib_dict(device_t dev)
1665 {
1666 int i, j;
1667 const struct cfiattrdata *ci;
1668 prop_dictionary_t attr_dict, loc_dict;
1669 prop_array_t attr_array, loc_array;
1670
1671 if ((attr_array = prop_array_create()) == NULL)
1672 return;
1673
1674 for (i = 0; ; i++) {
1675 if ((ci = dev->dv_cfdriver->cd_attrs[i]) == NULL)
1676 break;
1677 if ((attr_dict = prop_dictionary_create()) == NULL)
1678 break;
1679 prop_dictionary_set_string_nocopy(attr_dict, "attribute-name",
1680 ci->ci_name);
1681
1682 /* Create an array of the locator names and defaults */
1683
1684 if (ci->ci_loclen != 0 &&
1685 (loc_array = prop_array_create()) != NULL) {
1686 for (j = 0; j < ci->ci_loclen; j++) {
1687 loc_dict = prop_dictionary_create();
1688 if (loc_dict == NULL)
1689 continue;
1690 prop_dictionary_set_string_nocopy(loc_dict,
1691 "loc-name", ci->ci_locdesc[j].cld_name);
1692 if (ci->ci_locdesc[j].cld_defaultstr != NULL)
1693 prop_dictionary_set_string_nocopy(
1694 loc_dict, "default",
1695 ci->ci_locdesc[j].cld_defaultstr);
1696 prop_array_set(loc_array, j, loc_dict);
1697 prop_object_release(loc_dict);
1698 }
1699 prop_dictionary_set_and_rel(attr_dict, "locators",
1700 loc_array);
1701 }
1702 prop_array_add(attr_array, attr_dict);
1703 prop_object_release(attr_dict);
1704 }
1705 if (i == 0)
1706 prop_object_release(attr_array);
1707 else
1708 prop_dictionary_set_and_rel(dev->dv_properties,
1709 "interface-attributes", attr_array);
1710
1711 return;
1712 }
1713
1714 /*
1715 * Attach a found device.
1716 */
1717 device_t
1718 config_vattach(device_t parent, cfdata_t cf, void *aux, cfprint_t print,
1719 cfarg_t tag, va_list ap)
1720 {
1721 device_t dev;
1722 struct cftable *ct;
1723 const char *drvname;
1724
1725 KASSERT(KERNEL_LOCKED_P());
1726
1727 dev = config_vdevalloc(parent, cf, tag, ap);
1728 if (!dev)
1729 panic("config_attach: allocation of device softc failed");
1730
1731 /* XXX redundant - see below? */
1732 if (cf->cf_fstate != FSTATE_STAR) {
1733 KASSERT(cf->cf_fstate == FSTATE_NOTFOUND);
1734 cf->cf_fstate = FSTATE_FOUND;
1735 }
1736
1737 config_devlink(dev);
1738
1739 if (config_do_twiddle && cold)
1740 twiddle();
1741 else
1742 aprint_naive("Found ");
1743 /*
1744 * We want the next two printfs for normal, verbose, and quiet,
1745 * but not silent (in which case, we're twiddling, instead).
1746 */
1747 if (parent == ROOT) {
1748 aprint_naive("%s (root)", device_xname(dev));
1749 aprint_normal("%s (root)", device_xname(dev));
1750 } else {
1751 aprint_naive("%s at %s", device_xname(dev),
1752 device_xname(parent));
1753 aprint_normal("%s at %s", device_xname(dev),
1754 device_xname(parent));
1755 if (print)
1756 (void) (*print)(aux, NULL);
1757 }
1758
1759 /*
1760 * Before attaching, clobber any unfound devices that are
1761 * otherwise identical.
1762 * XXX code above is redundant?
1763 */
1764 drvname = dev->dv_cfdriver->cd_name;
1765 TAILQ_FOREACH(ct, &allcftables, ct_list) {
1766 for (cf = ct->ct_cfdata; cf->cf_name; cf++) {
1767 if (STREQ(cf->cf_name, drvname) &&
1768 cf->cf_unit == dev->dv_unit) {
1769 if (cf->cf_fstate == FSTATE_NOTFOUND)
1770 cf->cf_fstate = FSTATE_FOUND;
1771 }
1772 }
1773 }
1774 device_register(dev, aux);
1775
1776 /* Let userland know */
1777 devmon_report_device(dev, true);
1778
1779 (*dev->dv_cfattach->ca_attach)(parent, dev, aux);
1780
1781 if (((dev->dv_flags & DVF_ATTACH_INPROGRESS) == 0)
1782 && !device_pmf_is_registered(dev))
1783 aprint_debug_dev(dev,
1784 "WARNING: power management not supported\n");
1785
1786 config_process_deferred(&deferred_config_queue, dev);
1787
1788 device_register_post_config(dev, aux);
1789 return dev;
1790 }
1791
1792 device_t
1793 config_attach(device_t parent, cfdata_t cf, void *aux, cfprint_t print,
1794 cfarg_t tag, ...)
1795 {
1796 device_t dev;
1797 va_list ap;
1798
1799 KASSERT(KERNEL_LOCKED_P());
1800
1801 va_start(ap, tag);
1802 dev = config_vattach(parent, cf, aux, print, tag, ap);
1803 va_end(ap);
1804
1805 return dev;
1806 }
1807
1808 /*
1809 * As above, but for pseudo-devices. Pseudo-devices attached in this
1810 * way are silently inserted into the device tree, and their children
1811 * attached.
1812 *
1813 * Note that because pseudo-devices are attached silently, any information
1814 * the attach routine wishes to print should be prefixed with the device
1815 * name by the attach routine.
1816 */
1817 device_t
1818 config_attach_pseudo(cfdata_t cf)
1819 {
1820 device_t dev;
1821
1822 KASSERT(KERNEL_LOCKED_P());
1823
1824 dev = config_devalloc(ROOT, cf, CFARG_EOL);
1825 if (!dev)
1826 return NULL;
1827
1828 /* XXX mark busy in cfdata */
1829
1830 if (cf->cf_fstate != FSTATE_STAR) {
1831 KASSERT(cf->cf_fstate == FSTATE_NOTFOUND);
1832 cf->cf_fstate = FSTATE_FOUND;
1833 }
1834
1835 config_devlink(dev);
1836
1837 #if 0 /* XXXJRT not yet */
1838 device_register(dev, NULL); /* like a root node */
1839 #endif
1840
1841 /* Let userland know */
1842 devmon_report_device(dev, true);
1843
1844 (*dev->dv_cfattach->ca_attach)(ROOT, dev, NULL);
1845
1846 config_process_deferred(&deferred_config_queue, dev);
1847 return dev;
1848 }
1849
1850 /*
1851 * Caller must hold alldevs_lock.
1852 */
1853 static void
1854 config_collect_garbage(struct devicelist *garbage)
1855 {
1856 device_t dv;
1857
1858 KASSERT(!cpu_intr_p());
1859 KASSERT(!cpu_softintr_p());
1860 KASSERT(mutex_owned(&alldevs_lock));
1861
1862 while (alldevs_nwrite == 0 && alldevs_nread == 0 && alldevs_garbage) {
1863 TAILQ_FOREACH(dv, &alldevs, dv_list) {
1864 if (dv->dv_del_gen != 0)
1865 break;
1866 }
1867 if (dv == NULL) {
1868 alldevs_garbage = false;
1869 break;
1870 }
1871 config_devunlink(dv, garbage);
1872 }
1873 KASSERT(mutex_owned(&alldevs_lock));
1874 }
1875
1876 static void
1877 config_dump_garbage(struct devicelist *garbage)
1878 {
1879 device_t dv;
1880
1881 while ((dv = TAILQ_FIRST(garbage)) != NULL) {
1882 TAILQ_REMOVE(garbage, dv, dv_list);
1883 config_devdelete(dv);
1884 }
1885 }
1886
1887 /*
1888 * Detach a device. Optionally forced (e.g. because of hardware
1889 * removal) and quiet. Returns zero if successful, non-zero
1890 * (an error code) otherwise.
1891 *
1892 * Note that this code wants to be run from a process context, so
1893 * that the detach can sleep to allow processes which have a device
1894 * open to run and unwind their stacks.
1895 */
1896 int
1897 config_detach(device_t dev, int flags)
1898 {
1899 struct alldevs_foray af;
1900 struct cftable *ct;
1901 cfdata_t cf;
1902 const struct cfattach *ca;
1903 struct cfdriver *cd;
1904 device_t d __diagused;
1905 int rv = 0;
1906
1907 KASSERT(KERNEL_LOCKED_P());
1908
1909 cf = dev->dv_cfdata;
1910 KASSERTMSG((cf == NULL || cf->cf_fstate == FSTATE_FOUND ||
1911 cf->cf_fstate == FSTATE_STAR),
1912 "config_detach: %s: bad device fstate: %d",
1913 device_xname(dev), cf ? cf->cf_fstate : -1);
1914
1915 cd = dev->dv_cfdriver;
1916 KASSERT(cd != NULL);
1917
1918 ca = dev->dv_cfattach;
1919 KASSERT(ca != NULL);
1920
1921 mutex_enter(&alldevs_lock);
1922 if (dev->dv_del_gen != 0) {
1923 mutex_exit(&alldevs_lock);
1924 #ifdef DIAGNOSTIC
1925 printf("%s: %s is already detached\n", __func__,
1926 device_xname(dev));
1927 #endif /* DIAGNOSTIC */
1928 return ENOENT;
1929 }
1930 alldevs_nwrite++;
1931 mutex_exit(&alldevs_lock);
1932
1933 if (!detachall &&
1934 (flags & (DETACH_SHUTDOWN|DETACH_FORCE)) == DETACH_SHUTDOWN &&
1935 (dev->dv_flags & DVF_DETACH_SHUTDOWN) == 0) {
1936 rv = EOPNOTSUPP;
1937 } else if (ca->ca_detach != NULL) {
1938 rv = (*ca->ca_detach)(dev, flags);
1939 } else
1940 rv = EOPNOTSUPP;
1941
1942 /*
1943 * If it was not possible to detach the device, then we either
1944 * panic() (for the forced but failed case), or return an error.
1945 *
1946 * If it was possible to detach the device, ensure that the
1947 * device is deactivated.
1948 */
1949 if (rv == 0)
1950 dev->dv_flags &= ~DVF_ACTIVE;
1951 else if ((flags & DETACH_FORCE) == 0)
1952 goto out;
1953 else {
1954 panic("config_detach: forced detach of %s failed (%d)",
1955 device_xname(dev), rv);
1956 }
1957
1958 /*
1959 * The device has now been successfully detached.
1960 */
1961
1962 /* Let userland know */
1963 devmon_report_device(dev, false);
1964
1965 #ifdef DIAGNOSTIC
1966 /*
1967 * Sanity: If you're successfully detached, you should have no
1968 * children. (Note that because children must be attached
1969 * after parents, we only need to search the latter part of
1970 * the list.)
1971 */
1972 for (d = TAILQ_NEXT(dev, dv_list); d != NULL;
1973 d = TAILQ_NEXT(d, dv_list)) {
1974 if (d->dv_parent == dev && d->dv_del_gen == 0) {
1975 printf("config_detach: detached device %s"
1976 " has children %s\n", device_xname(dev),
1977 device_xname(d));
1978 panic("config_detach");
1979 }
1980 }
1981 #endif
1982
1983 /* notify the parent that the child is gone */
1984 if (dev->dv_parent) {
1985 device_t p = dev->dv_parent;
1986 if (p->dv_cfattach->ca_childdetached)
1987 (*p->dv_cfattach->ca_childdetached)(p, dev);
1988 }
1989
1990 /*
1991 * Mark cfdata to show that the unit can be reused, if possible.
1992 */
1993 TAILQ_FOREACH(ct, &allcftables, ct_list) {
1994 for (cf = ct->ct_cfdata; cf->cf_name; cf++) {
1995 if (STREQ(cf->cf_name, cd->cd_name)) {
1996 if (cf->cf_fstate == FSTATE_FOUND &&
1997 cf->cf_unit == dev->dv_unit)
1998 cf->cf_fstate = FSTATE_NOTFOUND;
1999 }
2000 }
2001 }
2002
2003 if (dev->dv_cfdata != NULL && (flags & DETACH_QUIET) == 0)
2004 aprint_normal_dev(dev, "detached\n");
2005
2006 out:
2007 config_alldevs_enter(&af);
2008 KASSERT(alldevs_nwrite != 0);
2009 --alldevs_nwrite;
2010 if (rv == 0 && dev->dv_del_gen == 0) {
2011 if (alldevs_nwrite == 0 && alldevs_nread == 0)
2012 config_devunlink(dev, &af.af_garbage);
2013 else {
2014 dev->dv_del_gen = alldevs_gen;
2015 alldevs_garbage = true;
2016 }
2017 }
2018 config_alldevs_exit(&af);
2019
2020 return rv;
2021 }
2022
2023 int
2024 config_detach_children(device_t parent, int flags)
2025 {
2026 device_t dv;
2027 deviter_t di;
2028 int error = 0;
2029
2030 KASSERT(KERNEL_LOCKED_P());
2031
2032 for (dv = deviter_first(&di, DEVITER_F_RW); dv != NULL;
2033 dv = deviter_next(&di)) {
2034 if (device_parent(dv) != parent)
2035 continue;
2036 if ((error = config_detach(dv, flags)) != 0)
2037 break;
2038 }
2039 deviter_release(&di);
2040 return error;
2041 }
2042
2043 device_t
2044 shutdown_first(struct shutdown_state *s)
2045 {
2046 if (!s->initialized) {
2047 deviter_init(&s->di, DEVITER_F_SHUTDOWN|DEVITER_F_LEAVES_FIRST);
2048 s->initialized = true;
2049 }
2050 return shutdown_next(s);
2051 }
2052
2053 device_t
2054 shutdown_next(struct shutdown_state *s)
2055 {
2056 device_t dv;
2057
2058 while ((dv = deviter_next(&s->di)) != NULL && !device_is_active(dv))
2059 ;
2060
2061 if (dv == NULL)
2062 s->initialized = false;
2063
2064 return dv;
2065 }
2066
2067 bool
2068 config_detach_all(int how)
2069 {
2070 static struct shutdown_state s;
2071 device_t curdev;
2072 bool progress = false;
2073 int flags;
2074
2075 KERNEL_LOCK(1, NULL);
2076
2077 if ((how & (RB_NOSYNC|RB_DUMP)) != 0)
2078 goto out;
2079
2080 if ((how & RB_POWERDOWN) == RB_POWERDOWN)
2081 flags = DETACH_SHUTDOWN | DETACH_POWEROFF;
2082 else
2083 flags = DETACH_SHUTDOWN;
2084
2085 for (curdev = shutdown_first(&s); curdev != NULL;
2086 curdev = shutdown_next(&s)) {
2087 aprint_debug(" detaching %s, ", device_xname(curdev));
2088 if (config_detach(curdev, flags) == 0) {
2089 progress = true;
2090 aprint_debug("success.");
2091 } else
2092 aprint_debug("failed.");
2093 }
2094
2095 out: KERNEL_UNLOCK_ONE(NULL);
2096 return progress;
2097 }
2098
2099 static bool
2100 device_is_ancestor_of(device_t ancestor, device_t descendant)
2101 {
2102 device_t dv;
2103
2104 for (dv = descendant; dv != NULL; dv = device_parent(dv)) {
2105 if (device_parent(dv) == ancestor)
2106 return true;
2107 }
2108 return false;
2109 }
2110
2111 int
2112 config_deactivate(device_t dev)
2113 {
2114 deviter_t di;
2115 const struct cfattach *ca;
2116 device_t descendant;
2117 int s, rv = 0, oflags;
2118
2119 for (descendant = deviter_first(&di, DEVITER_F_ROOT_FIRST);
2120 descendant != NULL;
2121 descendant = deviter_next(&di)) {
2122 if (dev != descendant &&
2123 !device_is_ancestor_of(dev, descendant))
2124 continue;
2125
2126 if ((descendant->dv_flags & DVF_ACTIVE) == 0)
2127 continue;
2128
2129 ca = descendant->dv_cfattach;
2130 oflags = descendant->dv_flags;
2131
2132 descendant->dv_flags &= ~DVF_ACTIVE;
2133 if (ca->ca_activate == NULL)
2134 continue;
2135 s = splhigh();
2136 rv = (*ca->ca_activate)(descendant, DVACT_DEACTIVATE);
2137 splx(s);
2138 if (rv != 0)
2139 descendant->dv_flags = oflags;
2140 }
2141 deviter_release(&di);
2142 return rv;
2143 }
2144
2145 /*
2146 * Defer the configuration of the specified device until all
2147 * of its parent's devices have been attached.
2148 */
2149 void
2150 config_defer(device_t dev, void (*func)(device_t))
2151 {
2152 struct deferred_config *dc;
2153
2154 if (dev->dv_parent == NULL)
2155 panic("config_defer: can't defer config of a root device");
2156
2157 dc = kmem_alloc(sizeof(*dc), KM_SLEEP);
2158
2159 config_pending_incr(dev);
2160
2161 mutex_enter(&config_misc_lock);
2162 #ifdef DIAGNOSTIC
2163 struct deferred_config *odc;
2164 TAILQ_FOREACH(odc, &deferred_config_queue, dc_queue) {
2165 if (odc->dc_dev == dev)
2166 panic("config_defer: deferred twice");
2167 }
2168 #endif
2169 dc->dc_dev = dev;
2170 dc->dc_func = func;
2171 TAILQ_INSERT_TAIL(&deferred_config_queue, dc, dc_queue);
2172 mutex_exit(&config_misc_lock);
2173 }
2174
2175 /*
2176 * Defer some autoconfiguration for a device until after interrupts
2177 * are enabled.
2178 */
2179 void
2180 config_interrupts(device_t dev, void (*func)(device_t))
2181 {
2182 struct deferred_config *dc;
2183
2184 /*
2185 * If interrupts are enabled, callback now.
2186 */
2187 if (cold == 0) {
2188 (*func)(dev);
2189 return;
2190 }
2191
2192 dc = kmem_alloc(sizeof(*dc), KM_SLEEP);
2193
2194 config_pending_incr(dev);
2195
2196 mutex_enter(&config_misc_lock);
2197 #ifdef DIAGNOSTIC
2198 struct deferred_config *odc;
2199 TAILQ_FOREACH(odc, &interrupt_config_queue, dc_queue) {
2200 if (odc->dc_dev == dev)
2201 panic("config_interrupts: deferred twice");
2202 }
2203 #endif
2204 dc->dc_dev = dev;
2205 dc->dc_func = func;
2206 TAILQ_INSERT_TAIL(&interrupt_config_queue, dc, dc_queue);
2207 dev->dv_flags |= DVF_ATTACH_INPROGRESS;
2208 mutex_exit(&config_misc_lock);
2209 }
2210
2211 /*
2212 * Defer some autoconfiguration for a device until after root file system
2213 * is mounted (to load firmware etc).
2214 */
2215 void
2216 config_mountroot(device_t dev, void (*func)(device_t))
2217 {
2218 struct deferred_config *dc;
2219
2220 /*
2221 * If root file system is mounted, callback now.
2222 */
2223 if (root_is_mounted) {
2224 (*func)(dev);
2225 return;
2226 }
2227
2228 dc = kmem_alloc(sizeof(*dc), KM_SLEEP);
2229
2230 mutex_enter(&config_misc_lock);
2231 #ifdef DIAGNOSTIC
2232 struct deferred_config *odc;
2233 TAILQ_FOREACH(odc, &mountroot_config_queue, dc_queue) {
2234 if (odc->dc_dev == dev)
2235 panic("%s: deferred twice", __func__);
2236 }
2237 #endif
2238
2239 dc->dc_dev = dev;
2240 dc->dc_func = func;
2241 TAILQ_INSERT_TAIL(&mountroot_config_queue, dc, dc_queue);
2242 mutex_exit(&config_misc_lock);
2243 }
2244
2245 /*
2246 * Process a deferred configuration queue.
2247 */
2248 static void
2249 config_process_deferred(struct deferred_config_head *queue, device_t parent)
2250 {
2251 struct deferred_config *dc;
2252
2253 KASSERT(KERNEL_LOCKED_P());
2254
2255 mutex_enter(&config_misc_lock);
2256 dc = TAILQ_FIRST(queue);
2257 while (dc) {
2258 if (parent == NULL || dc->dc_dev->dv_parent == parent) {
2259 TAILQ_REMOVE(queue, dc, dc_queue);
2260 mutex_exit(&config_misc_lock);
2261
2262 (*dc->dc_func)(dc->dc_dev);
2263 config_pending_decr(dc->dc_dev);
2264 kmem_free(dc, sizeof(*dc));
2265
2266 mutex_enter(&config_misc_lock);
2267 /* Restart, queue might have changed */
2268 dc = TAILQ_FIRST(queue);
2269 } else {
2270 dc = TAILQ_NEXT(dc, dc_queue);
2271 }
2272 }
2273 mutex_exit(&config_misc_lock);
2274 }
2275
2276 /*
2277 * Manipulate the config_pending semaphore.
2278 */
2279 void
2280 config_pending_incr(device_t dev)
2281 {
2282
2283 mutex_enter(&config_misc_lock);
2284 KASSERTMSG(dev->dv_pending < INT_MAX,
2285 "%s: excess config_pending_incr", device_xname(dev));
2286 if (dev->dv_pending++ == 0)
2287 TAILQ_INSERT_TAIL(&config_pending, dev, dv_pending_list);
2288 #ifdef DEBUG_AUTOCONF
2289 printf("%s: %s %d\n", __func__, device_xname(dev), dev->dv_pending);
2290 #endif
2291 mutex_exit(&config_misc_lock);
2292 }
2293
2294 void
2295 config_pending_decr(device_t dev)
2296 {
2297
2298 mutex_enter(&config_misc_lock);
2299 KASSERTMSG(dev->dv_pending > 0,
2300 "%s: excess config_pending_decr", device_xname(dev));
2301 if (--dev->dv_pending == 0)
2302 TAILQ_REMOVE(&config_pending, dev, dv_pending_list);
2303 #ifdef DEBUG_AUTOCONF
2304 printf("%s: %s %d\n", __func__, device_xname(dev), dev->dv_pending);
2305 #endif
2306 if (TAILQ_EMPTY(&config_pending))
2307 cv_broadcast(&config_misc_cv);
2308 mutex_exit(&config_misc_lock);
2309 }
2310
2311 /*
2312 * Register a "finalization" routine. Finalization routines are
2313 * called iteratively once all real devices have been found during
2314 * autoconfiguration, for as long as any one finalizer has done
2315 * any work.
2316 */
2317 int
2318 config_finalize_register(device_t dev, int (*fn)(device_t))
2319 {
2320 struct finalize_hook *f;
2321 int error = 0;
2322
2323 KERNEL_LOCK(1, NULL);
2324
2325 /*
2326 * If finalization has already been done, invoke the
2327 * callback function now.
2328 */
2329 if (config_finalize_done) {
2330 while ((*fn)(dev) != 0)
2331 /* loop */ ;
2332 goto out;
2333 }
2334
2335 /* Ensure this isn't already on the list. */
2336 TAILQ_FOREACH(f, &config_finalize_list, f_list) {
2337 if (f->f_func == fn && f->f_dev == dev) {
2338 error = EEXIST;
2339 goto out;
2340 }
2341 }
2342
2343 f = kmem_alloc(sizeof(*f), KM_SLEEP);
2344 f->f_func = fn;
2345 f->f_dev = dev;
2346 TAILQ_INSERT_TAIL(&config_finalize_list, f, f_list);
2347
2348 /* Success! */
2349 error = 0;
2350
2351 out: KERNEL_UNLOCK_ONE(NULL);
2352 return error;
2353 }
2354
2355 void
2356 config_finalize(void)
2357 {
2358 struct finalize_hook *f;
2359 struct pdevinit *pdev;
2360 extern struct pdevinit pdevinit[];
2361 int errcnt, rv;
2362
2363 /*
2364 * Now that device driver threads have been created, wait for
2365 * them to finish any deferred autoconfiguration.
2366 */
2367 mutex_enter(&config_misc_lock);
2368 while (!TAILQ_EMPTY(&config_pending)) {
2369 device_t dev;
2370 TAILQ_FOREACH(dev, &config_pending, dv_pending_list)
2371 aprint_debug_dev(dev, "holding up boot\n");
2372 cv_wait(&config_misc_cv, &config_misc_lock);
2373 }
2374 mutex_exit(&config_misc_lock);
2375
2376 KERNEL_LOCK(1, NULL);
2377
2378 /* Attach pseudo-devices. */
2379 for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
2380 (*pdev->pdev_attach)(pdev->pdev_count);
2381
2382 /* Run the hooks until none of them does any work. */
2383 do {
2384 rv = 0;
2385 TAILQ_FOREACH(f, &config_finalize_list, f_list)
2386 rv |= (*f->f_func)(f->f_dev);
2387 } while (rv != 0);
2388
2389 config_finalize_done = 1;
2390
2391 /* Now free all the hooks. */
2392 while ((f = TAILQ_FIRST(&config_finalize_list)) != NULL) {
2393 TAILQ_REMOVE(&config_finalize_list, f, f_list);
2394 kmem_free(f, sizeof(*f));
2395 }
2396
2397 KERNEL_UNLOCK_ONE(NULL);
2398
2399 errcnt = aprint_get_error_count();
2400 if ((boothowto & (AB_QUIET|AB_SILENT)) != 0 &&
2401 (boothowto & AB_VERBOSE) == 0) {
2402 mutex_enter(&config_misc_lock);
2403 if (config_do_twiddle) {
2404 config_do_twiddle = 0;
2405 printf_nolog(" done.\n");
2406 }
2407 mutex_exit(&config_misc_lock);
2408 }
2409 if (errcnt != 0) {
2410 printf("WARNING: %d error%s while detecting hardware; "
2411 "check system log.\n", errcnt,
2412 errcnt == 1 ? "" : "s");
2413 }
2414 }
2415
2416 void
2417 config_twiddle_init(void)
2418 {
2419
2420 if ((boothowto & (AB_SILENT|AB_VERBOSE)) == AB_SILENT) {
2421 config_do_twiddle = 1;
2422 }
2423 callout_setfunc(&config_twiddle_ch, config_twiddle_fn, NULL);
2424 }
2425
2426 void
2427 config_twiddle_fn(void *cookie)
2428 {
2429
2430 mutex_enter(&config_misc_lock);
2431 if (config_do_twiddle) {
2432 twiddle();
2433 callout_schedule(&config_twiddle_ch, mstohz(100));
2434 }
2435 mutex_exit(&config_misc_lock);
2436 }
2437
2438 static void
2439 config_alldevs_enter(struct alldevs_foray *af)
2440 {
2441 TAILQ_INIT(&af->af_garbage);
2442 mutex_enter(&alldevs_lock);
2443 config_collect_garbage(&af->af_garbage);
2444 }
2445
2446 static void
2447 config_alldevs_exit(struct alldevs_foray *af)
2448 {
2449 mutex_exit(&alldevs_lock);
2450 config_dump_garbage(&af->af_garbage);
2451 }
2452
2453 /*
2454 * device_lookup:
2455 *
2456 * Look up a device instance for a given driver.
2457 */
2458 device_t
2459 device_lookup(cfdriver_t cd, int unit)
2460 {
2461 device_t dv;
2462
2463 mutex_enter(&alldevs_lock);
2464 if (unit < 0 || unit >= cd->cd_ndevs)
2465 dv = NULL;
2466 else if ((dv = cd->cd_devs[unit]) != NULL && dv->dv_del_gen != 0)
2467 dv = NULL;
2468 mutex_exit(&alldevs_lock);
2469
2470 return dv;
2471 }
2472
2473 /*
2474 * device_lookup_private:
2475 *
2476 * Look up a softc instance for a given driver.
2477 */
2478 void *
2479 device_lookup_private(cfdriver_t cd, int unit)
2480 {
2481
2482 return device_private(device_lookup(cd, unit));
2483 }
2484
2485 /*
2486 * device_find_by_xname:
2487 *
2488 * Returns the device of the given name or NULL if it doesn't exist.
2489 */
2490 device_t
2491 device_find_by_xname(const char *name)
2492 {
2493 device_t dv;
2494 deviter_t di;
2495
2496 for (dv = deviter_first(&di, 0); dv != NULL; dv = deviter_next(&di)) {
2497 if (strcmp(device_xname(dv), name) == 0)
2498 break;
2499 }
2500 deviter_release(&di);
2501
2502 return dv;
2503 }
2504
2505 /*
2506 * device_find_by_driver_unit:
2507 *
2508 * Returns the device of the given driver name and unit or
2509 * NULL if it doesn't exist.
2510 */
2511 device_t
2512 device_find_by_driver_unit(const char *name, int unit)
2513 {
2514 struct cfdriver *cd;
2515
2516 if ((cd = config_cfdriver_lookup(name)) == NULL)
2517 return NULL;
2518 return device_lookup(cd, unit);
2519 }
2520
2521 static bool
2522 match_strcmp(const char * const s1, const char * const s2)
2523 {
2524 return strcmp(s1, s2) == 0;
2525 }
2526
2527 static bool
2528 match_pmatch(const char * const s1, const char * const s2)
2529 {
2530 return pmatch(s1, s2, NULL) == 2;
2531 }
2532
2533 static bool
2534 strarray_match_internal(const char ** const strings,
2535 unsigned int const nstrings, const char * const str,
2536 unsigned int * const indexp,
2537 bool (*match_fn)(const char *, const char *))
2538 {
2539 unsigned int i;
2540
2541 if (strings == NULL || nstrings == 0) {
2542 return false;
2543 }
2544
2545 for (i = 0; i < nstrings; i++) {
2546 if ((*match_fn)(strings[i], str)) {
2547 *indexp = i;
2548 return true;
2549 }
2550 }
2551
2552 return false;
2553 }
2554
2555 static int
2556 strarray_match(const char ** const strings, unsigned int const nstrings,
2557 const char * const str)
2558 {
2559 unsigned int idx;
2560
2561 if (strarray_match_internal(strings, nstrings, str, &idx,
2562 match_strcmp)) {
2563 return (int)(nstrings - idx);
2564 }
2565 return 0;
2566 }
2567
2568 static int
2569 strarray_pmatch(const char ** const strings, unsigned int const nstrings,
2570 const char * const pattern)
2571 {
2572 unsigned int idx;
2573
2574 if (strarray_match_internal(strings, nstrings, pattern, &idx,
2575 match_pmatch)) {
2576 return (int)(nstrings - idx);
2577 }
2578 return 0;
2579 }
2580
2581 static int
2582 device_compatible_match_strarray_internal(
2583 const char **device_compats, int ndevice_compats,
2584 const struct device_compatible_entry *driver_compats,
2585 const struct device_compatible_entry **matching_entryp,
2586 int (*match_fn)(const char **, unsigned int, const char *))
2587 {
2588 const struct device_compatible_entry *dce = NULL;
2589 int rv;
2590
2591 if (ndevice_compats == 0 || device_compats == NULL ||
2592 driver_compats == NULL)
2593 return 0;
2594
2595 for (dce = driver_compats; dce->compat != NULL; dce++) {
2596 rv = (*match_fn)(device_compats, ndevice_compats, dce->compat);
2597 if (rv != 0) {
2598 if (matching_entryp != NULL) {
2599 *matching_entryp = dce;
2600 }
2601 return rv;
2602 }
2603 }
2604 return 0;
2605 }
2606
2607 /*
2608 * device_compatible_match:
2609 *
2610 * Match a driver's "compatible" data against a device's
2611 * "compatible" strings. Returns resulted weighted by
2612 * which device "compatible" string was matched.
2613 */
2614 int
2615 device_compatible_match(const char **device_compats, int ndevice_compats,
2616 const struct device_compatible_entry *driver_compats)
2617 {
2618 return device_compatible_match_strarray_internal(device_compats,
2619 ndevice_compats, driver_compats, NULL, strarray_match);
2620 }
2621
2622 /*
2623 * device_compatible_pmatch:
2624 *
2625 * Like device_compatible_match(), but uses pmatch(9) to compare
2626 * the device "compatible" strings against patterns in the
2627 * driver's "compatible" data.
2628 */
2629 int
2630 device_compatible_pmatch(const char **device_compats, int ndevice_compats,
2631 const struct device_compatible_entry *driver_compats)
2632 {
2633 return device_compatible_match_strarray_internal(device_compats,
2634 ndevice_compats, driver_compats, NULL, strarray_pmatch);
2635 }
2636
2637 static int
2638 device_compatible_match_strlist_internal(
2639 const char * const device_compats, size_t const device_compatsize,
2640 const struct device_compatible_entry *driver_compats,
2641 const struct device_compatible_entry **matching_entryp,
2642 int (*match_fn)(const char *, size_t, const char *))
2643 {
2644 const struct device_compatible_entry *dce = NULL;
2645 int rv;
2646
2647 if (device_compats == NULL || device_compatsize == 0 ||
2648 driver_compats == NULL)
2649 return 0;
2650
2651 for (dce = driver_compats; dce->compat != NULL; dce++) {
2652 rv = (*match_fn)(device_compats, device_compatsize,
2653 dce->compat);
2654 if (rv != 0) {
2655 if (matching_entryp != NULL) {
2656 *matching_entryp = dce;
2657 }
2658 return rv;
2659 }
2660 }
2661 return 0;
2662 }
2663
2664 /*
2665 * device_compatible_match_strlist:
2666 *
2667 * Like device_compatible_match(), but take the device
2668 * "compatible" strings as an OpenFirmware-style string
2669 * list.
2670 */
2671 int
2672 device_compatible_match_strlist(
2673 const char * const device_compats, size_t const device_compatsize,
2674 const struct device_compatible_entry *driver_compats)
2675 {
2676 return device_compatible_match_strlist_internal(device_compats,
2677 device_compatsize, driver_compats, NULL, strlist_match);
2678 }
2679
2680 /*
2681 * device_compatible_pmatch_strlist:
2682 *
2683 * Like device_compatible_pmatch(), but take the device
2684 * "compatible" strings as an OpenFirmware-style string
2685 * list.
2686 */
2687 int
2688 device_compatible_pmatch_strlist(
2689 const char * const device_compats, size_t const device_compatsize,
2690 const struct device_compatible_entry *driver_compats)
2691 {
2692 return device_compatible_match_strlist_internal(device_compats,
2693 device_compatsize, driver_compats, NULL, strlist_pmatch);
2694 }
2695
2696 static int
2697 device_compatible_match_id_internal(
2698 uintptr_t const id, uintptr_t const mask, uintptr_t const sentinel_id,
2699 const struct device_compatible_entry *driver_compats,
2700 const struct device_compatible_entry **matching_entryp)
2701 {
2702 const struct device_compatible_entry *dce = NULL;
2703
2704 if (mask == 0)
2705 return 0;
2706
2707 for (dce = driver_compats; dce->id != sentinel_id; dce++) {
2708 if ((id & mask) == dce->id) {
2709 if (matching_entryp != NULL) {
2710 *matching_entryp = dce;
2711 }
2712 return 1;
2713 }
2714 }
2715 return 0;
2716 }
2717
2718 /*
2719 * device_compatible_match_id:
2720 *
2721 * Like device_compatible_match(), but takes a single
2722 * unsigned integer device ID.
2723 */
2724 int
2725 device_compatible_match_id(
2726 uintptr_t const id, uintptr_t const sentinel_id,
2727 const struct device_compatible_entry *driver_compats)
2728 {
2729 return device_compatible_match_id_internal(id, (uintptr_t)-1,
2730 sentinel_id, driver_compats, NULL);
2731 }
2732
2733 /*
2734 * device_compatible_lookup:
2735 *
2736 * Look up and return the device_compatible_entry, using the
2737 * same matching criteria used by device_compatible_match().
2738 */
2739 const struct device_compatible_entry *
2740 device_compatible_lookup(const char **device_compats, int ndevice_compats,
2741 const struct device_compatible_entry *driver_compats)
2742 {
2743 const struct device_compatible_entry *dce;
2744
2745 if (device_compatible_match_strarray_internal(device_compats,
2746 ndevice_compats, driver_compats, &dce, strarray_match)) {
2747 return dce;
2748 }
2749 return NULL;
2750 }
2751
2752 /*
2753 * device_compatible_plookup:
2754 *
2755 * Look up and return the device_compatible_entry, using the
2756 * same matching criteria used by device_compatible_pmatch().
2757 */
2758 const struct device_compatible_entry *
2759 device_compatible_plookup(const char **device_compats, int ndevice_compats,
2760 const struct device_compatible_entry *driver_compats)
2761 {
2762 const struct device_compatible_entry *dce;
2763
2764 if (device_compatible_match_strarray_internal(device_compats,
2765 ndevice_compats, driver_compats, &dce, strarray_pmatch)) {
2766 return dce;
2767 }
2768 return NULL;
2769 }
2770
2771 /*
2772 * device_compatible_lookup_strlist:
2773 *
2774 * Like device_compatible_lookup(), but take the device
2775 * "compatible" strings as an OpenFirmware-style string
2776 * list.
2777 */
2778 const struct device_compatible_entry *
2779 device_compatible_lookup_strlist(
2780 const char * const device_compats, size_t const device_compatsize,
2781 const struct device_compatible_entry *driver_compats)
2782 {
2783 const struct device_compatible_entry *dce;
2784
2785 if (device_compatible_match_strlist_internal(device_compats,
2786 device_compatsize, driver_compats, &dce, strlist_match)) {
2787 return dce;
2788 }
2789 return NULL;
2790 }
2791
2792 /*
2793 * device_compatible_plookup_strlist:
2794 *
2795 * Like device_compatible_plookup(), but take the device
2796 * "compatible" strings as an OpenFirmware-style string
2797 * list.
2798 */
2799 const struct device_compatible_entry *
2800 device_compatible_plookup_strlist(
2801 const char * const device_compats, size_t const device_compatsize,
2802 const struct device_compatible_entry *driver_compats)
2803 {
2804 const struct device_compatible_entry *dce;
2805
2806 if (device_compatible_match_strlist_internal(device_compats,
2807 device_compatsize, driver_compats, &dce, strlist_pmatch)) {
2808 return dce;
2809 }
2810 return NULL;
2811 }
2812
2813 /*
2814 * device_compatible_lookup_id:
2815 *
2816 * Like device_compatible_lookup(), but takes a single
2817 * unsigned integer device ID.
2818 */
2819 const struct device_compatible_entry *
2820 device_compatible_lookup_id(
2821 uintptr_t const id, uintptr_t const sentinel_id,
2822 const struct device_compatible_entry *driver_compats)
2823 {
2824 const struct device_compatible_entry *dce;
2825
2826 if (device_compatible_match_id_internal(id, (uintptr_t)-1,
2827 sentinel_id, driver_compats, &dce)) {
2828 return dce;
2829 }
2830 return NULL;
2831 }
2832
2833 /*
2834 * Power management related functions.
2835 */
2836
2837 bool
2838 device_pmf_is_registered(device_t dev)
2839 {
2840 return (dev->dv_flags & DVF_POWER_HANDLERS) != 0;
2841 }
2842
2843 bool
2844 device_pmf_driver_suspend(device_t dev, const pmf_qual_t *qual)
2845 {
2846 if ((dev->dv_flags & DVF_DRIVER_SUSPENDED) != 0)
2847 return true;
2848 if ((dev->dv_flags & DVF_CLASS_SUSPENDED) == 0)
2849 return false;
2850 if (pmf_qual_depth(qual) <= DEVACT_LEVEL_DRIVER &&
2851 dev->dv_driver_suspend != NULL &&
2852 !(*dev->dv_driver_suspend)(dev, qual))
2853 return false;
2854
2855 dev->dv_flags |= DVF_DRIVER_SUSPENDED;
2856 return true;
2857 }
2858
2859 bool
2860 device_pmf_driver_resume(device_t dev, const pmf_qual_t *qual)
2861 {
2862 if ((dev->dv_flags & DVF_DRIVER_SUSPENDED) == 0)
2863 return true;
2864 if ((dev->dv_flags & DVF_BUS_SUSPENDED) != 0)
2865 return false;
2866 if (pmf_qual_depth(qual) <= DEVACT_LEVEL_DRIVER &&
2867 dev->dv_driver_resume != NULL &&
2868 !(*dev->dv_driver_resume)(dev, qual))
2869 return false;
2870
2871 dev->dv_flags &= ~DVF_DRIVER_SUSPENDED;
2872 return true;
2873 }
2874
2875 bool
2876 device_pmf_driver_shutdown(device_t dev, int how)
2877 {
2878
2879 if (*dev->dv_driver_shutdown != NULL &&
2880 !(*dev->dv_driver_shutdown)(dev, how))
2881 return false;
2882 return true;
2883 }
2884
2885 bool
2886 device_pmf_driver_register(device_t dev,
2887 bool (*suspend)(device_t, const pmf_qual_t *),
2888 bool (*resume)(device_t, const pmf_qual_t *),
2889 bool (*shutdown)(device_t, int))
2890 {
2891 dev->dv_driver_suspend = suspend;
2892 dev->dv_driver_resume = resume;
2893 dev->dv_driver_shutdown = shutdown;
2894 dev->dv_flags |= DVF_POWER_HANDLERS;
2895 return true;
2896 }
2897
2898 static const char *
2899 curlwp_name(void)
2900 {
2901 if (curlwp->l_name != NULL)
2902 return curlwp->l_name;
2903 else
2904 return curlwp->l_proc->p_comm;
2905 }
2906
2907 void
2908 device_pmf_driver_deregister(device_t dev)
2909 {
2910 device_lock_t dvl = device_getlock(dev);
2911
2912 dev->dv_driver_suspend = NULL;
2913 dev->dv_driver_resume = NULL;
2914
2915 mutex_enter(&dvl->dvl_mtx);
2916 dev->dv_flags &= ~DVF_POWER_HANDLERS;
2917 while (dvl->dvl_nlock > 0 || dvl->dvl_nwait > 0) {
2918 /* Wake a thread that waits for the lock. That
2919 * thread will fail to acquire the lock, and then
2920 * it will wake the next thread that waits for the
2921 * lock, or else it will wake us.
2922 */
2923 cv_signal(&dvl->dvl_cv);
2924 pmflock_debug(dev, __func__, __LINE__);
2925 cv_wait(&dvl->dvl_cv, &dvl->dvl_mtx);
2926 pmflock_debug(dev, __func__, __LINE__);
2927 }
2928 mutex_exit(&dvl->dvl_mtx);
2929 }
2930
2931 bool
2932 device_pmf_driver_child_register(device_t dev)
2933 {
2934 device_t parent = device_parent(dev);
2935
2936 if (parent == NULL || parent->dv_driver_child_register == NULL)
2937 return true;
2938 return (*parent->dv_driver_child_register)(dev);
2939 }
2940
2941 void
2942 device_pmf_driver_set_child_register(device_t dev,
2943 bool (*child_register)(device_t))
2944 {
2945 dev->dv_driver_child_register = child_register;
2946 }
2947
2948 static void
2949 pmflock_debug(device_t dev, const char *func, int line)
2950 {
2951 device_lock_t dvl = device_getlock(dev);
2952
2953 aprint_debug_dev(dev,
2954 "%s.%d, %s dvl_nlock %d dvl_nwait %d dv_flags %x\n", func, line,
2955 curlwp_name(), dvl->dvl_nlock, dvl->dvl_nwait, dev->dv_flags);
2956 }
2957
2958 static bool
2959 device_pmf_lock1(device_t dev)
2960 {
2961 device_lock_t dvl = device_getlock(dev);
2962
2963 while (device_pmf_is_registered(dev) &&
2964 dvl->dvl_nlock > 0 && dvl->dvl_holder != curlwp) {
2965 dvl->dvl_nwait++;
2966 pmflock_debug(dev, __func__, __LINE__);
2967 cv_wait(&dvl->dvl_cv, &dvl->dvl_mtx);
2968 pmflock_debug(dev, __func__, __LINE__);
2969 dvl->dvl_nwait--;
2970 }
2971 if (!device_pmf_is_registered(dev)) {
2972 pmflock_debug(dev, __func__, __LINE__);
2973 /* We could not acquire the lock, but some other thread may
2974 * wait for it, also. Wake that thread.
2975 */
2976 cv_signal(&dvl->dvl_cv);
2977 return false;
2978 }
2979 dvl->dvl_nlock++;
2980 dvl->dvl_holder = curlwp;
2981 pmflock_debug(dev, __func__, __LINE__);
2982 return true;
2983 }
2984
2985 bool
2986 device_pmf_lock(device_t dev)
2987 {
2988 bool rc;
2989 device_lock_t dvl = device_getlock(dev);
2990
2991 mutex_enter(&dvl->dvl_mtx);
2992 rc = device_pmf_lock1(dev);
2993 mutex_exit(&dvl->dvl_mtx);
2994
2995 return rc;
2996 }
2997
2998 void
2999 device_pmf_unlock(device_t dev)
3000 {
3001 device_lock_t dvl = device_getlock(dev);
3002
3003 KASSERT(dvl->dvl_nlock > 0);
3004 mutex_enter(&dvl->dvl_mtx);
3005 if (--dvl->dvl_nlock == 0)
3006 dvl->dvl_holder = NULL;
3007 cv_signal(&dvl->dvl_cv);
3008 pmflock_debug(dev, __func__, __LINE__);
3009 mutex_exit(&dvl->dvl_mtx);
3010 }
3011
3012 device_lock_t
3013 device_getlock(device_t dev)
3014 {
3015 return &dev->dv_lock;
3016 }
3017
3018 void *
3019 device_pmf_bus_private(device_t dev)
3020 {
3021 return dev->dv_bus_private;
3022 }
3023
3024 bool
3025 device_pmf_bus_suspend(device_t dev, const pmf_qual_t *qual)
3026 {
3027 if ((dev->dv_flags & DVF_BUS_SUSPENDED) != 0)
3028 return true;
3029 if ((dev->dv_flags & DVF_CLASS_SUSPENDED) == 0 ||
3030 (dev->dv_flags & DVF_DRIVER_SUSPENDED) == 0)
3031 return false;
3032 if (pmf_qual_depth(qual) <= DEVACT_LEVEL_BUS &&
3033 dev->dv_bus_suspend != NULL &&
3034 !(*dev->dv_bus_suspend)(dev, qual))
3035 return false;
3036
3037 dev->dv_flags |= DVF_BUS_SUSPENDED;
3038 return true;
3039 }
3040
3041 bool
3042 device_pmf_bus_resume(device_t dev, const pmf_qual_t *qual)
3043 {
3044 if ((dev->dv_flags & DVF_BUS_SUSPENDED) == 0)
3045 return true;
3046 if (pmf_qual_depth(qual) <= DEVACT_LEVEL_BUS &&
3047 dev->dv_bus_resume != NULL &&
3048 !(*dev->dv_bus_resume)(dev, qual))
3049 return false;
3050
3051 dev->dv_flags &= ~DVF_BUS_SUSPENDED;
3052 return true;
3053 }
3054
3055 bool
3056 device_pmf_bus_shutdown(device_t dev, int how)
3057 {
3058
3059 if (*dev->dv_bus_shutdown != NULL &&
3060 !(*dev->dv_bus_shutdown)(dev, how))
3061 return false;
3062 return true;
3063 }
3064
3065 void
3066 device_pmf_bus_register(device_t dev, void *priv,
3067 bool (*suspend)(device_t, const pmf_qual_t *),
3068 bool (*resume)(device_t, const pmf_qual_t *),
3069 bool (*shutdown)(device_t, int), void (*deregister)(device_t))
3070 {
3071 dev->dv_bus_private = priv;
3072 dev->dv_bus_resume = resume;
3073 dev->dv_bus_suspend = suspend;
3074 dev->dv_bus_shutdown = shutdown;
3075 dev->dv_bus_deregister = deregister;
3076 }
3077
3078 void
3079 device_pmf_bus_deregister(device_t dev)
3080 {
3081 if (dev->dv_bus_deregister == NULL)
3082 return;
3083 (*dev->dv_bus_deregister)(dev);
3084 dev->dv_bus_private = NULL;
3085 dev->dv_bus_suspend = NULL;
3086 dev->dv_bus_resume = NULL;
3087 dev->dv_bus_deregister = NULL;
3088 }
3089
3090 void *
3091 device_pmf_class_private(device_t dev)
3092 {
3093 return dev->dv_class_private;
3094 }
3095
3096 bool
3097 device_pmf_class_suspend(device_t dev, const pmf_qual_t *qual)
3098 {
3099 if ((dev->dv_flags & DVF_CLASS_SUSPENDED) != 0)
3100 return true;
3101 if (pmf_qual_depth(qual) <= DEVACT_LEVEL_CLASS &&
3102 dev->dv_class_suspend != NULL &&
3103 !(*dev->dv_class_suspend)(dev, qual))
3104 return false;
3105
3106 dev->dv_flags |= DVF_CLASS_SUSPENDED;
3107 return true;
3108 }
3109
3110 bool
3111 device_pmf_class_resume(device_t dev, const pmf_qual_t *qual)
3112 {
3113 if ((dev->dv_flags & DVF_CLASS_SUSPENDED) == 0)
3114 return true;
3115 if ((dev->dv_flags & DVF_BUS_SUSPENDED) != 0 ||
3116 (dev->dv_flags & DVF_DRIVER_SUSPENDED) != 0)
3117 return false;
3118 if (pmf_qual_depth(qual) <= DEVACT_LEVEL_CLASS &&
3119 dev->dv_class_resume != NULL &&
3120 !(*dev->dv_class_resume)(dev, qual))
3121 return false;
3122
3123 dev->dv_flags &= ~DVF_CLASS_SUSPENDED;
3124 return true;
3125 }
3126
3127 void
3128 device_pmf_class_register(device_t dev, void *priv,
3129 bool (*suspend)(device_t, const pmf_qual_t *),
3130 bool (*resume)(device_t, const pmf_qual_t *),
3131 void (*deregister)(device_t))
3132 {
3133 dev->dv_class_private = priv;
3134 dev->dv_class_suspend = suspend;
3135 dev->dv_class_resume = resume;
3136 dev->dv_class_deregister = deregister;
3137 }
3138
3139 void
3140 device_pmf_class_deregister(device_t dev)
3141 {
3142 if (dev->dv_class_deregister == NULL)
3143 return;
3144 (*dev->dv_class_deregister)(dev);
3145 dev->dv_class_private = NULL;
3146 dev->dv_class_suspend = NULL;
3147 dev->dv_class_resume = NULL;
3148 dev->dv_class_deregister = NULL;
3149 }
3150
3151 bool
3152 device_active(device_t dev, devactive_t type)
3153 {
3154 size_t i;
3155
3156 if (dev->dv_activity_count == 0)
3157 return false;
3158
3159 for (i = 0; i < dev->dv_activity_count; ++i) {
3160 if (dev->dv_activity_handlers[i] == NULL)
3161 break;
3162 (*dev->dv_activity_handlers[i])(dev, type);
3163 }
3164
3165 return true;
3166 }
3167
3168 bool
3169 device_active_register(device_t dev, void (*handler)(device_t, devactive_t))
3170 {
3171 void (**new_handlers)(device_t, devactive_t);
3172 void (**old_handlers)(device_t, devactive_t);
3173 size_t i, old_size, new_size;
3174 int s;
3175
3176 old_handlers = dev->dv_activity_handlers;
3177 old_size = dev->dv_activity_count;
3178
3179 KASSERT(old_size == 0 || old_handlers != NULL);
3180
3181 for (i = 0; i < old_size; ++i) {
3182 KASSERT(old_handlers[i] != handler);
3183 if (old_handlers[i] == NULL) {
3184 old_handlers[i] = handler;
3185 return true;
3186 }
3187 }
3188
3189 new_size = old_size + 4;
3190 new_handlers = kmem_alloc(sizeof(void *) * new_size, KM_SLEEP);
3191
3192 for (i = 0; i < old_size; ++i)
3193 new_handlers[i] = old_handlers[i];
3194 new_handlers[old_size] = handler;
3195 for (i = old_size+1; i < new_size; ++i)
3196 new_handlers[i] = NULL;
3197
3198 s = splhigh();
3199 dev->dv_activity_count = new_size;
3200 dev->dv_activity_handlers = new_handlers;
3201 splx(s);
3202
3203 if (old_size > 0)
3204 kmem_free(old_handlers, sizeof(void *) * old_size);
3205
3206 return true;
3207 }
3208
3209 void
3210 device_active_deregister(device_t dev, void (*handler)(device_t, devactive_t))
3211 {
3212 void (**old_handlers)(device_t, devactive_t);
3213 size_t i, old_size;
3214 int s;
3215
3216 old_handlers = dev->dv_activity_handlers;
3217 old_size = dev->dv_activity_count;
3218
3219 for (i = 0; i < old_size; ++i) {
3220 if (old_handlers[i] == handler)
3221 break;
3222 if (old_handlers[i] == NULL)
3223 return; /* XXX panic? */
3224 }
3225
3226 if (i == old_size)
3227 return; /* XXX panic? */
3228
3229 for (; i < old_size - 1; ++i) {
3230 if ((old_handlers[i] = old_handlers[i + 1]) != NULL)
3231 continue;
3232
3233 if (i == 0) {
3234 s = splhigh();
3235 dev->dv_activity_count = 0;
3236 dev->dv_activity_handlers = NULL;
3237 splx(s);
3238 kmem_free(old_handlers, sizeof(void *) * old_size);
3239 }
3240 return;
3241 }
3242 old_handlers[i] = NULL;
3243 }
3244
3245 /* Return true iff the device_t `dev' exists at generation `gen'. */
3246 static bool
3247 device_exists_at(device_t dv, devgen_t gen)
3248 {
3249 return (dv->dv_del_gen == 0 || dv->dv_del_gen > gen) &&
3250 dv->dv_add_gen <= gen;
3251 }
3252
3253 static bool
3254 deviter_visits(const deviter_t *di, device_t dv)
3255 {
3256 return device_exists_at(dv, di->di_gen);
3257 }
3258
3259 /*
3260 * Device Iteration
3261 *
3262 * deviter_t: a device iterator. Holds state for a "walk" visiting
3263 * each device_t's in the device tree.
3264 *
3265 * deviter_init(di, flags): initialize the device iterator `di'
3266 * to "walk" the device tree. deviter_next(di) will return
3267 * the first device_t in the device tree, or NULL if there are
3268 * no devices.
3269 *
3270 * `flags' is one or more of DEVITER_F_RW, indicating that the
3271 * caller intends to modify the device tree by calling
3272 * config_detach(9) on devices in the order that the iterator
3273 * returns them; DEVITER_F_ROOT_FIRST, asking for the devices
3274 * nearest the "root" of the device tree to be returned, first;
3275 * DEVITER_F_LEAVES_FIRST, asking for the devices furthest from
3276 * the root of the device tree, first; and DEVITER_F_SHUTDOWN,
3277 * indicating both that deviter_init() should not respect any
3278 * locks on the device tree, and that deviter_next(di) may run
3279 * in more than one LWP before the walk has finished.
3280 *
3281 * Only one DEVITER_F_RW iterator may be in the device tree at
3282 * once.
3283 *
3284 * DEVITER_F_SHUTDOWN implies DEVITER_F_RW.
3285 *
3286 * Results are undefined if the flags DEVITER_F_ROOT_FIRST and
3287 * DEVITER_F_LEAVES_FIRST are used in combination.
3288 *
3289 * deviter_first(di, flags): initialize the device iterator `di'
3290 * and return the first device_t in the device tree, or NULL
3291 * if there are no devices. The statement
3292 *
3293 * dv = deviter_first(di);
3294 *
3295 * is shorthand for
3296 *
3297 * deviter_init(di);
3298 * dv = deviter_next(di);
3299 *
3300 * deviter_next(di): return the next device_t in the device tree,
3301 * or NULL if there are no more devices. deviter_next(di)
3302 * is undefined if `di' was not initialized with deviter_init() or
3303 * deviter_first().
3304 *
3305 * deviter_release(di): stops iteration (subsequent calls to
3306 * deviter_next() will return NULL), releases any locks and
3307 * resources held by the device iterator.
3308 *
3309 * Device iteration does not return device_t's in any particular
3310 * order. An iterator will never return the same device_t twice.
3311 * Device iteration is guaranteed to complete---i.e., if deviter_next(di)
3312 * is called repeatedly on the same `di', it will eventually return
3313 * NULL. It is ok to attach/detach devices during device iteration.
3314 */
3315 void
3316 deviter_init(deviter_t *di, deviter_flags_t flags)
3317 {
3318 device_t dv;
3319
3320 memset(di, 0, sizeof(*di));
3321
3322 if ((flags & DEVITER_F_SHUTDOWN) != 0)
3323 flags |= DEVITER_F_RW;
3324
3325 mutex_enter(&alldevs_lock);
3326 if ((flags & DEVITER_F_RW) != 0)
3327 alldevs_nwrite++;
3328 else
3329 alldevs_nread++;
3330 di->di_gen = alldevs_gen++;
3331 di->di_flags = flags;
3332
3333 switch (di->di_flags & (DEVITER_F_LEAVES_FIRST|DEVITER_F_ROOT_FIRST)) {
3334 case DEVITER_F_LEAVES_FIRST:
3335 TAILQ_FOREACH(dv, &alldevs, dv_list) {
3336 if (!deviter_visits(di, dv))
3337 continue;
3338 di->di_curdepth = MAX(di->di_curdepth, dv->dv_depth);
3339 }
3340 break;
3341 case DEVITER_F_ROOT_FIRST:
3342 TAILQ_FOREACH(dv, &alldevs, dv_list) {
3343 if (!deviter_visits(di, dv))
3344 continue;
3345 di->di_maxdepth = MAX(di->di_maxdepth, dv->dv_depth);
3346 }
3347 break;
3348 default:
3349 break;
3350 }
3351
3352 deviter_reinit(di);
3353 mutex_exit(&alldevs_lock);
3354 }
3355
3356 static void
3357 deviter_reinit(deviter_t *di)
3358 {
3359
3360 KASSERT(mutex_owned(&alldevs_lock));
3361 if ((di->di_flags & DEVITER_F_RW) != 0)
3362 di->di_prev = TAILQ_LAST(&alldevs, devicelist);
3363 else
3364 di->di_prev = TAILQ_FIRST(&alldevs);
3365 }
3366
3367 device_t
3368 deviter_first(deviter_t *di, deviter_flags_t flags)
3369 {
3370
3371 deviter_init(di, flags);
3372 return deviter_next(di);
3373 }
3374
3375 static device_t
3376 deviter_next2(deviter_t *di)
3377 {
3378 device_t dv;
3379
3380 KASSERT(mutex_owned(&alldevs_lock));
3381
3382 dv = di->di_prev;
3383
3384 if (dv == NULL)
3385 return NULL;
3386
3387 if ((di->di_flags & DEVITER_F_RW) != 0)
3388 di->di_prev = TAILQ_PREV(dv, devicelist, dv_list);
3389 else
3390 di->di_prev = TAILQ_NEXT(dv, dv_list);
3391
3392 return dv;
3393 }
3394
3395 static device_t
3396 deviter_next1(deviter_t *di)
3397 {
3398 device_t dv;
3399
3400 KASSERT(mutex_owned(&alldevs_lock));
3401
3402 do {
3403 dv = deviter_next2(di);
3404 } while (dv != NULL && !deviter_visits(di, dv));
3405
3406 return dv;
3407 }
3408
3409 device_t
3410 deviter_next(deviter_t *di)
3411 {
3412 device_t dv = NULL;
3413
3414 mutex_enter(&alldevs_lock);
3415 switch (di->di_flags & (DEVITER_F_LEAVES_FIRST|DEVITER_F_ROOT_FIRST)) {
3416 case 0:
3417 dv = deviter_next1(di);
3418 break;
3419 case DEVITER_F_LEAVES_FIRST:
3420 while (di->di_curdepth >= 0) {
3421 if ((dv = deviter_next1(di)) == NULL) {
3422 di->di_curdepth--;
3423 deviter_reinit(di);
3424 } else if (dv->dv_depth == di->di_curdepth)
3425 break;
3426 }
3427 break;
3428 case DEVITER_F_ROOT_FIRST:
3429 while (di->di_curdepth <= di->di_maxdepth) {
3430 if ((dv = deviter_next1(di)) == NULL) {
3431 di->di_curdepth++;
3432 deviter_reinit(di);
3433 } else if (dv->dv_depth == di->di_curdepth)
3434 break;
3435 }
3436 break;
3437 default:
3438 break;
3439 }
3440 mutex_exit(&alldevs_lock);
3441
3442 return dv;
3443 }
3444
3445 void
3446 deviter_release(deviter_t *di)
3447 {
3448 bool rw = (di->di_flags & DEVITER_F_RW) != 0;
3449
3450 mutex_enter(&alldevs_lock);
3451 if (rw)
3452 --alldevs_nwrite;
3453 else
3454 --alldevs_nread;
3455 /* XXX wake a garbage-collection thread */
3456 mutex_exit(&alldevs_lock);
3457 }
3458
3459 const char *
3460 cfdata_ifattr(const struct cfdata *cf)
3461 {
3462 return cf->cf_pspec->cfp_iattr;
3463 }
3464
3465 bool
3466 ifattr_match(const char *snull, const char *t)
3467 {
3468 return (snull == NULL) || strcmp(snull, t) == 0;
3469 }
3470
3471 void
3472 null_childdetached(device_t self, device_t child)
3473 {
3474 /* do nothing */
3475 }
3476
3477 static void
3478 sysctl_detach_setup(struct sysctllog **clog)
3479 {
3480
3481 sysctl_createv(clog, 0, NULL, NULL,
3482 CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
3483 CTLTYPE_BOOL, "detachall",
3484 SYSCTL_DESCR("Detach all devices at shutdown"),
3485 NULL, 0, &detachall, 0,
3486 CTL_KERN, CTL_CREATE, CTL_EOL);
3487 }
3488