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