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