xref: /freebsd/sys/kern/subr_bus.c (revision 0640d357f29fb1c0daaaffadd0416c5981413afd)
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.7 1998/10/25 17:44:51 phk 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/bus_private.h>
35 #include <sys/systm.h>
36 
37 #include "opt_bus.h"
38 
39 #ifdef BUS_DEBUG
40 #define PDEBUG(a)	(printf(__FUNCTION__ ":%d: ", __LINE__), printf a, printf("\n"))
41 #define DEVICENAME(d)	((d)? device_get_name(d): "no device")
42 #define DRIVERNAME(d)	((d)? d->name : "no driver")
43 #define DEVCLANAME(d)	((d)? d->name : "no devclass")
44 
45 /* Produce the indenting, indent*2 spaces plus a '.' ahead of that to
46  * prevent syslog from deleting initial spaces
47  */
48 #define indentprintf(p)	do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf("  "); printf p ; } while(0)
49 
50 static void print_method_list(device_method_t *m, int indent);
51 static void print_device_ops(device_ops_t ops, int indent);
52 static void print_device_short(device_t dev, int indent);
53 static void print_device(device_t dev, int indent);
54 void print_device_tree_short(device_t dev, int indent);
55 void print_device_tree(device_t dev, int indent);
56 static void print_driver_short(driver_t *driver, int indent);
57 static void print_driver(driver_t *driver, int indent);
58 static void print_driver_list(driver_list_t drivers, int indent);
59 static void print_devclass_short(devclass_t dc, int indent);
60 static void print_devclass(devclass_t dc, int indent);
61 void print_devclass_list_short(void);
62 void print_devclass_list(void);
63 
64 #else
65 /* Make the compiler ignore the function calls */
66 #define PDEBUG(a)			/* nop */
67 #define DEVICENAME(d)			/* nop */
68 #define DRIVERNAME(d)			/* nop */
69 #define DEVCLANAME(d)			/* nop */
70 
71 #define print_method_list(m,i)		/* nop */
72 #define print_device_ops(o,i)		/* nop */
73 #define print_device_short(d,i)		/* nop */
74 #define print_device(d,i)		/* nop */
75 #define print_device_tree_short(d,i)	/* nop */
76 #define print_device_tree(d,i)		/* nop */
77 #define print_driver_short(d,i)		/* nop */
78 #define print_driver(d,i)		/* nop */
79 #define print_driver_list(d,i)		/* nop */
80 #define print_devclass_short(d,i)	/* nop */
81 #define print_devclass(d,i)		/* nop */
82 #define print_devclass_list_short()	/* nop */
83 #define print_devclass_list()		/* nop */
84 #endif
85 
86 
87 /*
88  * Method table handling
89  */
90 static int next_method_offset = 1;
91 static int methods_count = 0;
92 static int methods_size = 0;
93 
94 struct method {
95     int offset;
96     char* name;
97 };
98 
99 static struct method *methods = 0;
100 
101 static void
102 register_method(struct device_op_desc *desc)
103 {
104     int i;
105     struct method* m;
106 
107     for (i = 0; i < methods_count; i++)
108 	if (!strcmp(methods[i].name, desc->name)) {
109 	    desc->offset = methods[i].offset;
110 	    PDEBUG(("methods[%d] has the same name, %s, with offset %d",
111 	    		i, desc->name, desc->offset));
112 	    return;
113 	}
114 
115     if (methods_count == methods_size) {
116 	struct method* p;
117 
118 	methods_size += 10;
119 	p = (struct method*) malloc(methods_size * sizeof(struct method),
120 				     M_DEVBUF, M_NOWAIT);
121 	if (!p)
122 	    panic("register_method: out of memory");
123 	if (methods) {
124 	    bcopy(methods, p, methods_count * sizeof(struct method));
125 	    free(methods, M_DEVBUF);
126 	}
127 	methods = p;
128     }
129     m = &methods[methods_count++];
130     m->name = malloc(strlen(desc->name) + 1, M_DEVBUF, M_NOWAIT);
131     if (!m->name)
132 	    panic("register_method: out of memory");
133     strcpy(m->name, desc->name);
134     desc->offset = m->offset = next_method_offset++;
135 }
136 
137 static int error_method(void)
138 {
139     return ENXIO;
140 }
141 
142 static struct device_ops null_ops = {
143     1,
144     { error_method }
145 };
146 
147 static void
148 compile_methods(driver_t *driver)
149 {
150     device_ops_t ops;
151     struct device_method *m;
152     int i;
153 
154     /*
155      * First register any methods which need it.
156      */
157     for (i = 0, m = driver->methods; m->desc; i++, m++)
158 	if (!m->desc->offset)
159 	    register_method(m->desc);
160 	else
161 	    PDEBUG(("offset not equal to zero, method desc %d left as is", i));
162 
163     /*
164      * Then allocate the compiled op table.
165      */
166     ops = malloc(sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t),
167 		 M_DEVBUF, M_NOWAIT);
168     if (!ops)
169 	panic("compile_methods: out of memory");
170 
171     ops->maxoffset = next_method_offset;
172     for (i = 0; i < next_method_offset; i++)
173 	ops->methods[i] = error_method;
174     for (i = 0, m = driver->methods; m->desc; i++, m++)
175 	ops->methods[m->desc->offset] = m->func;
176     PDEBUG(("%s has %d method%s, wasting %d bytes",
177     		DRIVERNAME(driver), i, (i==1?"":"s"),
178 		(next_method_offset-i)*sizeof(devop_t)));
179 
180     driver->ops = ops;
181 }
182 
183 /*
184  * Devclass implementation
185  */
186 
187 static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
188 
189 static devclass_t
190 devclass_find_internal(const char *classname, int create)
191 {
192     devclass_t dc;
193 
194     PDEBUG(("looking for %s", classname));
195     if (!classname)
196 	return NULL;
197 
198     for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link))
199 	if (!strcmp(dc->name, classname))
200 	    return dc;
201 
202     PDEBUG(("%s not found%s", classname, (create? ", creating": "")));
203     if (create) {
204 	dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,
205 		    M_DEVBUF, M_NOWAIT);
206 	if (!dc)
207 	    return NULL;
208 	dc->name = (char*) (dc + 1);
209 	strcpy(dc->name, classname);
210 	dc->devices = NULL;
211 	dc->maxunit = 0;
212 	dc->nextunit = 0;
213 	TAILQ_INIT(&dc->drivers);
214 	TAILQ_INSERT_TAIL(&devclasses, dc, link);
215     }
216 
217     return dc;
218 }
219 
220 devclass_t
221 devclass_find(const char *classname)
222 {
223     return devclass_find_internal(classname, FALSE);
224 }
225 
226 int
227 devclass_add_driver(devclass_t dc, driver_t *driver)
228 {
229     PDEBUG(("%s", DRIVERNAME(driver)));
230     /*
231      * Compile the drivers methods.
232      */
233     compile_methods(driver);
234 
235     /*
236      * Make sure the devclass which the driver is implementing exists.
237      */
238     devclass_find_internal(driver->name, TRUE);
239 
240     TAILQ_INSERT_TAIL(&dc->drivers, driver, link);
241 
242     return 0;
243 }
244 
245 int
246 devclass_delete_driver(devclass_t busclass, driver_t *driver)
247 {
248     devclass_t dc = devclass_find(driver->name);
249     device_t dev;
250     int i;
251     int error;
252 
253     PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
254 
255     if (!dc)
256 	return 0;
257 
258     /*
259      * Disassociate from any devices.  We iterate through all the
260      * devices in the devclass of the driver and detach any which are
261      * using the driver.
262      */
263     for (i = 0; i < dc->maxunit; i++) {
264 	if (dc->devices[i]) {
265 	    dev = dc->devices[i];
266 	    if (dev->driver == driver) {
267 		if (error = device_detach(dev))
268 		    return error;
269 		device_set_driver(dev, NULL);
270 	    }
271 	}
272     }
273 
274     TAILQ_REMOVE(&busclass->drivers, driver, link);
275     return 0;
276 }
277 
278 driver_t *
279 devclass_find_driver(devclass_t dc, const char *classname)
280 {
281     driver_t *driver;
282 
283     PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc)));
284 
285     for (driver = TAILQ_FIRST(&dc->drivers); driver;
286 	 driver = TAILQ_NEXT(driver, link)) {
287 	if (!strcmp(driver->name, classname))
288 	    return driver;
289     }
290 
291     PDEBUG(("not found"));
292     return NULL;
293 }
294 
295 const char *
296 devclass_get_name(devclass_t dc)
297 {
298     return dc->name;
299 }
300 
301 device_t
302 devclass_get_device(devclass_t dc, int unit)
303 {
304     if (unit < 0 || unit >= dc->maxunit)
305 	return NULL;
306     return dc->devices[unit];
307 }
308 
309 void *
310 devclass_get_softc(devclass_t dc, int unit)
311 {
312     device_t dev;
313 
314     if (unit < 0 || unit >= dc->maxunit)
315 	return NULL;
316     dev = dc->devices[unit];
317     if (!dev || dev->state < DS_ATTACHED)
318 	return NULL;
319     return dev->softc;
320 }
321 
322 int
323 devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp)
324 {
325     int i;
326     int count;
327     device_t *list;
328 
329     count = 0;
330     for (i = 0; i < dc->maxunit; i++)
331 	if (dc->devices[i])
332 	    count++;
333 
334     list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
335     if (!list)
336 	return ENOMEM;
337 
338     count = 0;
339     for (i = 0; i < dc->maxunit; i++)
340 	if (dc->devices[i]) {
341 	    list[count] = dc->devices[i];
342 	    count++;
343 	}
344 
345     *devlistp = list;
346     *devcountp = count;
347 
348     return 0;
349 }
350 
351 int
352 devclass_get_maxunit(devclass_t dc)
353 {
354     return dc->maxunit;
355 }
356 
357 static int
358 devclass_alloc_unit(devclass_t dc, int *unitp)
359 {
360     int unit = *unitp;
361 
362     PDEBUG(("unit %d in devclass %s", unit, DEVCLANAME(dc)));
363 
364     /*
365      * If we have been given a wired unit number, check for existing
366      * device.
367      */
368     if (unit != -1) {
369 	device_t dev;
370 	dev = devclass_get_device(dc, unit);
371 	if (dev) {
372 	    printf("devclass_alloc_unit: %s%d already exists, using next available unit number\n", dc->name, unit);
373 	    unit = -1;
374 	}
375     }
376 
377     if (unit == -1) {
378 	unit = dc->nextunit;
379 	dc->nextunit++;
380     } else if (dc->nextunit <= unit)
381 	dc->nextunit = unit + 1;
382 
383     if (unit >= dc->maxunit) {
384 	device_t *newlist;
385 	int newsize;
386 
387 	newsize = (dc->maxunit ? 2 * dc->maxunit
388 		   : MINALLOCSIZE / sizeof(device_t));
389 	newlist = malloc(sizeof(device_t) * newsize, M_DEVBUF, M_NOWAIT);
390 	if (!newlist)
391 	    return ENOMEM;
392 	bcopy(dc->devices, newlist, sizeof(device_t) * dc->maxunit);
393 	bzero(newlist + dc->maxunit,
394 	      sizeof(device_t) * (newsize - dc->maxunit));
395 	if (dc->devices)
396 	    free(dc->devices, M_DEVBUF);
397 	dc->devices = newlist;
398 	dc->maxunit = newsize;
399     }
400     PDEBUG(("now: unit %d in devclass %s", unit, DEVCLANAME(dc)));
401 
402     *unitp = unit;
403     return 0;
404 }
405 
406 static int
407 devclass_add_device(devclass_t dc, device_t dev)
408 {
409     int error;
410 
411     PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
412 
413     if (error = devclass_alloc_unit(dc, &dev->unit))
414 	return error;
415     dc->devices[dev->unit] = dev;
416     dev->devclass = dc;
417     return 0;
418 }
419 
420 static int
421 devclass_delete_device(devclass_t dc, device_t dev)
422 {
423     PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
424 
425     if (dev->devclass != dc
426 	|| dc->devices[dev->unit] != dev)
427 	panic("devclass_delete_device: inconsistent device class");
428     dc->devices[dev->unit] = NULL;
429     if (dev->flags & DF_WILDCARD)
430 	dev->unit = -1;
431     dev->devclass = NULL;
432     while (dc->nextunit > 0 && dc->devices[dc->nextunit - 1] == NULL)
433 	dc->nextunit--;
434     return 0;
435 }
436 
437 static device_t
438 make_device(device_t parent, const char *name,
439 	    int unit, void *ivars)
440 {
441     device_t dev;
442     devclass_t dc;
443     int error;
444 
445     PDEBUG(("%s at %s as unit %d with%s ivars",
446     	    name, DEVICENAME(parent), unit, (ivars? "":"out")));
447 
448     if (name) {
449 	dc = devclass_find_internal(name, TRUE);
450 	if (!dc) {
451 	    printf("make_device: can't find device class %s\n", name);
452 	    return NULL;
453 	}
454 
455 	if (error = devclass_alloc_unit(dc, &unit))
456 	    return NULL;
457     } else
458 	dc = NULL;
459 
460     dev = malloc(sizeof(struct device), M_DEVBUF, M_NOWAIT);
461     if (!dev)
462 	return 0;
463 
464     dev->parent = parent;
465     TAILQ_INIT(&dev->children);
466     dev->ops = &null_ops;
467     dev->driver = NULL;
468     dev->devclass = dc;
469     dev->unit = unit;
470     dev->desc = NULL;
471     dev->busy = 0;
472     dev->flags = DF_ENABLED;
473     if (unit == -1)
474 	dev->flags |= DF_WILDCARD;
475     if (name)
476 	dev->flags |= DF_FIXEDCLASS;
477     dev->ivars = ivars;
478     dev->softc = NULL;
479 
480     if (dc)
481 	dc->devices[unit] = dev;
482 
483     dev->state = DS_NOTPRESENT;
484 
485     return dev;
486 }
487 
488 static void
489 device_print_child(device_t dev, device_t child)
490 {
491     printf("%s%d", device_get_name(child), device_get_unit(child));
492     if (device_is_alive(child)) {
493 	if (device_get_desc(child))
494 	    printf(": <%s>", device_get_desc(child));
495 	BUS_PRINT_CHILD(dev, child);
496     } else
497 	printf(" not found");
498     printf("\n");
499 }
500 
501 device_t
502 device_add_child(device_t dev, const char *name, int unit, void *ivars)
503 {
504     device_t child;
505 
506     PDEBUG(("%s at %s as unit %d with%s ivars",
507     	    name, DEVICENAME(dev), unit, (ivars? "":"out")));
508 
509     child = make_device(dev, name, unit, ivars);
510 
511     TAILQ_INSERT_TAIL(&dev->children, child, link);
512 
513     return child;
514 }
515 
516 device_t
517 device_add_child_after(device_t dev, device_t place, const char *name,
518 		       int unit, void *ivars)
519 {
520     device_t child;
521 
522     PDEBUG(("%s at %s after %s as unit %d with%s ivars",
523     	    name, DEVICENAME(dev), DEVICENAME(place), unit, (ivars? "":"out")));
524 
525     child = make_device(dev, name, unit, ivars);
526 
527     if (place) {
528 	TAILQ_INSERT_AFTER(&dev->children, place, dev, link);
529     } else {
530 	TAILQ_INSERT_HEAD(&dev->children, dev, link);
531     }
532 
533     return child;
534 }
535 
536 int
537 device_delete_child(device_t dev, device_t child)
538 {
539     int error;
540 
541     PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
542 
543     if (error = device_detach(child))
544 	return error;
545     if (child->devclass)
546 	devclass_delete_device(child->devclass, child);
547     TAILQ_REMOVE(&dev->children, child, link);
548     free(dev, M_DEVBUF);
549 
550     return 0;
551 }
552 
553 /*
554  * Find only devices attached to this bus.
555  */
556 device_t
557 device_find_child(device_t dev, const char *classname, int unit)
558 {
559     devclass_t dc;
560     device_t child;
561 
562     dc = devclass_find(classname);
563     if (!dc)
564 	return NULL;
565 
566     child = devclass_get_device(dc, unit);
567     if (child && child->parent == dev)
568 	return child;
569     return NULL;
570 }
571 
572 static driver_t *
573 first_matching_driver(devclass_t dc, device_t dev)
574 {
575     if (dev->devclass)
576 	return devclass_find_driver(dc, dev->devclass->name);
577     else
578 	return TAILQ_FIRST(&dc->drivers);
579 }
580 
581 static driver_t *
582 next_matching_driver(devclass_t dc, device_t dev, driver_t *last)
583 {
584     if (dev->devclass) {
585 	driver_t *driver;
586 	for (driver = TAILQ_NEXT(last, link); driver;
587 	     driver = TAILQ_NEXT(driver, link))
588 	    if (!strcmp(dev->devclass->name, driver->name))
589 		return driver;
590 	return NULL;
591     } else
592 	return TAILQ_NEXT(last, link);
593 }
594 
595 static int
596 device_probe_child(device_t dev, device_t child)
597 {
598     devclass_t dc;
599     driver_t *driver;
600 
601     dc = dev->devclass;
602     if (dc == NULL)
603 	panic("device_probe_child: parent device has no devclass");
604 
605     if (child->state == DS_ALIVE)
606 	return 0;
607 
608     for (driver = first_matching_driver(dc, child);
609 	 driver;
610 	 driver = next_matching_driver(dc, child, driver)) {
611 	PDEBUG(("Trying %s", DRIVERNAME(driver)));
612 	device_set_driver(child, driver);
613 	if (DEVICE_PROBE(child) == 0) {
614 	    if (!child->devclass)
615 		device_set_devclass(child, driver->name);
616 	    child->state = DS_ALIVE;
617 	    return 0;
618 	}
619     }
620 
621     return ENXIO;
622 }
623 
624 device_t
625 device_get_parent(device_t dev)
626 {
627     return dev->parent;
628 }
629 
630 driver_t *
631 device_get_driver(device_t dev)
632 {
633     return dev->driver;
634 }
635 
636 devclass_t
637 device_get_devclass(device_t dev)
638 {
639     return dev->devclass;
640 }
641 
642 const char *
643 device_get_name(device_t dev)
644 {
645     if (dev->devclass)
646 	return devclass_get_name(dev->devclass);
647     return NULL;
648 }
649 
650 int
651 device_get_unit(device_t dev)
652 {
653     return dev->unit;
654 }
655 
656 const char *
657 device_get_desc(device_t dev)
658 {
659     return dev->desc;
660 }
661 
662 void
663 device_set_desc(device_t dev, const char* desc)
664 {
665     dev->desc = desc;
666 }
667 
668 void *
669 device_get_softc(device_t dev)
670 {
671     return dev->softc;
672 }
673 
674 void *
675 device_get_ivars(device_t dev)
676 {
677     return dev->ivars;
678 }
679 
680 device_state_t
681 device_get_state(device_t dev)
682 {
683     return dev->state;
684 }
685 
686 void
687 device_enable(device_t dev)
688 {
689     dev->flags |= DF_ENABLED;
690 }
691 
692 void
693 device_disable(device_t dev)
694 {
695     dev->flags &= ~DF_ENABLED;
696 }
697 
698 void
699 device_busy(device_t dev)
700 {
701     if (dev->state < DS_ATTACHED)
702 	panic("device_busy: called for unattached device");
703     if (dev->busy == 0 && dev->parent)
704 	device_busy(dev->parent);
705     dev->busy++;
706     dev->state = DS_BUSY;
707 }
708 
709 void
710 device_unbusy(device_t dev)
711 {
712     if (dev->state != DS_BUSY)
713 	panic("device_unbusy: called for non-busy device");
714     dev->busy--;
715     if (dev->busy == 0) {
716 	if (dev->parent)
717 	    device_unbusy(dev->parent);
718 	dev->state = DS_ATTACHED;
719     }
720 }
721 
722 int
723 device_is_enabled(device_t dev)
724 {
725     return (dev->flags & DF_ENABLED) != 0;
726 }
727 
728 int
729 device_is_alive(device_t dev)
730 {
731     return dev->state >= DS_ALIVE;
732 }
733 
734 int
735 device_set_devclass(device_t dev, const char *classname)
736 {
737     devclass_t dc;
738 
739     if (dev->devclass) {
740 	printf("device_set_devclass: device class already set\n");
741 	return EINVAL;
742     }
743 
744     dc = devclass_find_internal(classname, TRUE);
745     if (!dc)
746 	return ENOMEM;
747 
748     return devclass_add_device(dc, dev);
749 }
750 
751 int
752 device_set_driver(device_t dev, driver_t *driver)
753 {
754     if (dev->state >= DS_ATTACHED)
755 	return EBUSY;
756 
757     if (dev->driver == driver)
758 	return 0;
759 
760     if (dev->softc) {
761 	free(dev->softc, M_DEVBUF);
762 	dev->softc = NULL;
763     }
764     dev->ops = &null_ops;
765     dev->driver = driver;
766     if (driver) {
767 	dev->ops = driver->ops;
768 	dev->softc = malloc(driver->softc, M_DEVBUF, M_NOWAIT);
769 	if (!dev->softc) {
770 	    dev->ops = &null_ops;
771 	    dev->driver = NULL;
772 	    return ENOMEM;
773 	}
774 	bzero(dev->softc, driver->softc);
775     }
776     return 0;
777 }
778 
779 int
780 device_probe_and_attach(device_t dev)
781 {
782     device_t bus = dev->parent;
783     int error;
784 
785     if (dev->state >= DS_ALIVE)
786 	return 0;
787 
788     if (dev->flags & DF_ENABLED) {
789 	device_probe_child(bus, dev);
790 	device_print_child(bus, dev);
791 	if (dev->state == DS_ALIVE) {
792 	    error = DEVICE_ATTACH(dev);
793 	    if (!error)
794 		dev->state = DS_ATTACHED;
795 	    else {
796 		printf("device_probe_and_attach: %s%d attach returned %d\n",
797 		       dev->driver->name, dev->unit, error);
798 		device_set_driver(dev, NULL);
799 		dev->state = DS_NOTPRESENT;
800 	    }
801 	}
802     } else
803 	printf("%s%d: disabled, not probed.\n",
804 	       dev->devclass->name, dev->unit);
805 
806     return 0;
807 }
808 
809 int
810 device_detach(device_t dev)
811 {
812     int error;
813 
814     PDEBUG(("%s", DEVICENAME(dev)));
815     if (dev->state == DS_BUSY)
816 	return EBUSY;
817     if (dev->state != DS_ATTACHED)
818 	return 0;
819 
820     if (error = DEVICE_DETACH(dev))
821 	    return error;
822 
823     if (!(dev->flags & DF_FIXEDCLASS))
824 	devclass_delete_device(dev->devclass, dev);
825 
826     dev->state = DS_NOTPRESENT;
827     device_set_driver(dev, NULL);
828 
829     return 0;
830 }
831 
832 int
833 device_shutdown(device_t dev)
834 {
835     if (dev->state < DS_ATTACHED)
836 	return 0;
837     return DEVICE_SHUTDOWN(dev);
838 }
839 
840 /*
841  * Access functions for device resources.
842  */
843 extern struct config_device devtab[];
844 extern int devtab_count;
845 
846 static int
847 resource_match_string(int i, char *resname, char *value)
848 {
849 	int j;
850 	struct resource *res;
851 
852 	for (j = 0, res = devtab[i].resources;
853 	     j < devtab[i].resource_count; j++, res++)
854 		if (!strcmp(res->name, resname)
855 		    && res->type == RES_STRING
856 		    && !strcmp(res->u.stringval, value))
857 			return TRUE;
858 	return FALSE;
859 }
860 
861 static int
862 resource_find(const char *name, int unit, char *resname, struct resource **result)
863 {
864 	int i, j;
865 	struct resource *res;
866 
867 	/*
868 	 * First check specific instances, then generic.
869 	 */
870 	for (i = 0; i < devtab_count; i++) {
871 		if (devtab[i].unit < 0)
872 			continue;
873 		if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
874 			res = devtab[i].resources;
875 			for (j = 0; j < devtab[i].resource_count; j++, res++)
876 				if (!strcmp(res->name, resname)) {
877 					*result = res;
878 					return 0;
879 				}
880 		}
881 	}
882 	for (i = 0; i < devtab_count; i++) {
883 		if (devtab[i].unit >= 0)
884 			continue;
885 		if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
886 			res = devtab[i].resources;
887 			for (j = 0; j < devtab[i].resource_count; j++, res++)
888 				if (!strcmp(res->name, resname)) {
889 					*result = res;
890 					return 0;
891 				}
892 		}
893 	}
894 	return ENOENT;
895 }
896 
897 int
898 resource_int_value(const char *name, int unit, char *resname, int *result)
899 {
900 	int error;
901 	struct resource *res;
902 	if ((error = resource_find(name, unit, resname, &res)) != 0)
903 		return error;
904 	if (res->type != RES_INT)
905 		return EFTYPE;
906 	*result = res->u.intval;
907 	return 0;
908 }
909 
910 int
911 resource_long_value(const char *name, int unit, char *resname, long *result)
912 {
913 	int error;
914 	struct resource *res;
915 	if ((error = resource_find(name, unit, resname, &res)) != 0)
916 		return error;
917 	if (res->type != RES_LONG)
918 		return EFTYPE;
919 	*result = res->u.longval;
920 	return 0;
921 }
922 
923 int
924 resource_string_value(const char *name, int unit, char *resname, char **result)
925 {
926 	int error;
927 	struct resource *res;
928 	if ((error = resource_find(name, unit, resname, &res)) != 0)
929 		return error;
930 	if (res->type != RES_STRING)
931 		return EFTYPE;
932 	*result = res->u.stringval;
933 	return 0;
934 }
935 
936 int
937 resource_query_string(int i, char *resname, char *value)
938 {
939 	if (i < 0)
940 		i = 0;
941 	else
942 		i = i + 1;
943 	for (; i < devtab_count; i++)
944 		if (resource_match_string(i, resname, value))
945 			return i;
946 	return -1;
947 }
948 
949 char *
950 resource_query_name(int i)
951 {
952 	return devtab[i].name;
953 }
954 
955 int
956 resource_query_unit(int i)
957 {
958 	return devtab[i].unit;
959 }
960 
961 
962 /*
963  * Some useful method implementations to make life easier for bus drivers.
964  */
965 int
966 bus_generic_attach(device_t dev)
967 {
968     device_t child;
969 
970     for (child = TAILQ_FIRST(&dev->children);
971 	 child; child = TAILQ_NEXT(child, link))
972 	device_probe_and_attach(child);
973 
974     return 0;
975 }
976 
977 int
978 bus_generic_detach(device_t dev)
979 {
980     device_t child;
981     int error;
982 
983     if (dev->state != DS_ATTACHED)
984 	return EBUSY;
985 
986     for (child = TAILQ_FIRST(&dev->children);
987 	 child; child = TAILQ_NEXT(child, link))
988 	if (error = device_detach(child))
989 	    return error;
990 
991     return 0;
992 }
993 
994 int
995 bus_generic_shutdown(device_t dev)
996 {
997     device_t child;
998 
999     for (child = TAILQ_FIRST(&dev->children);
1000 	 child; child = TAILQ_NEXT(child, link))
1001 	DEVICE_SHUTDOWN(child);
1002 
1003     return 0;
1004 }
1005 
1006 void
1007 bus_generic_print_child(device_t dev, device_t child)
1008 {
1009 }
1010 
1011 int
1012 bus_generic_read_ivar(device_t dev, device_t child, int index, u_long* result)
1013 {
1014     return ENOENT;
1015 }
1016 
1017 int
1018 bus_generic_write_ivar(device_t dev, device_t child, int index, u_long value)
1019 {
1020     return ENOENT;
1021 }
1022 
1023 void *
1024 bus_generic_create_intr(device_t dev, device_t child, int irq, driver_intr_t *intr, void *arg)
1025 {
1026     /* Propagate up the bus hierarchy until someone handles it. */
1027     if (dev->parent)
1028 	return BUS_CREATE_INTR(dev->parent, dev, irq, intr, arg);
1029     else
1030 	return NULL;
1031 }
1032 
1033 int
1034 bus_generic_connect_intr(device_t dev, void *ih)
1035 {
1036     /* Propagate up the bus hierarchy until someone handles it. */
1037     if (dev->parent)
1038 	return BUS_CONNECT_INTR(dev->parent, ih);
1039     else
1040 	return EINVAL;
1041 }
1042 
1043 static int root_create_intr(device_t dev, device_t child,
1044 			    driver_intr_t *intr, void *arg)
1045 {
1046     /*
1047      * If an interrupt mapping gets to here something bad has happened.
1048      * Should probably panic.
1049      */
1050     return EINVAL;
1051 }
1052 
1053 static device_method_t root_methods[] = {
1054 	/* Bus interface */
1055 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
1056 	DEVMETHOD(bus_read_ivar,	bus_generic_read_ivar),
1057 	DEVMETHOD(bus_write_ivar,	bus_generic_write_ivar),
1058 	DEVMETHOD(bus_create_intr,	root_create_intr),
1059 
1060 	{ 0, 0 }
1061 };
1062 
1063 static driver_t root_driver = {
1064 	"root",
1065 	root_methods,
1066 	DRIVER_TYPE_MISC,
1067 	1,			/* no softc */
1068 };
1069 
1070 device_t root_bus;
1071 devclass_t root_devclass;
1072 
1073 static int
1074 root_bus_module_handler(module_t mod, modeventtype_t what, void* arg)
1075 {
1076     switch (what) {
1077     case MOD_LOAD:
1078 	compile_methods(&root_driver);
1079 	root_bus = make_device(NULL, "root", 0, NULL);
1080 	root_bus->desc = "System root bus";
1081 	root_bus->ops = root_driver.ops;
1082 	root_bus->driver = &root_driver;
1083 	root_bus->state = DS_ATTACHED;
1084 	root_devclass = devclass_find_internal("root", FALSE);
1085 	return 0;
1086     }
1087 
1088     return 0;
1089 }
1090 
1091 static moduledata_t root_bus_mod = {
1092 	"rootbus",
1093 	root_bus_module_handler,
1094 	0
1095 };
1096 DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
1097 
1098 void
1099 root_bus_configure()
1100 {
1101     device_t dev;
1102 
1103     PDEBUG(("."));
1104 
1105     for (dev = TAILQ_FIRST(&root_bus->children); dev;
1106 	 dev = TAILQ_NEXT(dev, link)) {
1107 	device_probe_and_attach(dev);
1108     }
1109 }
1110 
1111 int
1112 driver_module_handler(module_t mod, modeventtype_t what, void* arg)
1113 {
1114     struct driver_module_data* data = (struct driver_module_data*) arg;
1115     devclass_t bus_devclass = devclass_find_internal(data->busname, TRUE);
1116     int error;
1117 
1118     switch (what) {
1119     case MOD_LOAD:
1120     	PDEBUG(("Loading module: driver %s on bus %s",
1121 		DRIVERNAME(data->driver), data->busname));
1122 	if (error = devclass_add_driver(bus_devclass,
1123 					data->driver))
1124 	    return error;
1125 	*data->devclass =
1126 	    devclass_find_internal(data->driver->name, TRUE);
1127 	break;
1128 
1129     case MOD_UNLOAD:
1130     	PDEBUG(("Unloading module: driver %s from bus %s",
1131 		DRIVERNAME(data->driver), data->busname));
1132 	if (error = devclass_delete_driver(bus_devclass,
1133 					   data->driver))
1134 	    return error;
1135 	break;
1136     }
1137 
1138     if (data->chainevh)
1139 	return data->chainevh(mod, what, data->chainarg);
1140     else
1141 	return 0;
1142 }
1143 
1144 
1145 
1146 #ifdef BUS_DEBUG
1147 
1148 /* the _short versions avoid iteration by not calling anything that prints
1149  * more than oneliners. I love oneliners.
1150  */
1151 
1152 static void
1153 print_method_list(device_method_t *m, int indent)
1154 {
1155 	int i;
1156 
1157 	if (!m)
1158 		return;
1159 
1160 	for (i = 0; m->desc; i++, m++)
1161 		indentprintf(("method %d: %s, offset=%d\n",
1162 			i, m->desc->name, m->desc->offset));
1163 }
1164 
1165 static void
1166 print_device_ops(device_ops_t ops, int indent)
1167 {
1168 	int i;
1169 	int count = 0;
1170 
1171 	if (!ops)
1172 		return;
1173 
1174 	/* we present a list of the methods that are pointing to the
1175 	 * error_method, but ignore the 0'th elements; it is always
1176 	 * error_method.
1177 	 */
1178 	for (i = 1; i < ops->maxoffset; i++) {
1179 		if (ops->methods[i] == error_method) {
1180 			if (count == 0)
1181 				indentprintf(("error_method:"));
1182 			printf(" %d", i);
1183 			count++;
1184 		}
1185 	}
1186 	if (count)
1187 		printf("\n");
1188 
1189 	indentprintf(("(%d method%s, %d valid, %d error_method%s)\n",
1190 		ops->maxoffset-1, (ops->maxoffset-1 == 1? "":"s"),
1191 		ops->maxoffset-1-count,
1192 		count, (count == 1? "":"'s")));
1193 }
1194 
1195 static void
1196 print_device_short(device_t dev, int indent)
1197 {
1198 	if (!dev)
1199 		return;
1200 
1201 	indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%sivars,%ssoftc,busy=%d\n",
1202 		dev->unit, dev->desc,
1203 		(dev->parent? "":"no "),
1204 		(TAILQ_EMPTY(&dev->children)? "no ":""),
1205 		(dev->flags&DF_ENABLED? "enabled,":"disabled,"),
1206 		(dev->flags&DF_FIXEDCLASS? "fixed,":""),
1207 		(dev->flags&DF_WILDCARD? "wildcard,":""),
1208 		(dev->ivars? "":"no "),
1209 		(dev->softc? "":"no "),
1210 		dev->busy));
1211 }
1212 
1213 static void
1214 print_device(device_t dev, int indent)
1215 {
1216 	if (!dev)
1217 		return;
1218 
1219 	print_device_short(dev, indent);
1220 
1221 	indentprintf(("Parent:\n"));
1222 	print_device_short(dev->parent, indent+1);
1223 	indentprintf(("Methods:\n"));
1224 	print_device_ops(dev->ops, indent+1);
1225 	indentprintf(("Driver:\n"));
1226 	print_driver_short(dev->driver, indent+1);
1227 	indentprintf(("Devclass:\n"));
1228 	print_devclass_short(dev->devclass, indent+1);
1229 }
1230 
1231 void
1232 print_device_tree_short(device_t dev, int indent)
1233 /* print the device and all its children (indented) */
1234 {
1235 	device_t child;
1236 
1237 	if (!dev)
1238 		return;
1239 
1240 	print_device_short(dev, indent);
1241 
1242 	for (child = TAILQ_FIRST(&dev->children); child;
1243 		 child = TAILQ_NEXT(child, link))
1244 		print_device_tree_short(child, indent+1);
1245 }
1246 
1247 void
1248 print_device_tree(device_t dev, int indent)
1249 /* print the device and all its children (indented) */
1250 {
1251 	device_t child;
1252 
1253 	if (!dev)
1254 		return;
1255 
1256 	print_device(dev, indent);
1257 
1258 	for (child = TAILQ_FIRST(&dev->children); child;
1259 		 child = TAILQ_NEXT(child, link))
1260 		print_device_tree(child, indent+1);
1261 }
1262 
1263 static void
1264 print_driver_short(driver_t *driver, int indent)
1265 {
1266 	if (!driver)
1267 		return;
1268 
1269 	indentprintf(("driver %s: type = %s%s%s%s, softc size = %d\n",
1270 		driver->name,
1271 		/* yes, I know this looks silly, but going to bed at
1272 		 * two o'clock and having to get up at 7:30 again is silly
1273 		 * as well. As is sticking your head in a bucket of water.
1274 		 */
1275 		(driver->type == DRIVER_TYPE_TTY? "tty":""),
1276 		(driver->type == DRIVER_TYPE_BIO? "bio":""),
1277 		(driver->type == DRIVER_TYPE_NET? "net":""),
1278 		(driver->type == DRIVER_TYPE_MISC? "misc":""),
1279 		driver->softc));
1280 }
1281 
1282 static void
1283 print_driver(driver_t *driver, int indent)
1284 {
1285 	if (!driver)
1286 		return;
1287 
1288 	print_driver_short(driver, indent);
1289 	indentprintf(("Methods:\n"));
1290 	print_method_list(driver->methods, indent+1);
1291 	indentprintf(("Operations:\n"));
1292 	print_device_ops(driver->ops, indent+1);
1293 }
1294 
1295 
1296 static void
1297 print_driver_list(driver_list_t drivers, int indent)
1298 {
1299 	driver_t *driver;
1300 
1301 	for (driver = TAILQ_FIRST(&drivers); driver;
1302 	     driver = TAILQ_NEXT(driver, link))
1303 		print_driver(driver, indent);
1304 }
1305 
1306 static void
1307 print_devclass_short(devclass_t dc, int indent)
1308 {
1309 	device_t dev;
1310 
1311 	if ( !dc )
1312 		return;
1313 
1314 	indentprintf(("devclass %s: max units = %d, next unit = %d\n",
1315 		dc->name, dc->maxunit, dc->nextunit));
1316 }
1317 
1318 static void
1319 print_devclass(devclass_t dc, int indent)
1320 {
1321 	int i;
1322 
1323 	if ( !dc )
1324 		return;
1325 
1326 	print_devclass_short(dc, indent);
1327 	indentprintf(("Drivers:\n"));
1328 	print_driver_list(dc->drivers, indent+1);
1329 
1330 	indentprintf(("Devices:\n"));
1331 	for (i = 0; i < dc->maxunit; i++)
1332 		if (dc->devices[i])
1333 			print_device(dc->devices[i], indent+1);
1334 }
1335 
1336 void
1337 print_devclass_list_short(void)
1338 {
1339 	devclass_t dc;
1340 
1341 	printf("Short listing of devclasses, drivers & devices:\n");
1342 	for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link))
1343 		print_devclass_short(dc, 0);
1344 }
1345 
1346 void
1347 print_devclass_list(void)
1348 {
1349 	devclass_t dc;
1350 
1351 	printf("Full listing of devclasses, drivers & devices:\n");
1352 	for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link))
1353 		print_devclass(dc, 0);
1354 }
1355 
1356 #endif
1357