subr_bus.c revision 54074
1/*-
2 * Copyright (c) 1997,1998 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/kern/subr_bus.c 54074 1999-12-03 09:10:04Z mjacob $
27 */
28
29#include "opt_bus.h"
30
31#include <sys/param.h>
32#include <sys/queue.h>
33#include <sys/malloc.h>
34#include <sys/kernel.h>
35#include <sys/module.h>
36#ifdef DEVICE_SYSCTLS
37#include <sys/sysctl.h>
38#endif
39#include <sys/bus_private.h>
40#include <sys/systm.h>
41#include <machine/bus.h>
42#include <sys/rman.h>
43#include <machine/stdarg.h>	/* for device_printf() */
44
45MALLOC_DEFINE(M_BUS, "bus", "Bus data structures");
46
47#ifdef BUS_DEBUG
48#define PDEBUG(a)	(printf(__FUNCTION__ ":%d: ", __LINE__), printf a, printf("\n"))
49#define DEVICENAME(d)	((d)? device_get_name(d): "no device")
50#define DRIVERNAME(d)	((d)? d->name : "no driver")
51#define DEVCLANAME(d)	((d)? d->name : "no devclass")
52
53/* Produce the indenting, indent*2 spaces plus a '.' ahead of that to
54 * prevent syslog from deleting initial spaces
55 */
56#define indentprintf(p)	do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf("  "); printf p ; } while(0)
57
58static void print_method_list(device_method_t *m, int indent);
59static void print_device_ops(device_ops_t ops, int indent);
60static void print_device_short(device_t dev, int indent);
61static void print_device(device_t dev, int indent);
62void print_device_tree_short(device_t dev, int indent);
63void print_device_tree(device_t dev, int indent);
64static void print_driver_short(driver_t *driver, int indent);
65static void print_driver(driver_t *driver, int indent);
66static void print_driver_list(driver_list_t drivers, int indent);
67static void print_devclass_short(devclass_t dc, int indent);
68static void print_devclass(devclass_t dc, int indent);
69void print_devclass_list_short(void);
70void print_devclass_list(void);
71
72#else
73/* Make the compiler ignore the function calls */
74#define PDEBUG(a)			/* nop */
75#define DEVICENAME(d)			/* nop */
76#define DRIVERNAME(d)			/* nop */
77#define DEVCLANAME(d)			/* nop */
78
79#define print_method_list(m,i)		/* nop */
80#define print_device_ops(o,i)		/* nop */
81#define print_device_short(d,i)		/* nop */
82#define print_device(d,i)		/* nop */
83#define print_device_tree_short(d,i)	/* nop */
84#define print_device_tree(d,i)		/* nop */
85#define print_driver_short(d,i)		/* nop */
86#define print_driver(d,i)		/* nop */
87#define print_driver_list(d,i)		/* nop */
88#define print_devclass_short(d,i)	/* nop */
89#define print_devclass(d,i)		/* nop */
90#define print_devclass_list_short()	/* nop */
91#define print_devclass_list()		/* nop */
92#endif
93
94#ifdef DEVICE_SYSCTLS
95static void device_register_oids(device_t dev);
96static void device_unregister_oids(device_t dev);
97#endif
98
99/*
100 * Method table handling
101 */
102static int error_method(void);
103static int next_method_offset = 1;
104
105LIST_HEAD(methodlist, method) methods;
106struct method {
107    LIST_ENTRY(method) link;	/* linked list of methods */
108    int offset;			/* offset in method table */
109    int refs;			/* count of device_op_desc users */
110    devop_t deflt;		/* default implementation */
111    char* name;			/* unique name of method */
112};
113
114static void
115register_method(struct device_op_desc *desc)
116{
117    struct method* m;
118
119    if (desc->method) {
120	desc->method->refs++;
121	return;
122    }
123
124    /*
125     * Make sure that desc->deflt is always valid to simplify dispatch.
126     */
127    if (!desc->deflt)
128	desc->deflt = error_method;
129
130    for (m = LIST_FIRST(&methods); m; m = LIST_NEXT(m, link)) {
131	if (!strcmp(m->name, desc->name)) {
132	    desc->offset = m->offset;
133	    desc->method = m;
134	    m->refs++;
135	    PDEBUG(("method %p has the same name, %s, with offset %d",
136		    (void *)m, desc->name, desc->offset));
137	    return;
138	}
139    }
140
141    m = (struct method *) malloc(sizeof(struct method)
142				 + strlen(desc->name) + 1,
143				 M_BUS, M_NOWAIT);
144    if (!m)
145	    panic("register_method: out of memory");
146    bzero(m, sizeof(struct method) + strlen(desc->name) + 1);
147    m->offset = next_method_offset++;
148    m->refs = 1;
149    m->deflt = desc->deflt;
150    m->name = (char*) (m + 1);
151    strcpy(m->name, desc->name);
152    LIST_INSERT_HEAD(&methods, m, link);
153
154    desc->offset = m->offset;
155    desc->method = m;
156}
157
158static void
159unregister_method(struct device_op_desc *desc)
160{
161    struct method *m = desc->method;
162    m->refs--;
163    if (m->refs == 0) {
164	PDEBUG(("method %s, reached refcount 0", desc->name));
165	LIST_REMOVE(m, link);
166	free(m, M_BUS);
167    	desc->method = 0;
168    }
169}
170
171static int error_method(void)
172{
173    return ENXIO;
174}
175
176static struct device_ops null_ops = {
177    1,
178    { error_method }
179};
180
181static void
182compile_methods(driver_t *driver)
183{
184    device_ops_t ops;
185    struct device_method *m;
186    struct method *cm;
187    int i;
188
189    /*
190     * First register any methods which need it.
191     */
192    for (i = 0, m = driver->methods; m->desc; i++, m++)
193	register_method(m->desc);
194
195    /*
196     * Then allocate the compiled op table.
197     */
198    ops = malloc(sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t),
199		 M_BUS, M_NOWAIT);
200    if (!ops)
201	panic("compile_methods: out of memory");
202    bzero(ops, sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t));
203
204    ops->maxoffset = next_method_offset;
205    /* Fill in default methods and then overwrite with driver methods */
206    for (i = 0; i < next_method_offset; i++)
207	ops->methods[i] = error_method;
208    for (cm = LIST_FIRST(&methods); cm; cm = LIST_NEXT(cm, link)) {
209	if (cm->deflt)
210	    ops->methods[cm->offset] = cm->deflt;
211    }
212    for (i = 0, m = driver->methods; m->desc; i++, m++)
213	ops->methods[m->desc->offset] = m->func;
214    PDEBUG(("%s has %d method%s, wasting %d bytes",
215    		DRIVERNAME(driver), i, (i==1?"":"s"),
216		(next_method_offset-i)*sizeof(devop_t)));
217
218    driver->ops = ops;
219}
220
221static void
222free_methods(driver_t *driver)
223{
224    int i;
225    struct device_method *m;
226
227    /*
228     * Unregister any methods which are no longer used.
229     */
230    for (i = 0, m = driver->methods; m->desc; i++, m++)
231	unregister_method(m->desc);
232
233    /*
234     * Free memory and clean up.
235     */
236    free(driver->ops, M_BUS);
237    driver->ops = 0;
238}
239
240/*
241 * Devclass implementation
242 */
243
244static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
245
246static devclass_t
247devclass_find_internal(const char *classname, int create)
248{
249    devclass_t dc;
250
251    PDEBUG(("looking for %s", classname));
252    if (!classname)
253	return NULL;
254
255    for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link))
256	if (!strcmp(dc->name, classname))
257	    return dc;
258
259    PDEBUG(("%s not found%s", classname, (create? ", creating": "")));
260    if (create) {
261	dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,
262		    M_BUS, M_NOWAIT);
263	if (!dc)
264	    return NULL;
265	bzero(dc, sizeof(struct devclass) + strlen(classname) + 1);
266	dc->name = (char*) (dc + 1);
267	strcpy(dc->name, classname);
268	dc->devices = NULL;
269	dc->maxunit = 0;
270	dc->nextunit = 0;
271	TAILQ_INIT(&dc->drivers);
272	TAILQ_INSERT_TAIL(&devclasses, dc, link);
273    }
274
275    return dc;
276}
277
278devclass_t
279devclass_create(const char *classname)
280{
281    return devclass_find_internal(classname, TRUE);
282}
283
284devclass_t
285devclass_find(const char *classname)
286{
287    return devclass_find_internal(classname, FALSE);
288}
289
290int
291devclass_add_driver(devclass_t dc, driver_t *driver)
292{
293    driverlink_t dl;
294    int i;
295
296    PDEBUG(("%s", DRIVERNAME(driver)));
297
298    dl = malloc(sizeof *dl, M_BUS, M_NOWAIT);
299    if (!dl)
300	return ENOMEM;
301    bzero(dl, sizeof *dl);
302
303    /*
304     * Compile the driver's methods.
305     */
306    if (!driver->ops)
307	compile_methods(driver);
308
309    /*
310     * Make sure the devclass which the driver is implementing exists.
311     */
312    devclass_find_internal(driver->name, TRUE);
313
314    dl->driver = driver;
315    TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
316    driver->refs++;
317
318    /*
319     * Call BUS_DRIVER_ADDED for any existing busses in this class.
320     */
321    for (i = 0; i < dc->maxunit; i++)
322	if (dc->devices[i])
323	    BUS_DRIVER_ADDED(dc->devices[i], driver);
324
325    return 0;
326}
327
328int
329devclass_delete_driver(devclass_t busclass, driver_t *driver)
330{
331    devclass_t dc = devclass_find(driver->name);
332    driverlink_t dl;
333    device_t dev;
334    int i;
335    int error;
336
337    PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
338
339    if (!dc)
340	return 0;
341
342    /*
343     * Find the link structure in the bus' list of drivers.
344     */
345    for (dl = TAILQ_FIRST(&busclass->drivers); dl;
346	 dl = TAILQ_NEXT(dl, link)) {
347	if (dl->driver == driver)
348	    break;
349    }
350
351    if (!dl) {
352	PDEBUG(("%s not found in %s list", driver->name, busclass->name));
353	return ENOENT;
354    }
355
356    /*
357     * Disassociate from any devices.  We iterate through all the
358     * devices in the devclass of the driver and detach any which are
359     * using the driver and which have a parent in the devclass which
360     * we are deleting from.
361     *
362     * Note that since a driver can be in multiple devclasses, we
363     * should not detach devices which are not children of devices in
364     * the affected devclass.
365     */
366    for (i = 0; i < dc->maxunit; i++) {
367	if (dc->devices[i]) {
368	    dev = dc->devices[i];
369	    if (dev->driver == driver
370		&& dev->parent && dev->parent->devclass == busclass) {
371		if ((error = device_detach(dev)) != 0)
372		    return error;
373		device_set_driver(dev, NULL);
374	    }
375	}
376    }
377
378    TAILQ_REMOVE(&busclass->drivers, dl, link);
379    free(dl, M_BUS);
380
381    driver->refs--;
382    if (driver->refs == 0)
383	free_methods(driver);
384
385    return 0;
386}
387
388static driverlink_t
389devclass_find_driver_internal(devclass_t dc, const char *classname)
390{
391    driverlink_t dl;
392
393    PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc)));
394
395    for (dl = TAILQ_FIRST(&dc->drivers); dl; dl = TAILQ_NEXT(dl, link)) {
396	if (!strcmp(dl->driver->name, classname))
397	    return dl;
398    }
399
400    PDEBUG(("not found"));
401    return NULL;
402}
403
404driver_t *
405devclass_find_driver(devclass_t dc, const char *classname)
406{
407    driverlink_t dl;
408
409    dl = devclass_find_driver_internal(dc, classname);
410    if (dl)
411	return dl->driver;
412    else
413	return NULL;
414}
415
416const char *
417devclass_get_name(devclass_t dc)
418{
419    return dc->name;
420}
421
422device_t
423devclass_get_device(devclass_t dc, int unit)
424{
425    if (dc == NULL || unit < 0 || unit >= dc->maxunit)
426	return NULL;
427    return dc->devices[unit];
428}
429
430void *
431devclass_get_softc(devclass_t dc, int unit)
432{
433    device_t dev;
434
435    dev = devclass_get_device(dc, unit);
436    if (!dev)
437	return (NULL);
438
439    return (device_get_softc(dev));
440}
441
442int
443devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp)
444{
445    int i;
446    int count;
447    device_t *list;
448
449    count = 0;
450    for (i = 0; i < dc->maxunit; i++)
451	if (dc->devices[i])
452	    count++;
453
454    list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
455    if (!list)
456	return ENOMEM;
457    bzero(list, count * sizeof(device_t));
458
459    count = 0;
460    for (i = 0; i < dc->maxunit; i++)
461	if (dc->devices[i]) {
462	    list[count] = dc->devices[i];
463	    count++;
464	}
465
466    *devlistp = list;
467    *devcountp = count;
468
469    return 0;
470}
471
472int
473devclass_get_maxunit(devclass_t dc)
474{
475    return dc->maxunit;
476}
477
478static int
479devclass_alloc_unit(devclass_t dc, int *unitp)
480{
481    int unit = *unitp;
482
483    PDEBUG(("unit %d in devclass %s", unit, DEVCLANAME(dc)));
484
485    /*
486     * If we have been given a wired unit number, check for existing
487     * device.
488     */
489    if (unit != -1) {
490	device_t dev;
491	dev = devclass_get_device(dc, unit);
492	if (dev) {
493	    printf("devclass_alloc_unit: %s%d already exists, using next available unit number\n", dc->name, unit);
494	    unit = -1;
495	}
496    }
497
498    if (unit == -1) {
499	unit = dc->nextunit;
500	dc->nextunit++;
501    } else if (dc->nextunit <= unit)
502	dc->nextunit = unit + 1;
503
504    if (unit >= dc->maxunit) {
505	device_t *newlist;
506	int newsize;
507
508	newsize = (dc->maxunit ? 2 * dc->maxunit
509		   : MINALLOCSIZE / sizeof(device_t));
510	newlist = malloc(sizeof(device_t) * newsize, M_BUS, M_NOWAIT);
511	if (!newlist)
512	    return ENOMEM;
513	bcopy(dc->devices, newlist, sizeof(device_t) * dc->maxunit);
514	bzero(newlist + dc->maxunit,
515	      sizeof(device_t) * (newsize - dc->maxunit));
516	if (dc->devices)
517	    free(dc->devices, M_BUS);
518	dc->devices = newlist;
519	dc->maxunit = newsize;
520    }
521    PDEBUG(("now: unit %d in devclass %s", unit, DEVCLANAME(dc)));
522
523    *unitp = unit;
524    return 0;
525}
526
527static int
528devclass_add_device(devclass_t dc, device_t dev)
529{
530    int buflen, error;
531
532    PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
533
534    buflen = strlen(dc->name) + 5;
535    dev->nameunit = malloc(buflen, M_BUS, M_NOWAIT);
536    if (!dev->nameunit)
537	return ENOMEM;
538    bzero(dev->nameunit, buflen);
539
540    if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) {
541	free(dev->nameunit, M_BUS);
542	dev->nameunit = NULL;
543	return error;
544    }
545    dc->devices[dev->unit] = dev;
546    dev->devclass = dc;
547    snprintf(dev->nameunit, buflen, "%s%d", dc->name, dev->unit);
548
549#ifdef DEVICE_SYSCTLS
550    device_register_oids(dev);
551#endif
552
553    return 0;
554}
555
556static int
557devclass_delete_device(devclass_t dc, device_t dev)
558{
559    if (!dc || !dev)
560	return 0;
561
562    PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
563
564    if (dev->devclass != dc
565	|| dc->devices[dev->unit] != dev)
566	panic("devclass_delete_device: inconsistent device class");
567    dc->devices[dev->unit] = NULL;
568    if (dev->flags & DF_WILDCARD)
569	dev->unit = -1;
570    dev->devclass = NULL;
571    free(dev->nameunit, M_BUS);
572    dev->nameunit = NULL;
573    while (dc->nextunit > 0 && dc->devices[dc->nextunit - 1] == NULL)
574	dc->nextunit--;
575
576#ifdef DEVICE_SYSCTLS
577    device_unregister_oids(dev);
578#endif
579
580    return 0;
581}
582
583static device_t
584make_device(device_t parent, const char *name, int unit)
585{
586    device_t dev;
587    devclass_t dc;
588
589    PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
590
591    if (name) {
592	dc = devclass_find_internal(name, TRUE);
593	if (!dc) {
594	    printf("make_device: can't find device class %s\n", name);
595	    return NULL;
596	}
597    } else
598	dc = NULL;
599
600    dev = malloc(sizeof(struct device), M_BUS, M_NOWAIT);
601    if (!dev)
602	return 0;
603    bzero(dev, sizeof(struct device));
604
605    dev->parent = parent;
606    TAILQ_INIT(&dev->children);
607    dev->ops = &null_ops;
608    dev->driver = NULL;
609    dev->devclass = NULL;
610    dev->unit = unit;
611    dev->nameunit = NULL;
612    dev->desc = NULL;
613    dev->busy = 0;
614    dev->devflags = 0;
615    dev->flags = DF_ENABLED;
616    dev->order = 0;
617    if (unit == -1)
618	dev->flags |= DF_WILDCARD;
619    if (name) {
620	dev->flags |= DF_FIXEDCLASS;
621	devclass_add_device(dc, dev);
622    }
623    dev->ivars = NULL;
624    dev->softc = NULL;
625
626    dev->state = DS_NOTPRESENT;
627
628    return dev;
629}
630
631static int
632device_print_child(device_t dev, device_t child)
633{
634    int retval = 0;
635
636    if (device_is_alive(child)) {
637	retval += BUS_PRINT_CHILD(dev, child);
638    } else
639	retval += device_printf(child, " not found\n");
640
641    return (retval);
642}
643
644device_t
645device_add_child(device_t dev, const char *name, int unit)
646{
647    return device_add_child_ordered(dev, 0, name, unit);
648}
649
650device_t
651device_add_child_ordered(device_t dev, int order, const char *name, int unit)
652{
653    device_t child;
654    device_t place;
655
656    PDEBUG(("%s at %s with order %d as unit %d",
657	    name, DEVICENAME(dev), order, unit));
658
659    child = make_device(dev, name, unit);
660    if (child == NULL)
661	return child;
662    child->order = order;
663
664    TAILQ_FOREACH(place, &dev->children, link)
665	if (place->order > order)
666	    break;
667
668    if (place) {
669	/*
670	 * The device 'place' is the first device whose order is
671	 * greater than the new child.
672	 */
673	TAILQ_INSERT_BEFORE(place, child, link);
674    } else {
675	/*
676	 * The new child's order is greater or equal to the order of
677	 * any existing device. Add the child to the tail of the list.
678	 */
679	TAILQ_INSERT_TAIL(&dev->children, child, link);
680    }
681
682    return child;
683}
684
685int
686device_delete_child(device_t dev, device_t child)
687{
688    int error;
689    device_t grandchild;
690
691    PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
692
693    /* remove children first */
694    while ( (grandchild = TAILQ_FIRST(&child->children)) ) {
695        error = device_delete_child(child, grandchild);
696	if (error)
697	    return error;
698    }
699
700    if ((error = device_detach(child)) != 0)
701	return error;
702    if (child->devclass)
703	devclass_delete_device(child->devclass, child);
704    TAILQ_REMOVE(&dev->children, child, link);
705    device_set_desc(child, NULL);
706    free(child, M_BUS);
707
708    return 0;
709}
710
711/*
712 * Find only devices attached to this bus.
713 */
714device_t
715device_find_child(device_t dev, const char *classname, int unit)
716{
717    devclass_t dc;
718    device_t child;
719
720    dc = devclass_find(classname);
721    if (!dc)
722	return NULL;
723
724    child = devclass_get_device(dc, unit);
725    if (child && child->parent == dev)
726	return child;
727    return NULL;
728}
729
730static driverlink_t
731first_matching_driver(devclass_t dc, device_t dev)
732{
733    if (dev->devclass)
734	return devclass_find_driver_internal(dc, dev->devclass->name);
735    else
736	return TAILQ_FIRST(&dc->drivers);
737}
738
739static driverlink_t
740next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
741{
742    if (dev->devclass) {
743	driverlink_t dl;
744	for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link))
745	    if (!strcmp(dev->devclass->name, dl->driver->name))
746		return dl;
747	return NULL;
748    } else
749	return TAILQ_NEXT(last, link);
750}
751
752static int
753device_probe_child(device_t dev, device_t child)
754{
755    devclass_t dc;
756    driverlink_t best = 0;
757    driverlink_t dl;
758    int result, pri = 0;
759
760    dc = dev->devclass;
761    if (dc == NULL)
762	panic("device_probe_child: parent device has no devclass");
763
764    if (child->state == DS_ALIVE)
765	return 0;
766
767    for (dl = first_matching_driver(dc, child);
768	 dl;
769	 dl = next_matching_driver(dc, child, dl)) {
770	PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
771	device_set_driver(child, dl->driver);
772	result = DEVICE_PROBE(child);
773
774	/*
775	 * If the driver returns SUCCESS, there can be no higher match
776	 * for this device.
777	 */
778	if (result == 0) {
779	    best = dl;
780	    pri = 0;
781	    break;
782	}
783
784	/*
785	 * The driver returned an error so it certainly doesn't match.
786	 */
787	if (result > 0)
788	    continue;
789
790	/*
791	 * A priority lower than SUCCESS, remember the best matching
792	 * driver. Initialise the value of pri for the first match.
793	 */
794	if (best == 0 || result > pri) {
795	    best = dl;
796	    pri = result;
797	    continue;
798	}
799    }
800
801    /*
802     * If we found a driver, change state and initialise the devclass.
803     */
804    if (best) {
805	if (!child->devclass)
806	    device_set_devclass(child, best->driver->name);
807	device_set_driver(child, best->driver);
808	if (pri < 0) {
809	    /*
810	     * A bit bogus. Call the probe method again to make sure
811	     * that we have the right description.
812	     */
813	    DEVICE_PROBE(child);
814	}
815	child->state = DS_ALIVE;
816	return 0;
817    }
818
819    return ENXIO;
820}
821
822device_t
823device_get_parent(device_t dev)
824{
825    return dev->parent;
826}
827
828int
829device_get_children(device_t dev, device_t **devlistp, int *devcountp)
830{
831    int count;
832    device_t child;
833    device_t *list;
834
835    count = 0;
836    for (child = TAILQ_FIRST(&dev->children); child;
837	 child = TAILQ_NEXT(child, link))
838	count++;
839
840    list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
841    if (!list)
842	return ENOMEM;
843    bzero(list, count * sizeof(device_t));
844
845    count = 0;
846    for (child = TAILQ_FIRST(&dev->children); child;
847	 child = TAILQ_NEXT(child, link)) {
848	list[count] = child;
849	count++;
850    }
851
852    *devlistp = list;
853    *devcountp = count;
854
855    return 0;
856}
857
858driver_t *
859device_get_driver(device_t dev)
860{
861    return dev->driver;
862}
863
864devclass_t
865device_get_devclass(device_t dev)
866{
867    return dev->devclass;
868}
869
870const char *
871device_get_name(device_t dev)
872{
873    if (dev->devclass)
874	return devclass_get_name(dev->devclass);
875    return NULL;
876}
877
878const char *
879device_get_nameunit(device_t dev)
880{
881    return dev->nameunit;
882}
883
884int
885device_get_unit(device_t dev)
886{
887    return dev->unit;
888}
889
890const char *
891device_get_desc(device_t dev)
892{
893    return dev->desc;
894}
895
896u_int32_t
897device_get_flags(device_t dev)
898{
899    return dev->devflags;
900}
901
902int
903device_print_prettyname(device_t dev)
904{
905    const char *name = device_get_name(dev);
906
907    if (name == 0)
908	return printf("unknown: ");
909    else
910	return printf("%s%d: ", name, device_get_unit(dev));
911}
912
913int
914device_printf(device_t dev, const char * fmt, ...)
915{
916    va_list ap;
917    int retval;
918
919    retval = device_print_prettyname(dev);
920    va_start(ap, fmt);
921    retval += vprintf(fmt, ap);
922    va_end(ap);
923    return retval;
924}
925
926static void
927device_set_desc_internal(device_t dev, const char* desc, int copy)
928{
929    if (dev->desc && (dev->flags & DF_DESCMALLOCED)) {
930	free(dev->desc, M_BUS);
931	dev->flags &= ~DF_DESCMALLOCED;
932	dev->desc = NULL;
933    }
934
935    if (copy && desc) {
936	dev->desc = malloc(strlen(desc) + 1, M_BUS, M_NOWAIT);
937	if (dev->desc) {
938	    strcpy(dev->desc, desc);
939	    dev->flags |= DF_DESCMALLOCED;
940	}
941    } else
942	/* Avoid a -Wcast-qual warning */
943	dev->desc = (char *)(uintptr_t) desc;
944
945#ifdef DEVICE_SYSCTLS
946    {
947	struct sysctl_oid *oid = &dev->oid[1];
948	oid->oid_arg1 = dev->desc ? dev->desc : "";
949	oid->oid_arg2 = dev->desc ? strlen(dev->desc) : 0;
950    }
951#endif
952}
953
954void
955device_set_desc(device_t dev, const char* desc)
956{
957    device_set_desc_internal(dev, desc, FALSE);
958}
959
960void
961device_set_desc_copy(device_t dev, const char* desc)
962{
963    device_set_desc_internal(dev, desc, TRUE);
964}
965
966void
967device_set_flags(device_t dev, u_int32_t flags)
968{
969    dev->devflags = flags;
970}
971
972void *
973device_get_softc(device_t dev)
974{
975    return dev->softc;
976}
977
978void *
979device_get_ivars(device_t dev)
980{
981    return dev->ivars;
982}
983
984void
985device_set_ivars(device_t dev, void * ivars)
986{
987    if (!dev)
988	return;
989
990    dev->ivars = ivars;
991
992    return;
993}
994
995device_state_t
996device_get_state(device_t dev)
997{
998    return dev->state;
999}
1000
1001void
1002device_enable(device_t dev)
1003{
1004    dev->flags |= DF_ENABLED;
1005}
1006
1007void
1008device_disable(device_t dev)
1009{
1010    dev->flags &= ~DF_ENABLED;
1011}
1012
1013void
1014device_busy(device_t dev)
1015{
1016    if (dev->state < DS_ATTACHED)
1017	panic("device_busy: called for unattached device");
1018    if (dev->busy == 0 && dev->parent)
1019	device_busy(dev->parent);
1020    dev->busy++;
1021    dev->state = DS_BUSY;
1022}
1023
1024void
1025device_unbusy(device_t dev)
1026{
1027    if (dev->state != DS_BUSY)
1028	panic("device_unbusy: called for non-busy device");
1029    dev->busy--;
1030    if (dev->busy == 0) {
1031	if (dev->parent)
1032	    device_unbusy(dev->parent);
1033	dev->state = DS_ATTACHED;
1034    }
1035}
1036
1037void
1038device_quiet(device_t dev)
1039{
1040    dev->flags |= DF_QUIET;
1041}
1042
1043void
1044device_verbose(device_t dev)
1045{
1046    dev->flags &= ~DF_QUIET;
1047}
1048
1049int
1050device_is_quiet(device_t dev)
1051{
1052    return (dev->flags & DF_QUIET) != 0;
1053}
1054
1055int
1056device_is_enabled(device_t dev)
1057{
1058    return (dev->flags & DF_ENABLED) != 0;
1059}
1060
1061int
1062device_is_alive(device_t dev)
1063{
1064    return dev->state >= DS_ALIVE;
1065}
1066
1067int
1068device_set_devclass(device_t dev, const char *classname)
1069{
1070    devclass_t dc;
1071
1072    if (dev->devclass) {
1073	printf("device_set_devclass: device class already set\n");
1074	return EINVAL;
1075    }
1076
1077    dc = devclass_find_internal(classname, TRUE);
1078    if (!dc)
1079	return ENOMEM;
1080
1081    return devclass_add_device(dc, dev);
1082}
1083
1084int
1085device_set_driver(device_t dev, driver_t *driver)
1086{
1087    if (dev->state >= DS_ATTACHED)
1088	return EBUSY;
1089
1090    if (dev->driver == driver)
1091	return 0;
1092
1093    if (dev->softc) {
1094	free(dev->softc, M_BUS);
1095	dev->softc = NULL;
1096    }
1097    dev->ops = &null_ops;
1098    dev->driver = driver;
1099    if (driver) {
1100	dev->ops = driver->ops;
1101	dev->softc = malloc(driver->softc, M_BUS, M_NOWAIT);
1102	if (!dev->softc) {
1103	    dev->ops = &null_ops;
1104	    dev->driver = NULL;
1105	    return ENOMEM;
1106	}
1107	bzero(dev->softc, driver->softc);
1108    }
1109    return 0;
1110}
1111
1112int
1113device_probe_and_attach(device_t dev)
1114{
1115    device_t bus = dev->parent;
1116    int error = 0;
1117
1118    if (dev->state >= DS_ALIVE)
1119	return 0;
1120
1121    if (dev->flags & DF_ENABLED) {
1122	error = device_probe_child(bus, dev);
1123	if (!error) {
1124	    if (!device_is_quiet(dev))
1125		device_print_child(bus, dev);
1126	    error = DEVICE_ATTACH(dev);
1127	    if (!error)
1128		dev->state = DS_ATTACHED;
1129	    else {
1130		printf("device_probe_and_attach: %s%d attach returned %d\n",
1131		       dev->driver->name, dev->unit, error);
1132		device_set_driver(dev, NULL);
1133		dev->state = DS_NOTPRESENT;
1134	    }
1135	} else {
1136		BUS_PROBE_NOMATCH(bus, dev);
1137	}
1138    } else {
1139	    device_print_prettyname(dev);
1140	    printf("not probed (disabled)\n");
1141    }
1142
1143    return error;
1144}
1145
1146int
1147device_detach(device_t dev)
1148{
1149    int error;
1150
1151    PDEBUG(("%s", DEVICENAME(dev)));
1152    if (dev->state == DS_BUSY)
1153	return EBUSY;
1154    if (dev->state != DS_ATTACHED)
1155	return 0;
1156
1157    if ((error = DEVICE_DETACH(dev)) != 0)
1158	return error;
1159    if (dev->parent)
1160	BUS_CHILD_DETACHED(dev->parent, dev);
1161
1162    if (!(dev->flags & DF_FIXEDCLASS))
1163	devclass_delete_device(dev->devclass, dev);
1164
1165    dev->state = DS_NOTPRESENT;
1166    device_set_driver(dev, NULL);
1167
1168    return 0;
1169}
1170
1171int
1172device_shutdown(device_t dev)
1173{
1174    if (dev->state < DS_ATTACHED)
1175	return 0;
1176    return DEVICE_SHUTDOWN(dev);
1177}
1178
1179#ifdef DEVICE_SYSCTLS
1180
1181/*
1182 * Sysctl nodes for devices.
1183 */
1184
1185SYSCTL_NODE(_hw, OID_AUTO, devices, CTLFLAG_RW, 0, "A list of all devices");
1186
1187static int
1188sysctl_handle_children SYSCTL_HANDLER_ARGS
1189{
1190    device_t dev = arg1;
1191    device_t child;
1192    int first = 1, error = 0;
1193
1194    for (child = TAILQ_FIRST(&dev->children); child;
1195	 child = TAILQ_NEXT(child, link)) {
1196	if (child->nameunit) {
1197	    if (!first) {
1198		error = SYSCTL_OUT(req, ",", 1);
1199		if (error) return error;
1200	    } else {
1201		first = 0;
1202	    }
1203	    error = SYSCTL_OUT(req, child->nameunit, strlen(child->nameunit));
1204	    if (error) return error;
1205	}
1206    }
1207
1208    error = SYSCTL_OUT(req, "", 1);
1209
1210    return error;
1211}
1212
1213static int
1214sysctl_handle_state SYSCTL_HANDLER_ARGS
1215{
1216    device_t dev = arg1;
1217
1218    switch (dev->state) {
1219    case DS_NOTPRESENT:
1220	return SYSCTL_OUT(req, "notpresent", sizeof("notpresent"));
1221    case DS_ALIVE:
1222	return SYSCTL_OUT(req, "alive", sizeof("alive"));
1223    case DS_ATTACHED:
1224	return SYSCTL_OUT(req, "attached", sizeof("attached"));
1225    case DS_BUSY:
1226	return SYSCTL_OUT(req, "busy", sizeof("busy"));
1227    }
1228
1229    return 0;
1230}
1231
1232static void
1233device_register_oids(device_t dev)
1234{
1235    struct sysctl_oid* oid;
1236
1237    oid = &dev->oid[0];
1238    bzero(oid, sizeof(*oid));
1239    oid->oid_parent = &sysctl__hw_devices_children;
1240    oid->oid_number = OID_AUTO;
1241    oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW;
1242    oid->oid_arg1 = &dev->oidlist[0];
1243    oid->oid_arg2 = 0;
1244    oid->oid_name = dev->nameunit;
1245    oid->oid_handler = 0;
1246    oid->oid_fmt = "N";
1247    SLIST_INIT(&dev->oidlist[0]);
1248    sysctl_register_oid(oid);
1249
1250    oid = &dev->oid[1];
1251    bzero(oid, sizeof(*oid));
1252    oid->oid_parent = &dev->oidlist[0];
1253    oid->oid_number = OID_AUTO;
1254    oid->oid_kind = CTLTYPE_STRING | CTLFLAG_RD;
1255    oid->oid_arg1 = dev->desc ? dev->desc : "";
1256    oid->oid_arg2 = dev->desc ? strlen(dev->desc) : 0;
1257    oid->oid_name = "desc";
1258    oid->oid_handler = sysctl_handle_string;
1259    oid->oid_fmt = "A";
1260    sysctl_register_oid(oid);
1261
1262    oid = &dev->oid[2];
1263    bzero(oid, sizeof(*oid));
1264    oid->oid_parent = &dev->oidlist[0];
1265    oid->oid_number = OID_AUTO;
1266    oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
1267    oid->oid_arg1 = dev;
1268    oid->oid_arg2 = 0;
1269    oid->oid_name = "children";
1270    oid->oid_handler = sysctl_handle_children;
1271    oid->oid_fmt = "A";
1272    sysctl_register_oid(oid);
1273
1274    oid = &dev->oid[3];
1275    bzero(oid, sizeof(*oid));
1276    oid->oid_parent = &dev->oidlist[0];
1277    oid->oid_number = OID_AUTO;
1278    oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
1279    oid->oid_arg1 = dev;
1280    oid->oid_arg2 = 0;
1281    oid->oid_name = "state";
1282    oid->oid_handler = sysctl_handle_state;
1283    oid->oid_fmt = "A";
1284    sysctl_register_oid(oid);
1285}
1286
1287static void
1288device_unregister_oids(device_t dev)
1289{
1290    sysctl_unregister_oid(&dev->oid[0]);
1291    sysctl_unregister_oid(&dev->oid[1]);
1292    sysctl_unregister_oid(&dev->oid[2]);
1293}
1294
1295#endif
1296
1297/*======================================*/
1298/*
1299 * Access functions for device resources.
1300 */
1301
1302/* Supplied by config(8) in ioconf.c */
1303extern struct config_device config_devtab[];
1304extern int devtab_count;
1305
1306/* Runtime version */
1307struct config_device *devtab = config_devtab;
1308
1309static int
1310resource_new_name(const char *name, int unit)
1311{
1312	struct config_device *new;
1313
1314	new = malloc((devtab_count + 1) * sizeof(*new), M_TEMP, M_NOWAIT);
1315	if (new == NULL)
1316		return -1;
1317	if (devtab && devtab_count > 0)
1318		bcopy(devtab, new, devtab_count * sizeof(*new));
1319	bzero(&new[devtab_count], sizeof(*new));
1320	new[devtab_count].name = malloc(strlen(name) + 1, M_TEMP, M_NOWAIT);
1321	if (new[devtab_count].name == NULL) {
1322		free(new, M_TEMP);
1323		return -1;
1324	}
1325	strcpy(new[devtab_count].name, name);
1326	new[devtab_count].unit = unit;
1327	new[devtab_count].resource_count = 0;
1328	new[devtab_count].resources = NULL;
1329	devtab = new;
1330	return devtab_count++;
1331}
1332
1333static int
1334resource_new_resname(int j, const char *resname, resource_type type)
1335{
1336	struct config_resource *new;
1337	int i;
1338
1339	i = devtab[j].resource_count;
1340	new = malloc((i + 1) * sizeof(*new), M_TEMP, M_NOWAIT);
1341	if (new == NULL)
1342		return -1;
1343	if (devtab[j].resources && i > 0)
1344		bcopy(devtab[j].resources, new, i * sizeof(*new));
1345	bzero(&new[i], sizeof(*new));
1346	new[i].name = malloc(strlen(resname) + 1, M_TEMP, M_NOWAIT);
1347	if (new[i].name == NULL) {
1348		free(new, M_TEMP);
1349		return -1;
1350	}
1351	strcpy(new[i].name, resname);
1352	new[i].type = type;
1353	if (devtab[j].resources)
1354		free(devtab[j].resources, M_TEMP);
1355	devtab[j].resources = new;
1356	devtab[j].resource_count = i + 1;
1357	return i;
1358}
1359
1360static int
1361resource_match_string(int i, const char *resname, const char *value)
1362{
1363	int j;
1364	struct config_resource *res;
1365
1366	for (j = 0, res = devtab[i].resources;
1367	     j < devtab[i].resource_count; j++, res++)
1368		if (!strcmp(res->name, resname)
1369		    && res->type == RES_STRING
1370		    && !strcmp(res->u.stringval, value))
1371			return j;
1372	return -1;
1373}
1374
1375static int
1376resource_find(const char *name, int unit, const char *resname,
1377	      struct config_resource **result)
1378{
1379	int i, j;
1380	struct config_resource *res;
1381
1382	/*
1383	 * First check specific instances, then generic.
1384	 */
1385	for (i = 0; i < devtab_count; i++) {
1386		if (devtab[i].unit < 0)
1387			continue;
1388		if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
1389			res = devtab[i].resources;
1390			for (j = 0; j < devtab[i].resource_count; j++, res++)
1391				if (!strcmp(res->name, resname)) {
1392					*result = res;
1393					return 0;
1394				}
1395		}
1396	}
1397	for (i = 0; i < devtab_count; i++) {
1398		if (devtab[i].unit >= 0)
1399			continue;
1400		/* XXX should this `&& devtab[i].unit == unit' be here? */
1401		/* XXX if so, then the generic match does nothing */
1402		if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
1403			res = devtab[i].resources;
1404			for (j = 0; j < devtab[i].resource_count; j++, res++)
1405				if (!strcmp(res->name, resname)) {
1406					*result = res;
1407					return 0;
1408				}
1409		}
1410	}
1411	return ENOENT;
1412}
1413
1414int
1415resource_int_value(const char *name, int unit, const char *resname, int *result)
1416{
1417	int error;
1418	struct config_resource *res;
1419
1420	if ((error = resource_find(name, unit, resname, &res)) != 0)
1421		return error;
1422	if (res->type != RES_INT)
1423		return EFTYPE;
1424	*result = res->u.intval;
1425	return 0;
1426}
1427
1428int
1429resource_long_value(const char *name, int unit, const char *resname,
1430		    long *result)
1431{
1432	int error;
1433	struct config_resource *res;
1434
1435	if ((error = resource_find(name, unit, resname, &res)) != 0)
1436		return error;
1437	if (res->type != RES_LONG)
1438		return EFTYPE;
1439	*result = res->u.longval;
1440	return 0;
1441}
1442
1443int
1444resource_string_value(const char *name, int unit, const char *resname,
1445		      char **result)
1446{
1447	int error;
1448	struct config_resource *res;
1449
1450	if ((error = resource_find(name, unit, resname, &res)) != 0)
1451		return error;
1452	if (res->type != RES_STRING)
1453		return EFTYPE;
1454	*result = res->u.stringval;
1455	return 0;
1456}
1457
1458int
1459resource_query_string(int i, const char *resname, const char *value)
1460{
1461	if (i < 0)
1462		i = 0;
1463	else
1464		i = i + 1;
1465	for (; i < devtab_count; i++)
1466		if (resource_match_string(i, resname, value) >= 0)
1467			return i;
1468	return -1;
1469}
1470
1471int
1472resource_locate(int i, const char *resname)
1473{
1474	if (i < 0)
1475		i = 0;
1476	else
1477		i = i + 1;
1478	for (; i < devtab_count; i++)
1479		if (!strcmp(devtab[i].name, resname))
1480			return i;
1481	return -1;
1482}
1483
1484int
1485resource_count(void)
1486{
1487	return devtab_count;
1488}
1489
1490char *
1491resource_query_name(int i)
1492{
1493	return devtab[i].name;
1494}
1495
1496int
1497resource_query_unit(int i)
1498{
1499	return devtab[i].unit;
1500}
1501
1502static int
1503resource_create(const char *name, int unit, const char *resname,
1504		resource_type type, struct config_resource **result)
1505{
1506	int i, j;
1507	struct config_resource *res = NULL;
1508
1509	for (i = 0; i < devtab_count; i++) {
1510		if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
1511			res = devtab[i].resources;
1512			break;
1513		}
1514	}
1515	if (res == NULL) {
1516		i = resource_new_name(name, unit);
1517		if (i < 0)
1518			return ENOMEM;
1519		res = devtab[i].resources;
1520	}
1521	for (j = 0; j < devtab[i].resource_count; j++, res++) {
1522		if (!strcmp(res->name, resname)) {
1523			*result = res;
1524			return 0;
1525		}
1526	}
1527	j = resource_new_resname(i, resname, type);
1528	if (j < 0)
1529		return ENOMEM;
1530	res = &devtab[i].resources[j];
1531	*result = res;
1532	return 0;
1533}
1534
1535int
1536resource_set_int(const char *name, int unit, const char *resname, int value)
1537{
1538	int error;
1539	struct config_resource *res;
1540
1541	error = resource_create(name, unit, resname, RES_INT, &res);
1542	if (error)
1543		return error;
1544	if (res->type != RES_INT)
1545		return EFTYPE;
1546	res->u.intval = value;
1547	return 0;
1548}
1549
1550int
1551resource_set_long(const char *name, int unit, const char *resname, long value)
1552{
1553	int error;
1554	struct config_resource *res;
1555
1556	error = resource_create(name, unit, resname, RES_LONG, &res);
1557	if (error)
1558		return error;
1559	if (res->type != RES_LONG)
1560		return EFTYPE;
1561	res->u.longval = value;
1562	return 0;
1563}
1564
1565int
1566resource_set_string(const char *name, int unit, const char *resname,
1567		    const char *value)
1568{
1569	int error;
1570	struct config_resource *res;
1571
1572	error = resource_create(name, unit, resname, RES_STRING, &res);
1573	if (error)
1574		return error;
1575	if (res->type != RES_STRING)
1576		return EFTYPE;
1577	if (res->u.stringval)
1578		free(res->u.stringval, M_TEMP);
1579	res->u.stringval = malloc(strlen(value) + 1, M_TEMP, M_NOWAIT);
1580	if (res->u.stringval == NULL)
1581		return ENOMEM;
1582	strcpy(res->u.stringval, value);
1583	return 0;
1584}
1585
1586
1587static void
1588resource_cfgload(void *dummy __unused)
1589{
1590	struct config_resource *res, *cfgres;
1591	int i, j;
1592	int error;
1593	char *name, *resname;
1594	int unit;
1595	resource_type type;
1596	char *stringval;
1597	int config_devtab_count;
1598
1599	config_devtab_count = devtab_count;
1600	devtab = NULL;
1601	devtab_count = 0;
1602
1603	for (i = 0; i < config_devtab_count; i++) {
1604		name = config_devtab[i].name;
1605		unit = config_devtab[i].unit;
1606
1607		for (j = 0; j < config_devtab[i].resource_count; j++) {
1608			cfgres = config_devtab[i].resources;
1609			resname = cfgres[j].name;
1610			type = cfgres[j].type;
1611			error = resource_create(name, unit, resname, type,
1612						&res);
1613			if (error) {
1614				printf("create resource %s%d: error %d\n",
1615					name, unit, error);
1616				continue;
1617			}
1618			if (res->type != type) {
1619				printf("type mismatch %s%d: %d != %d\n",
1620					name, unit, res->type, type);
1621				continue;
1622			}
1623			switch (type) {
1624			case RES_INT:
1625				res->u.intval = cfgres[j].u.intval;
1626				break;
1627			case RES_LONG:
1628				res->u.longval = cfgres[j].u.longval;
1629				break;
1630			case RES_STRING:
1631				if (res->u.stringval)
1632					free(res->u.stringval, M_TEMP);
1633				stringval = cfgres[j].u.stringval;
1634				res->u.stringval = malloc(strlen(stringval) + 1,
1635							  M_TEMP, M_NOWAIT);
1636				if (res->u.stringval == NULL)
1637					break;
1638				strcpy(res->u.stringval, stringval);
1639				break;
1640			default:
1641				panic("unknown resource type %d\n", type);
1642			}
1643		}
1644	}
1645}
1646SYSINIT(cfgload, SI_SUB_KMEM, SI_ORDER_ANY + 50, resource_cfgload, 0)
1647
1648
1649/*======================================*/
1650/*
1651 * Some useful method implementations to make life easier for bus drivers.
1652 */
1653
1654void
1655resource_list_init(struct resource_list *rl)
1656{
1657	SLIST_INIT(rl);
1658}
1659
1660void
1661resource_list_free(struct resource_list *rl)
1662{
1663    struct resource_list_entry *rle;
1664
1665    while ((rle = SLIST_FIRST(rl)) != NULL) {
1666	if (rle->res)
1667	    panic("resource_list_free: resource entry is busy");
1668	SLIST_REMOVE_HEAD(rl, link);
1669	free(rle, M_BUS);
1670    }
1671}
1672
1673void
1674resource_list_add(struct resource_list *rl,
1675		  int type, int rid,
1676		  u_long start, u_long end, u_long count)
1677{
1678    struct resource_list_entry *rle;
1679
1680    rle = resource_list_find(rl, type, rid);
1681    if (!rle) {
1682	rle = malloc(sizeof(struct resource_list_entry), M_BUS, M_NOWAIT);
1683	if (!rle)
1684	    panic("resource_list_add: can't record entry");
1685	SLIST_INSERT_HEAD(rl, rle, link);
1686	rle->type = type;
1687	rle->rid = rid;
1688	rle->res = NULL;
1689    }
1690
1691    if (rle->res)
1692	panic("resource_list_add: resource entry is busy");
1693
1694    rle->start = start;
1695    rle->end = end;
1696    rle->count = count;
1697}
1698
1699struct resource_list_entry*
1700resource_list_find(struct resource_list *rl,
1701		   int type, int rid)
1702{
1703    struct resource_list_entry *rle;
1704
1705    SLIST_FOREACH(rle, rl, link)
1706	if (rle->type == type && rle->rid == rid)
1707	    return rle;
1708    return NULL;
1709}
1710
1711void
1712resource_list_delete(struct resource_list *rl,
1713		     int type, int rid)
1714{
1715    struct resource_list_entry *rle = resource_list_find(rl, type, rid);
1716
1717    if (rle) {
1718	SLIST_REMOVE(rl, rle, resource_list_entry, link);
1719	free(rle, M_BUS);
1720    }
1721}
1722
1723struct resource *
1724resource_list_alloc(struct resource_list *rl,
1725		    device_t bus, device_t child,
1726		    int type, int *rid,
1727		    u_long start, u_long end,
1728		    u_long count, u_int flags)
1729{
1730    struct resource_list_entry *rle = 0;
1731    int passthrough = (device_get_parent(child) != bus);
1732    int isdefault = (start == 0UL && end == ~0UL);
1733
1734    if (passthrough) {
1735	return BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1736				  type, rid,
1737				  start, end, count, flags);
1738    }
1739
1740    rle = resource_list_find(rl, type, *rid);
1741
1742    if (!rle)
1743	return 0;		/* no resource of that type/rid */
1744    if (rle->res)
1745	panic("resource_list_alloc: resource entry is busy");
1746
1747    if (isdefault) {
1748	start = rle->start;
1749	count = max(count, rle->count);
1750	end = max(rle->end, start + count - 1);
1751    }
1752
1753    rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1754				  type, rid, start, end, count, flags);
1755
1756    /*
1757     * Record the new range.
1758     */
1759    if (rle->res) {
1760	    rle->start = rman_get_start(rle->res);
1761	    rle->end = rman_get_end(rle->res);
1762	    rle->count = count;
1763    }
1764
1765    return rle->res;
1766}
1767
1768int
1769resource_list_release(struct resource_list *rl,
1770		      device_t bus, device_t child,
1771		      int type, int rid, struct resource *res)
1772{
1773    struct resource_list_entry *rle = 0;
1774    int passthrough = (device_get_parent(child) != bus);
1775    int error;
1776
1777    if (passthrough) {
1778	return BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1779				    type, rid, res);
1780    }
1781
1782    rle = resource_list_find(rl, type, rid);
1783
1784    if (!rle)
1785	panic("resource_list_release: can't find resource");
1786    if (!rle->res)
1787	panic("resource_list_release: resource entry is not busy");
1788
1789    error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1790				 type, rid, res);
1791    if (error)
1792	return error;
1793
1794    rle->res = NULL;
1795    return 0;
1796}
1797
1798/*
1799 * Call DEVICE_IDENTIFY for each driver.
1800 */
1801int
1802bus_generic_probe(device_t dev)
1803{
1804    devclass_t dc = dev->devclass;
1805    driverlink_t dl;
1806
1807    for (dl = TAILQ_FIRST(&dc->drivers); dl; dl = TAILQ_NEXT(dl, link))
1808	DEVICE_IDENTIFY(dl->driver, dev);
1809
1810    return 0;
1811}
1812
1813int
1814bus_generic_attach(device_t dev)
1815{
1816    device_t child;
1817
1818    for (child = TAILQ_FIRST(&dev->children);
1819	 child; child = TAILQ_NEXT(child, link))
1820	device_probe_and_attach(child);
1821
1822    return 0;
1823}
1824
1825int
1826bus_generic_detach(device_t dev)
1827{
1828    device_t child;
1829    int error;
1830
1831    if (dev->state != DS_ATTACHED)
1832	return EBUSY;
1833
1834    for (child = TAILQ_FIRST(&dev->children);
1835	 child; child = TAILQ_NEXT(child, link))
1836	if ((error = device_detach(child)) != 0)
1837	    return error;
1838
1839    return 0;
1840}
1841
1842int
1843bus_generic_shutdown(device_t dev)
1844{
1845    device_t child;
1846
1847    for (child = TAILQ_FIRST(&dev->children);
1848	 child; child = TAILQ_NEXT(child, link))
1849	device_shutdown(child);
1850
1851    return 0;
1852}
1853
1854int
1855bus_generic_suspend(device_t dev)
1856{
1857	int		error;
1858	device_t	child, child2;
1859
1860	for (child = TAILQ_FIRST(&dev->children);
1861	     child; child = TAILQ_NEXT(child, link)) {
1862		error = DEVICE_SUSPEND(child);
1863		if (error) {
1864			for (child2 = TAILQ_FIRST(&dev->children);
1865			     child2 && child2 != child;
1866			     child2 = TAILQ_NEXT(child2, link))
1867				DEVICE_RESUME(child2);
1868			return (error);
1869		}
1870	}
1871	return 0;
1872}
1873
1874int
1875bus_generic_resume(device_t dev)
1876{
1877	device_t	child;
1878
1879	for (child = TAILQ_FIRST(&dev->children);
1880	     child; child = TAILQ_NEXT(child, link)) {
1881		DEVICE_RESUME(child);
1882		/* if resume fails, there's nothing we can usefully do... */
1883	}
1884	return 0;
1885}
1886
1887int
1888bus_print_child_header (device_t dev, device_t child)
1889{
1890	int	retval = 0;
1891
1892	if (device_get_desc(child)) {
1893		retval += device_printf(child, "<%s>",
1894				       device_get_desc(child));
1895	} else {
1896		retval += printf("%s", device_get_nameunit(child));
1897	}
1898
1899	return (retval);
1900}
1901
1902int
1903bus_print_child_footer (device_t dev, device_t child)
1904{
1905	return(printf(" on %s\n", device_get_nameunit(dev)));
1906}
1907
1908int
1909bus_generic_print_child(device_t dev, device_t child)
1910{
1911	int	retval = 0;
1912
1913	retval += bus_print_child_header(dev, child);
1914	retval += bus_print_child_footer(dev, child);
1915
1916	return (retval);
1917}
1918
1919int
1920bus_generic_read_ivar(device_t dev, device_t child, int index,
1921		      uintptr_t * result)
1922{
1923    return ENOENT;
1924}
1925
1926int
1927bus_generic_write_ivar(device_t dev, device_t child, int index,
1928		       uintptr_t value)
1929{
1930    return ENOENT;
1931}
1932
1933void
1934bus_generic_driver_added(device_t dev, driver_t *driver)
1935{
1936    device_t child;
1937
1938    DEVICE_IDENTIFY(driver, dev);
1939    for (child = TAILQ_FIRST(&dev->children);
1940	 child; child = TAILQ_NEXT(child, link))
1941	if (child->state == DS_NOTPRESENT)
1942	    device_probe_and_attach(child);
1943}
1944
1945int
1946bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1947		       int flags, driver_intr_t *intr, void *arg,
1948		       void **cookiep)
1949{
1950	/* Propagate up the bus hierarchy until someone handles it. */
1951	if (dev->parent)
1952		return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
1953				       intr, arg, cookiep));
1954	else
1955		return (EINVAL);
1956}
1957
1958int
1959bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
1960			  void *cookie)
1961{
1962	/* Propagate up the bus hierarchy until someone handles it. */
1963	if (dev->parent)
1964		return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
1965	else
1966		return (EINVAL);
1967}
1968
1969struct resource *
1970bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
1971			   u_long start, u_long end, u_long count, u_int flags)
1972{
1973	/* Propagate up the bus hierarchy until someone handles it. */
1974	if (dev->parent)
1975		return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid,
1976					   start, end, count, flags));
1977	else
1978		return (NULL);
1979}
1980
1981int
1982bus_generic_release_resource(device_t dev, device_t child, int type, int rid,
1983			     struct resource *r)
1984{
1985	/* Propagate up the bus hierarchy until someone handles it. */
1986	if (dev->parent)
1987		return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid,
1988					     r));
1989	else
1990		return (EINVAL);
1991}
1992
1993int
1994bus_generic_activate_resource(device_t dev, device_t child, int type, int rid,
1995			      struct resource *r)
1996{
1997	/* Propagate up the bus hierarchy until someone handles it. */
1998	if (dev->parent)
1999		return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid,
2000					      r));
2001	else
2002		return (EINVAL);
2003}
2004
2005int
2006bus_generic_deactivate_resource(device_t dev, device_t child, int type,
2007				int rid, struct resource *r)
2008{
2009	/* Propagate up the bus hierarchy until someone handles it. */
2010	if (dev->parent)
2011		return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
2012						r));
2013	else
2014		return (EINVAL);
2015}
2016
2017/*
2018 * Some convenience functions to make it easier for drivers to use the
2019 * resource-management functions.  All these really do is hide the
2020 * indirection through the parent's method table, making for slightly
2021 * less-wordy code.  In the future, it might make sense for this code
2022 * to maintain some sort of a list of resources allocated by each device.
2023 */
2024struct resource *
2025bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end,
2026		   u_long count, u_int flags)
2027{
2028	if (dev->parent == 0)
2029		return (0);
2030	return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
2031				   count, flags));
2032}
2033
2034int
2035bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
2036{
2037	if (dev->parent == 0)
2038		return (EINVAL);
2039	return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
2040}
2041
2042int
2043bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
2044{
2045	if (dev->parent == 0)
2046		return (EINVAL);
2047	return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
2048}
2049
2050int
2051bus_release_resource(device_t dev, int type, int rid, struct resource *r)
2052{
2053	if (dev->parent == 0)
2054		return (EINVAL);
2055	return (BUS_RELEASE_RESOURCE(dev->parent, dev,
2056				     type, rid, r));
2057}
2058
2059int
2060bus_setup_intr(device_t dev, struct resource *r, int flags,
2061	       driver_intr_t handler, void *arg, void **cookiep)
2062{
2063	if (dev->parent == 0)
2064		return (EINVAL);
2065	return (BUS_SETUP_INTR(dev->parent, dev, r, flags,
2066			       handler, arg, cookiep));
2067}
2068
2069int
2070bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
2071{
2072	if (dev->parent == 0)
2073		return (EINVAL);
2074	return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
2075}
2076
2077int
2078bus_set_resource(device_t dev, int type, int rid,
2079		 u_long start, u_long count)
2080{
2081	return BUS_SET_RESOURCE(device_get_parent(dev), dev, type, rid,
2082				start, count);
2083}
2084
2085int
2086bus_get_resource(device_t dev, int type, int rid,
2087		 u_long *startp, u_long *countp)
2088{
2089	return BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2090				startp, countp);
2091}
2092
2093u_long
2094bus_get_resource_start(device_t dev, int type, int rid)
2095{
2096	u_long start, count;
2097	int error;
2098
2099	error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2100				 &start, &count);
2101	if (error)
2102		return 0;
2103	return start;
2104}
2105
2106u_long
2107bus_get_resource_count(device_t dev, int type, int rid)
2108{
2109	u_long start, count;
2110	int error;
2111
2112	error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2113				 &start, &count);
2114	if (error)
2115		return 0;
2116	return count;
2117}
2118
2119void
2120bus_delete_resource(device_t dev, int type, int rid)
2121{
2122	BUS_DELETE_RESOURCE(device_get_parent(dev), dev, type, rid);
2123}
2124
2125static int
2126root_print_child(device_t dev, device_t child)
2127{
2128	return (0);
2129}
2130
2131static int
2132root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg,
2133		void **cookiep)
2134{
2135	/*
2136	 * If an interrupt mapping gets to here something bad has happened.
2137	 */
2138	panic("root_setup_intr");
2139}
2140
2141static device_method_t root_methods[] = {
2142	/* Device interface */
2143	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
2144	DEVMETHOD(device_suspend,	bus_generic_suspend),
2145	DEVMETHOD(device_resume,	bus_generic_resume),
2146
2147	/* Bus interface */
2148	DEVMETHOD(bus_print_child,	root_print_child),
2149	DEVMETHOD(bus_read_ivar,	bus_generic_read_ivar),
2150	DEVMETHOD(bus_write_ivar,	bus_generic_write_ivar),
2151	DEVMETHOD(bus_setup_intr,	root_setup_intr),
2152
2153	{ 0, 0 }
2154};
2155
2156static driver_t root_driver = {
2157	"root",
2158	root_methods,
2159	1,			/* no softc */
2160};
2161
2162device_t	root_bus;
2163devclass_t	root_devclass;
2164
2165static int
2166root_bus_module_handler(module_t mod, int what, void* arg)
2167{
2168    switch (what) {
2169    case MOD_LOAD:
2170	compile_methods(&root_driver);
2171	root_bus = make_device(NULL, "root", 0);
2172	root_bus->desc = "System root bus";
2173	root_bus->ops = root_driver.ops;
2174	root_bus->driver = &root_driver;
2175	root_bus->state = DS_ATTACHED;
2176	root_devclass = devclass_find_internal("root", FALSE);
2177	return 0;
2178
2179    case MOD_SHUTDOWN:
2180	device_shutdown(root_bus);
2181	return 0;
2182    }
2183
2184    return 0;
2185}
2186
2187static moduledata_t root_bus_mod = {
2188	"rootbus",
2189	root_bus_module_handler,
2190	0
2191};
2192DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
2193
2194void
2195root_bus_configure(void)
2196{
2197    device_t dev;
2198
2199    PDEBUG(("."));
2200
2201    for (dev = TAILQ_FIRST(&root_bus->children); dev;
2202	 dev = TAILQ_NEXT(dev, link)) {
2203	device_probe_and_attach(dev);
2204    }
2205}
2206
2207int
2208driver_module_handler(module_t mod, int what, void *arg)
2209{
2210	int error, i;
2211	struct driver_module_data *dmd;
2212	devclass_t bus_devclass;
2213
2214	dmd = (struct driver_module_data *)arg;
2215	bus_devclass = devclass_find_internal(dmd->dmd_busname, TRUE);
2216	error = 0;
2217
2218	switch (what) {
2219	case MOD_LOAD:
2220		if (dmd->dmd_chainevh)
2221			error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
2222
2223		for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
2224			PDEBUG(("Loading module: driver %s on bus %s",
2225				DRIVERNAME(dmd->dmd_drivers[i]),
2226				dmd->dmd_busname));
2227			error = devclass_add_driver(bus_devclass,
2228						    dmd->dmd_drivers[i]);
2229		}
2230		if (error)
2231			break;
2232
2233		/*
2234		 * The drivers loaded in this way are assumed to all
2235		 * implement the same devclass.
2236		 */
2237		*dmd->dmd_devclass =
2238			devclass_find_internal(dmd->dmd_drivers[0]->name,
2239					       TRUE);
2240		break;
2241
2242	case MOD_UNLOAD:
2243		for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
2244			PDEBUG(("Unloading module: driver %s from bus %s",
2245				DRIVERNAME(dmd->dmd_drivers[i]),
2246				dmd->dmd_busname));
2247			error = devclass_delete_driver(bus_devclass,
2248						       dmd->dmd_drivers[i]);
2249		}
2250
2251		if (!error && dmd->dmd_chainevh)
2252			error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
2253		break;
2254	}
2255
2256	return (error);
2257}
2258
2259#ifdef BUS_DEBUG
2260
2261/* the _short versions avoid iteration by not calling anything that prints
2262 * more than oneliners. I love oneliners.
2263 */
2264
2265static void
2266print_method_list(device_method_t *m, int indent)
2267{
2268	int i;
2269
2270	if (!m)
2271		return;
2272
2273	for (i = 0; m->desc; i++, m++)
2274		indentprintf(("method %d: %s, offset=%d\n",
2275			i, m->desc->name, m->desc->offset));
2276}
2277
2278static void
2279print_device_ops(device_ops_t ops, int indent)
2280{
2281	int i;
2282	int count = 0;
2283
2284	if (!ops)
2285		return;
2286
2287	/* we present a list of the methods that are pointing to the
2288	 * error_method, but ignore the 0'th elements; it is always
2289	 * error_method.
2290	 */
2291	for (i = 1; i < ops->maxoffset; i++) {
2292		if (ops->methods[i] == error_method) {
2293			if (count == 0)
2294				indentprintf(("error_method:"));
2295			printf(" %d", i);
2296			count++;
2297		}
2298	}
2299	if (count)
2300		printf("\n");
2301
2302	indentprintf(("(%d method%s, %d valid, %d error_method%s)\n",
2303		ops->maxoffset-1, (ops->maxoffset-1 == 1? "":"s"),
2304		ops->maxoffset-1-count,
2305		count, (count == 1? "":"'s")));
2306}
2307
2308static void
2309print_device_short(device_t dev, int indent)
2310{
2311	if (!dev)
2312		return;
2313
2314	indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
2315		dev->unit, dev->desc,
2316		(dev->parent? "":"no "),
2317		(TAILQ_EMPTY(&dev->children)? "no ":""),
2318		(dev->flags&DF_ENABLED? "enabled,":"disabled,"),
2319		(dev->flags&DF_FIXEDCLASS? "fixed,":""),
2320		(dev->flags&DF_WILDCARD? "wildcard,":""),
2321		(dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
2322		(dev->ivars? "":"no "),
2323		(dev->softc? "":"no "),
2324		dev->busy));
2325}
2326
2327static void
2328print_device(device_t dev, int indent)
2329{
2330	if (!dev)
2331		return;
2332
2333	print_device_short(dev, indent);
2334
2335	indentprintf(("Parent:\n"));
2336	print_device_short(dev->parent, indent+1);
2337	indentprintf(("Methods:\n"));
2338	print_device_ops(dev->ops, indent+1);
2339	indentprintf(("Driver:\n"));
2340	print_driver_short(dev->driver, indent+1);
2341	indentprintf(("Devclass:\n"));
2342	print_devclass_short(dev->devclass, indent+1);
2343}
2344
2345void
2346print_device_tree_short(device_t dev, int indent)
2347/* print the device and all its children (indented) */
2348{
2349	device_t child;
2350
2351	if (!dev)
2352		return;
2353
2354	print_device_short(dev, indent);
2355
2356	for (child = TAILQ_FIRST(&dev->children); child;
2357		 child = TAILQ_NEXT(child, link))
2358		print_device_tree_short(child, indent+1);
2359}
2360
2361void
2362print_device_tree(device_t dev, int indent)
2363/* print the device and all its children (indented) */
2364{
2365	device_t child;
2366
2367	if (!dev)
2368		return;
2369
2370	print_device(dev, indent);
2371
2372	for (child = TAILQ_FIRST(&dev->children); child;
2373		 child = TAILQ_NEXT(child, link))
2374		print_device_tree(child, indent+1);
2375}
2376
2377static void
2378print_driver_short(driver_t *driver, int indent)
2379{
2380	if (!driver)
2381		return;
2382
2383	indentprintf(("driver %s: softc size = %d\n",
2384		driver->name, driver->softc));
2385}
2386
2387static void
2388print_driver(driver_t *driver, int indent)
2389{
2390	if (!driver)
2391		return;
2392
2393	print_driver_short(driver, indent);
2394	indentprintf(("Methods:\n"));
2395	print_method_list(driver->methods, indent+1);
2396	indentprintf(("Operations:\n"));
2397	print_device_ops(driver->ops, indent+1);
2398}
2399
2400
2401static void
2402print_driver_list(driver_list_t drivers, int indent)
2403{
2404	driverlink_t driver;
2405
2406	for (driver = TAILQ_FIRST(&drivers); driver;
2407	     driver = TAILQ_NEXT(driver, link))
2408		print_driver(driver->driver, indent);
2409}
2410
2411static void
2412print_devclass_short(devclass_t dc, int indent)
2413{
2414	if ( !dc )
2415		return;
2416
2417	indentprintf(("devclass %s: max units = %d, next unit = %d\n",
2418		dc->name, dc->maxunit, dc->nextunit));
2419}
2420
2421static void
2422print_devclass(devclass_t dc, int indent)
2423{
2424	int i;
2425
2426	if ( !dc )
2427		return;
2428
2429	print_devclass_short(dc, indent);
2430	indentprintf(("Drivers:\n"));
2431	print_driver_list(dc->drivers, indent+1);
2432
2433	indentprintf(("Devices:\n"));
2434	for (i = 0; i < dc->maxunit; i++)
2435		if (dc->devices[i])
2436			print_device(dc->devices[i], indent+1);
2437}
2438
2439void
2440print_devclass_list_short(void)
2441{
2442	devclass_t dc;
2443
2444	printf("Short listing of devclasses, drivers & devices:\n");
2445	for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link))
2446		print_devclass_short(dc, 0);
2447}
2448
2449void
2450print_devclass_list(void)
2451{
2452	devclass_t dc;
2453
2454	printf("Full listing of devclasses, drivers & devices:\n");
2455	for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link))
2456		print_devclass(dc, 0);
2457}
2458
2459#endif
2460