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