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