Implement an upcall mechanism to support userland LWKT. This mechanism will
[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.9 2003/11/18 05:10:31 dillon 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_set_devclass(device_t dev, const char *classname)
954 {
955     devclass_t dc;
956
957     if (!classname) {
958         if (dev->devclass)
959             devclass_delete_device(dev->devclass, dev);
960         return 0;
961     }
962
963     if (dev->devclass) {
964         printf("device_set_devclass: device class already set\n");
965         return EINVAL;
966     }
967
968     dc = devclass_find_internal(classname, TRUE);
969     if (!dc)
970         return ENOMEM;
971
972     return devclass_add_device(dc, dev);
973 }
974
975 int
976 device_set_driver(device_t dev, driver_t *driver)
977 {
978     if (dev->state >= DS_ATTACHED)
979         return EBUSY;
980
981     if (dev->driver == driver)
982         return 0;
983
984     if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
985         free(dev->softc, M_BUS);
986         dev->softc = NULL;
987     }
988     kobj_delete((kobj_t) dev, 0);
989     dev->driver = driver;
990     if (driver) {
991         kobj_init((kobj_t) dev, (kobj_class_t) driver);
992         if (!(dev->flags & DF_EXTERNALSOFTC)) {
993             dev->softc = malloc(driver->size, M_BUS, M_NOWAIT | M_ZERO);
994             if (!dev->softc) {
995                 kobj_delete((kobj_t)dev, 0);
996                 kobj_init((kobj_t) dev, &null_class);
997                 dev->driver = NULL;
998                 return ENOMEM;
999             }
1000         }
1001     } else
1002         kobj_init((kobj_t) dev, &null_class);
1003     return 0;
1004 }
1005
1006 int
1007 device_probe_and_attach(device_t dev)
1008 {
1009     device_t bus = dev->parent;
1010     int error = 0;
1011     int hasclass = (dev->devclass != 0);
1012
1013     if (dev->state >= DS_ALIVE)
1014         return 0;
1015
1016     if (dev->flags & DF_ENABLED) {
1017         error = device_probe_child(bus, dev);
1018         if (!error) {
1019             if (!device_is_quiet(dev))
1020                 device_print_child(bus, dev);
1021             error = DEVICE_ATTACH(dev);
1022             if (!error)
1023                 dev->state = DS_ATTACHED;
1024             else {
1025                 printf("device_probe_and_attach: %s%d attach returned %d\n",
1026                        dev->driver->name, dev->unit, error);
1027                 /* Unset the class that was set in device_probe_child */
1028                 if (!hasclass)
1029                     device_set_devclass(dev, 0);
1030                 device_set_driver(dev, NULL);
1031                 dev->state = DS_NOTPRESENT;
1032             }
1033         } else {
1034             if (!(dev->flags & DF_DONENOMATCH)) {
1035                 BUS_PROBE_NOMATCH(bus, dev);
1036                 dev->flags |= DF_DONENOMATCH;
1037             }
1038         }
1039     } else {
1040         if (bootverbose) {
1041             device_print_prettyname(dev);
1042             printf("not probed (disabled)\n");
1043         }
1044     }
1045
1046     return error;
1047 }
1048
1049 int
1050 device_detach(device_t dev)
1051 {
1052     int error;
1053
1054     PDEBUG(("%s", DEVICENAME(dev)));
1055     if (dev->state == DS_BUSY)
1056         return EBUSY;
1057     if (dev->state != DS_ATTACHED)
1058         return 0;
1059
1060     if ((error = DEVICE_DETACH(dev)) != 0)
1061         return error;
1062     device_printf(dev, "detached\n");
1063     if (dev->parent)
1064         BUS_CHILD_DETACHED(dev->parent, dev);
1065
1066     if (!(dev->flags & DF_FIXEDCLASS))
1067         devclass_delete_device(dev->devclass, dev);
1068
1069     dev->state = DS_NOTPRESENT;
1070     device_set_driver(dev, NULL);
1071
1072     return 0;
1073 }
1074
1075 int
1076 device_shutdown(device_t dev)
1077 {
1078     if (dev->state < DS_ATTACHED)
1079         return 0;
1080     return DEVICE_SHUTDOWN(dev);
1081 }
1082
1083 int
1084 device_set_unit(device_t dev, int unit)
1085 {
1086     devclass_t dc;
1087     int err;
1088
1089     dc = device_get_devclass(dev);
1090     if (unit < dc->maxunit && dc->devices[unit])
1091         return EBUSY;
1092     err = devclass_delete_device(dc, dev);
1093     if (err)
1094         return err;
1095     dev->unit = unit;
1096     err = devclass_add_device(dc, dev);
1097     if (err)
1098         return err;
1099     return 0;
1100 }
1101
1102 #ifdef DEVICE_SYSCTLS
1103
1104 /*
1105  * Sysctl nodes for devices.
1106  */
1107
1108 SYSCTL_NODE(_hw, OID_AUTO, devices, CTLFLAG_RW, 0, "A list of all devices");
1109
1110 static int
1111 sysctl_handle_children(SYSCTL_HANDLER_ARGS)
1112 {
1113     device_t dev = arg1;
1114     device_t child;
1115     int first = 1, error = 0;
1116
1117     TAILQ_FOREACH(child, &dev->children, link) {
1118         if (child->nameunit) {
1119             if (!first) {
1120                 error = SYSCTL_OUT(req, ",", 1);
1121                 if (error) return error;
1122             } else {
1123                 first = 0;
1124             }
1125             error = SYSCTL_OUT(req, child->nameunit, strlen(child->nameunit));
1126             if (error) return error;
1127         }
1128     }
1129
1130     error = SYSCTL_OUT(req, "", 1);
1131
1132     return error;
1133 }
1134
1135 static int
1136 sysctl_handle_state(SYSCTL_HANDLER_ARGS)
1137 {
1138     device_t dev = arg1;
1139
1140     switch (dev->state) {
1141     case DS_NOTPRESENT:
1142         return SYSCTL_OUT(req, "notpresent", sizeof("notpresent"));
1143     case DS_ALIVE:
1144         return SYSCTL_OUT(req, "alive", sizeof("alive"));
1145     case DS_ATTACHED:
1146         return SYSCTL_OUT(req, "attached", sizeof("attached"));
1147     case DS_BUSY:
1148         return SYSCTL_OUT(req, "busy", sizeof("busy"));
1149     }
1150
1151     return 0;
1152 }
1153
1154 static void
1155 device_register_oids(device_t dev)
1156 {
1157     struct sysctl_oid* oid;
1158
1159     oid = &dev->oid[0];
1160     bzero(oid, sizeof(*oid));
1161     oid->oid_parent = &sysctl__hw_devices_children;
1162     oid->oid_number = OID_AUTO;
1163     oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW;
1164     oid->oid_arg1 = &dev->oidlist[0];
1165     oid->oid_arg2 = 0;
1166     oid->oid_name = dev->nameunit;
1167     oid->oid_handler = 0;
1168     oid->oid_fmt = "N";
1169     SLIST_INIT(&dev->oidlist[0]);
1170     sysctl_register_oid(oid);
1171
1172     oid = &dev->oid[1];
1173     bzero(oid, sizeof(*oid));
1174     oid->oid_parent = &dev->oidlist[0];
1175     oid->oid_number = OID_AUTO;
1176     oid->oid_kind = CTLTYPE_STRING | CTLFLAG_RD;
1177     oid->oid_arg1 = dev->desc ? dev->desc : "";
1178     oid->oid_arg2 = dev->desc ? strlen(dev->desc) : 0;
1179     oid->oid_name = "desc";
1180     oid->oid_handler = sysctl_handle_string;
1181     oid->oid_fmt = "A";
1182     sysctl_register_oid(oid);
1183
1184     oid = &dev->oid[2];
1185     bzero(oid, sizeof(*oid));
1186     oid->oid_parent = &dev->oidlist[0];
1187     oid->oid_number = OID_AUTO;
1188     oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
1189     oid->oid_arg1 = dev;
1190     oid->oid_arg2 = 0;
1191     oid->oid_name = "children";
1192     oid->oid_handler = sysctl_handle_children;
1193     oid->oid_fmt = "A";
1194     sysctl_register_oid(oid);
1195
1196     oid = &dev->oid[3];
1197     bzero(oid, sizeof(*oid));
1198     oid->oid_parent = &dev->oidlist[0];
1199     oid->oid_number = OID_AUTO;
1200     oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
1201     oid->oid_arg1 = dev;
1202     oid->oid_arg2 = 0;
1203     oid->oid_name = "state";
1204     oid->oid_handler = sysctl_handle_state;
1205     oid->oid_fmt = "A";
1206     sysctl_register_oid(oid);
1207 }
1208
1209 static void
1210 device_unregister_oids(device_t dev)
1211 {
1212     sysctl_unregister_oid(&dev->oid[0]);
1213     sysctl_unregister_oid(&dev->oid[1]);
1214     sysctl_unregister_oid(&dev->oid[2]);
1215 }
1216
1217 #endif
1218
1219 /*======================================*/
1220 /*
1221  * Access functions for device resources.
1222  */
1223
1224 /* Supplied by config(8) in ioconf.c */
1225 extern struct config_device config_devtab[];
1226 extern int devtab_count;
1227
1228 /* Runtime version */
1229 struct config_device *devtab = config_devtab;
1230
1231 static int
1232 resource_new_name(const char *name, int unit)
1233 {
1234         struct config_device *new;
1235
1236         new = malloc((devtab_count + 1) * sizeof(*new), M_TEMP,
1237                      M_NOWAIT | M_ZERO);
1238         if (new == NULL)
1239                 return -1;
1240         if (devtab && devtab_count > 0)
1241                 bcopy(devtab, new, devtab_count * sizeof(*new));
1242         new[devtab_count].name = malloc(strlen(name) + 1, M_TEMP, M_NOWAIT);
1243         if (new[devtab_count].name == NULL) {
1244                 free(new, M_TEMP);
1245                 return -1;
1246         }
1247         strcpy(new[devtab_count].name, name);
1248         new[devtab_count].unit = unit;
1249         new[devtab_count].resource_count = 0;
1250         new[devtab_count].resources = NULL;
1251         devtab = new;
1252         return devtab_count++;
1253 }
1254
1255 static int
1256 resource_new_resname(int j, const char *resname, resource_type type)
1257 {
1258         struct config_resource *new;
1259         int i;
1260
1261         i = devtab[j].resource_count;
1262         new = malloc((i + 1) * sizeof(*new), M_TEMP, M_NOWAIT | M_ZERO);
1263         if (new == NULL)
1264                 return -1;
1265         if (devtab[j].resources && i > 0)
1266                 bcopy(devtab[j].resources, new, i * sizeof(*new));
1267         new[i].name = malloc(strlen(resname) + 1, M_TEMP, M_NOWAIT);
1268         if (new[i].name == NULL) {
1269                 free(new, M_TEMP);
1270                 return -1;
1271         }
1272         strcpy(new[i].name, resname);
1273         new[i].type = type;
1274         if (devtab[j].resources)
1275                 free(devtab[j].resources, M_TEMP);
1276         devtab[j].resources = new;
1277         devtab[j].resource_count = i + 1;
1278         return i;
1279 }
1280
1281 static int
1282 resource_match_string(int i, const char *resname, const char *value)
1283 {
1284         int j;
1285         struct config_resource *res;
1286
1287         for (j = 0, res = devtab[i].resources;
1288              j < devtab[i].resource_count; j++, res++)
1289                 if (!strcmp(res->name, resname)
1290                     && res->type == RES_STRING
1291                     && !strcmp(res->u.stringval, value))
1292                         return j;
1293         return -1;
1294 }
1295
1296 static int
1297 resource_find(const char *name, int unit, const char *resname, 
1298               struct config_resource **result)
1299 {
1300         int i, j;
1301         struct config_resource *res;
1302
1303         /*
1304          * First check specific instances, then generic.
1305          */
1306         for (i = 0; i < devtab_count; i++) {
1307                 if (devtab[i].unit < 0)
1308                         continue;
1309                 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
1310                         res = devtab[i].resources;
1311                         for (j = 0; j < devtab[i].resource_count; j++, res++)
1312                                 if (!strcmp(res->name, resname)) {
1313                                         *result = res;
1314                                         return 0;
1315                                 }
1316                 }
1317         }
1318         for (i = 0; i < devtab_count; i++) {
1319                 if (devtab[i].unit >= 0)
1320                         continue;
1321                 /* XXX should this `&& devtab[i].unit == unit' be here? */
1322                 /* XXX if so, then the generic match does nothing */
1323                 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
1324                         res = devtab[i].resources;
1325                         for (j = 0; j < devtab[i].resource_count; j++, res++)
1326                                 if (!strcmp(res->name, resname)) {
1327                                         *result = res;
1328                                         return 0;
1329                                 }
1330                 }
1331         }
1332         return ENOENT;
1333 }
1334
1335 int
1336 resource_int_value(const char *name, int unit, const char *resname, int *result)
1337 {
1338         int error;
1339         struct config_resource *res;
1340
1341         if ((error = resource_find(name, unit, resname, &res)) != 0)
1342                 return error;
1343         if (res->type != RES_INT)
1344                 return EFTYPE;
1345         *result = res->u.intval;
1346         return 0;
1347 }
1348
1349 int
1350 resource_long_value(const char *name, int unit, const char *resname,
1351                     long *result)
1352 {
1353         int error;
1354         struct config_resource *res;
1355
1356         if ((error = resource_find(name, unit, resname, &res)) != 0)
1357                 return error;
1358         if (res->type != RES_LONG)
1359                 return EFTYPE;
1360         *result = res->u.longval;
1361         return 0;
1362 }
1363
1364 int
1365 resource_string_value(const char *name, int unit, const char *resname,
1366                       char **result)
1367 {
1368         int error;
1369         struct config_resource *res;
1370
1371         if ((error = resource_find(name, unit, resname, &res)) != 0)
1372                 return error;
1373         if (res->type != RES_STRING)
1374                 return EFTYPE;
1375         *result = res->u.stringval;
1376         return 0;
1377 }
1378
1379 int
1380 resource_query_string(int i, const char *resname, const char *value)
1381 {
1382         if (i < 0)
1383                 i = 0;
1384         else
1385                 i = i + 1;
1386         for (; i < devtab_count; i++)
1387                 if (resource_match_string(i, resname, value) >= 0)
1388                         return i;
1389         return -1;
1390 }
1391
1392 int
1393 resource_locate(int i, const char *resname)
1394 {
1395         if (i < 0)
1396                 i = 0;
1397         else
1398                 i = i + 1;
1399         for (; i < devtab_count; i++)
1400                 if (!strcmp(devtab[i].name, resname))
1401                         return i;
1402         return -1;
1403 }
1404
1405 int
1406 resource_count(void)
1407 {
1408         return devtab_count;
1409 }
1410
1411 char *
1412 resource_query_name(int i)
1413 {
1414         return devtab[i].name;
1415 }
1416
1417 int
1418 resource_query_unit(int i)
1419 {
1420         return devtab[i].unit;
1421 }
1422
1423 static int
1424 resource_create(const char *name, int unit, const char *resname,
1425                 resource_type type, struct config_resource **result)
1426 {
1427         int i, j;
1428         struct config_resource *res = NULL;
1429
1430         for (i = 0; i < devtab_count; i++) {
1431                 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
1432                         res = devtab[i].resources;
1433                         break;
1434                 }
1435         }
1436         if (res == NULL) {
1437                 i = resource_new_name(name, unit);
1438                 if (i < 0)
1439                         return ENOMEM;
1440                 res = devtab[i].resources;
1441         }
1442         for (j = 0; j < devtab[i].resource_count; j++, res++) {
1443                 if (!strcmp(res->name, resname)) {
1444                         *result = res;
1445                         return 0;
1446                 }
1447         }
1448         j = resource_new_resname(i, resname, type);
1449         if (j < 0)
1450                 return ENOMEM;
1451         res = &devtab[i].resources[j];
1452         *result = res;
1453         return 0;
1454 }
1455
1456 int
1457 resource_set_int(const char *name, int unit, const char *resname, int value)
1458 {
1459         int error;
1460         struct config_resource *res;
1461
1462         error = resource_create(name, unit, resname, RES_INT, &res);
1463         if (error)
1464                 return error;
1465         if (res->type != RES_INT)
1466                 return EFTYPE;
1467         res->u.intval = value;
1468         return 0;
1469 }
1470
1471 int
1472 resource_set_long(const char *name, int unit, const char *resname, long value)
1473 {
1474         int error;
1475         struct config_resource *res;
1476
1477         error = resource_create(name, unit, resname, RES_LONG, &res);
1478         if (error)
1479                 return error;
1480         if (res->type != RES_LONG)
1481                 return EFTYPE;
1482         res->u.longval = value;
1483         return 0;
1484 }
1485
1486 int
1487 resource_set_string(const char *name, int unit, const char *resname,
1488                     const char *value)
1489 {
1490         int error;
1491         struct config_resource *res;
1492
1493         error = resource_create(name, unit, resname, RES_STRING, &res);
1494         if (error)
1495                 return error;
1496         if (res->type != RES_STRING)
1497                 return EFTYPE;
1498         if (res->u.stringval)
1499                 free(res->u.stringval, M_TEMP);
1500         res->u.stringval = malloc(strlen(value) + 1, M_TEMP, M_NOWAIT);
1501         if (res->u.stringval == NULL)
1502                 return ENOMEM;
1503         strcpy(res->u.stringval, value);
1504         return 0;
1505 }
1506
1507
1508 static void
1509 resource_cfgload(void *dummy __unused)
1510 {
1511         struct config_resource *res, *cfgres;
1512         int i, j;
1513         int error;
1514         char *name, *resname;
1515         int unit;
1516         resource_type type;
1517         char *stringval;
1518         int config_devtab_count;
1519
1520         config_devtab_count = devtab_count;
1521         devtab = NULL;
1522         devtab_count = 0;
1523
1524         for (i = 0; i < config_devtab_count; i++) {
1525                 name = config_devtab[i].name;
1526                 unit = config_devtab[i].unit;
1527
1528                 for (j = 0; j < config_devtab[i].resource_count; j++) {
1529                         cfgres = config_devtab[i].resources;
1530                         resname = cfgres[j].name;
1531                         type = cfgres[j].type;
1532                         error = resource_create(name, unit, resname, type,
1533                                                 &res);
1534                         if (error) {
1535                                 printf("create resource %s%d: error %d\n",
1536                                         name, unit, error);
1537                                 continue;
1538                         }
1539                         if (res->type != type) {
1540                                 printf("type mismatch %s%d: %d != %d\n",
1541                                         name, unit, res->type, type);
1542                                 continue;
1543                         }
1544                         switch (type) {
1545                         case RES_INT:
1546                                 res->u.intval = cfgres[j].u.intval;
1547                                 break;
1548                         case RES_LONG:
1549                                 res->u.longval = cfgres[j].u.longval;
1550                                 break;
1551                         case RES_STRING:
1552                                 if (res->u.stringval)
1553                                         free(res->u.stringval, M_TEMP);
1554                                 stringval = cfgres[j].u.stringval;
1555                                 res->u.stringval = malloc(strlen(stringval) + 1,
1556                                                           M_TEMP, M_NOWAIT);
1557                                 if (res->u.stringval == NULL)
1558                                         break;
1559                                 strcpy(res->u.stringval, stringval);
1560                                 break;
1561                         default:
1562                                 panic("unknown resource type %d\n", type);
1563                         }
1564                 }
1565         }
1566 }
1567 SYSINIT(cfgload, SI_SUB_KMEM, SI_ORDER_ANY + 50, resource_cfgload, 0)
1568
1569
1570 /*======================================*/
1571 /*
1572  * Some useful method implementations to make life easier for bus drivers.
1573  */
1574
1575 void
1576 resource_list_init(struct resource_list *rl)
1577 {
1578         SLIST_INIT(rl);
1579 }
1580
1581 void
1582 resource_list_free(struct resource_list *rl)
1583 {
1584     struct resource_list_entry *rle;
1585
1586     while ((rle = SLIST_FIRST(rl)) != NULL) {
1587         if (rle->res)
1588             panic("resource_list_free: resource entry is busy");
1589         SLIST_REMOVE_HEAD(rl, link);
1590         free(rle, M_BUS);
1591     }
1592 }
1593
1594 void
1595 resource_list_add(struct resource_list *rl,
1596                   int type, int rid,
1597                   u_long start, u_long end, u_long count)
1598 {
1599     struct resource_list_entry *rle;
1600
1601     rle = resource_list_find(rl, type, rid);
1602     if (!rle) {
1603         rle = malloc(sizeof(struct resource_list_entry), M_BUS, M_NOWAIT);
1604         if (!rle)
1605             panic("resource_list_add: can't record entry");
1606         SLIST_INSERT_HEAD(rl, rle, link);
1607         rle->type = type;
1608         rle->rid = rid;
1609         rle->res = NULL;
1610     }
1611
1612     if (rle->res)
1613         panic("resource_list_add: resource entry is busy");
1614
1615     rle->start = start;
1616     rle->end = end;
1617     rle->count = count;
1618 }
1619
1620 struct resource_list_entry*
1621 resource_list_find(struct resource_list *rl,
1622                    int type, int rid)
1623 {
1624     struct resource_list_entry *rle;
1625
1626     SLIST_FOREACH(rle, rl, link)
1627         if (rle->type == type && rle->rid == rid)
1628             return rle;
1629     return NULL;
1630 }
1631
1632 void
1633 resource_list_delete(struct resource_list *rl,
1634                      int type, int rid)
1635 {
1636     struct resource_list_entry *rle = resource_list_find(rl, type, rid);
1637
1638     if (rle) {
1639         SLIST_REMOVE(rl, rle, resource_list_entry, link);
1640         free(rle, M_BUS);
1641     }
1642 }
1643
1644 struct resource *
1645 resource_list_alloc(struct resource_list *rl,
1646                     device_t bus, device_t child,
1647                     int type, int *rid,
1648                     u_long start, u_long end,
1649                     u_long count, u_int flags)
1650 {
1651     struct resource_list_entry *rle = 0;
1652     int passthrough = (device_get_parent(child) != bus);
1653     int isdefault = (start == 0UL && end == ~0UL);
1654
1655     if (passthrough) {
1656         return BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1657                                   type, rid,
1658                                   start, end, count, flags);
1659     }
1660
1661     rle = resource_list_find(rl, type, *rid);
1662
1663     if (!rle)
1664         return 0;               /* no resource of that type/rid */
1665     if (rle->res)
1666         panic("resource_list_alloc: resource entry is busy");
1667
1668     if (isdefault) {
1669         start = rle->start;
1670         count = max(count, rle->count);
1671         end = max(rle->end, start + count - 1);
1672     }
1673
1674     rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1675                                   type, rid, start, end, count, flags);
1676
1677     /*
1678      * Record the new range.
1679      */
1680     if (rle->res) {
1681             rle->start = rman_get_start(rle->res);
1682             rle->end = rman_get_end(rle->res);
1683             rle->count = count;
1684     }
1685
1686     return rle->res;
1687 }
1688
1689 int
1690 resource_list_release(struct resource_list *rl,
1691                       device_t bus, device_t child,
1692                       int type, int rid, struct resource *res)
1693 {
1694     struct resource_list_entry *rle = 0;
1695     int passthrough = (device_get_parent(child) != bus);
1696     int error;
1697
1698     if (passthrough) {
1699         return BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1700                                     type, rid, res);
1701     }
1702
1703     rle = resource_list_find(rl, type, rid);
1704
1705     if (!rle)
1706         panic("resource_list_release: can't find resource");
1707     if (!rle->res)
1708         panic("resource_list_release: resource entry is not busy");
1709
1710     error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1711                                  type, rid, res);
1712     if (error)
1713         return error;
1714
1715     rle->res = NULL;
1716     return 0;
1717 }
1718
1719 int
1720 resource_list_print_type(struct resource_list *rl, const char *name, int type,
1721     const char *format)
1722 {
1723         struct resource_list_entry *rle;
1724         int printed, retval;
1725
1726         printed = 0;
1727         retval = 0;
1728         /* Yes, this is kinda cheating */
1729         SLIST_FOREACH(rle, rl, link) {
1730                 if (rle->type == type) {
1731                         if (printed == 0)
1732                                 retval += printf(" %s ", name);
1733                         else
1734                                 retval += printf(",");
1735                         printed++;
1736                         retval += printf(format, rle->start);
1737                         if (rle->count > 1) {
1738                                 retval += printf("-");
1739                                 retval += printf(format, rle->start +
1740                                                  rle->count - 1);
1741                         }
1742                 }
1743         }
1744         return (retval);
1745 }
1746
1747 /*
1748  * Call DEVICE_IDENTIFY for each driver.
1749  */
1750 int
1751 bus_generic_probe(device_t dev)
1752 {
1753     devclass_t dc = dev->devclass;
1754     driverlink_t dl;
1755
1756     TAILQ_FOREACH(dl, &dc->drivers, link) {
1757         DEVICE_IDENTIFY(dl->driver, dev);
1758     }
1759
1760     return 0;
1761 }
1762
1763 int
1764 bus_generic_attach(device_t dev)
1765 {
1766     device_t child;
1767
1768     TAILQ_FOREACH(child, &dev->children, link) {
1769         device_probe_and_attach(child);
1770     }
1771
1772     return 0;
1773 }
1774
1775 int
1776 bus_generic_detach(device_t dev)
1777 {
1778     device_t child;
1779     int error;
1780
1781     if (dev->state != DS_ATTACHED)
1782         return EBUSY;
1783
1784     TAILQ_FOREACH(child, &dev->children, link) {
1785         if ((error = device_detach(child)) != 0)
1786             return error;
1787     }
1788
1789     return 0;
1790 }
1791
1792 int
1793 bus_generic_shutdown(device_t dev)
1794 {
1795     device_t child;
1796
1797     TAILQ_FOREACH(child, &dev->children, link) {
1798         device_shutdown(child);
1799     }
1800
1801     return 0;
1802 }
1803
1804 int
1805 bus_generic_suspend(device_t dev)
1806 {
1807         int             error;
1808         device_t        child, child2;
1809
1810         TAILQ_FOREACH(child, &dev->children, link) {
1811                 error = DEVICE_SUSPEND(child);
1812                 if (error) {
1813                         for (child2 = TAILQ_FIRST(&dev->children);
1814                              child2 && child2 != child; 
1815                              child2 = TAILQ_NEXT(child2, link))
1816                                 DEVICE_RESUME(child2);
1817                         return (error);
1818                 }
1819         }
1820         return 0;
1821 }
1822
1823 int
1824 bus_generic_resume(device_t dev)
1825 {
1826         device_t        child;
1827
1828         TAILQ_FOREACH(child, &dev->children, link) {
1829                 DEVICE_RESUME(child);
1830                 /* if resume fails, there's nothing we can usefully do... */
1831         }
1832         return 0;
1833 }
1834
1835 int
1836 bus_print_child_header (device_t dev, device_t child)
1837 {
1838         int     retval = 0;
1839
1840         if (device_get_desc(child)) { 
1841                 retval += device_printf(child, "<%s>",
1842                                        device_get_desc(child));      
1843         } else {
1844                 retval += printf("%s", device_get_nameunit(child));
1845         }
1846
1847         return (retval);
1848 }
1849
1850 int
1851 bus_print_child_footer (device_t dev, device_t child)
1852 {
1853         return(printf(" on %s\n", device_get_nameunit(dev)));
1854 }
1855
1856 int
1857 bus_generic_print_child(device_t dev, device_t child)
1858 {
1859         int     retval = 0;
1860
1861         retval += bus_print_child_header(dev, child);
1862         retval += bus_print_child_footer(dev, child);
1863
1864         return (retval);
1865 }
1866
1867 int
1868 bus_generic_read_ivar(device_t dev, device_t child, int index, 
1869                       uintptr_t * result)
1870 {
1871     return ENOENT;
1872 }
1873
1874 int
1875 bus_generic_write_ivar(device_t dev, device_t child, int index, 
1876                        uintptr_t value)
1877 {
1878     return ENOENT;
1879 }
1880
1881 void
1882 bus_generic_driver_added(device_t dev, driver_t *driver)
1883 {
1884     device_t child;
1885
1886     DEVICE_IDENTIFY(driver, dev);
1887     TAILQ_FOREACH(child, &dev->children, link) {
1888         if (child->state == DS_NOTPRESENT)
1889             device_probe_and_attach(child);
1890     }
1891 }
1892
1893 int
1894 bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq, 
1895                        int flags, driver_intr_t *intr, void *arg,
1896                        void **cookiep)
1897 {
1898         /* Propagate up the bus hierarchy until someone handles it. */
1899         if (dev->parent)
1900                 return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
1901                                        intr, arg, cookiep));
1902         else
1903                 return (EINVAL);
1904 }
1905
1906 int
1907 bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
1908                           void *cookie)
1909 {
1910         /* Propagate up the bus hierarchy until someone handles it. */
1911         if (dev->parent)
1912                 return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
1913         else
1914                 return (EINVAL);
1915 }
1916
1917 struct resource *
1918 bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
1919                            u_long start, u_long end, u_long count, u_int flags)
1920 {
1921         /* Propagate up the bus hierarchy until someone handles it. */
1922         if (dev->parent)
1923                 return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid, 
1924                                            start, end, count, flags));
1925         else
1926                 return (NULL);
1927 }
1928
1929 int
1930 bus_generic_release_resource(device_t dev, device_t child, int type, int rid,
1931                              struct resource *r)
1932 {
1933         /* Propagate up the bus hierarchy until someone handles it. */
1934         if (dev->parent)
1935                 return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid, 
1936                                              r));
1937         else
1938                 return (EINVAL);
1939 }
1940
1941 int
1942 bus_generic_activate_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_ACTIVATE_RESOURCE(dev->parent, child, type, rid, 
1948                                               r));
1949         else
1950                 return (EINVAL);
1951 }
1952
1953 int
1954 bus_generic_deactivate_resource(device_t dev, device_t child, int type,
1955                                 int rid, struct resource *r)
1956 {
1957         /* Propagate up the bus hierarchy until someone handles it. */
1958         if (dev->parent)
1959                 return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
1960                                                 r));
1961         else
1962                 return (EINVAL);
1963 }
1964
1965 /*
1966  * Some convenience functions to make it easier for drivers to use the
1967  * resource-management functions.  All these really do is hide the
1968  * indirection through the parent's method table, making for slightly
1969  * less-wordy code.  In the future, it might make sense for this code
1970  * to maintain some sort of a list of resources allocated by each device.
1971  */
1972 struct resource *
1973 bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end,
1974                    u_long count, u_int flags)
1975 {
1976         if (dev->parent == 0)
1977                 return (0);
1978         return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
1979                                    count, flags));
1980 }
1981
1982 int
1983 bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
1984 {
1985         if (dev->parent == 0)
1986                 return (EINVAL);
1987         return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
1988 }
1989
1990 int
1991 bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
1992 {
1993         if (dev->parent == 0)
1994                 return (EINVAL);
1995         return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
1996 }
1997
1998 int
1999 bus_release_resource(device_t dev, int type, int rid, struct resource *r)
2000 {
2001         if (dev->parent == 0)
2002                 return (EINVAL);
2003         return (BUS_RELEASE_RESOURCE(dev->parent, dev,
2004                                      type, rid, r));
2005 }
2006
2007 int
2008 bus_setup_intr(device_t dev, struct resource *r, int flags,
2009                driver_intr_t handler, void *arg, void **cookiep)
2010 {
2011         if (dev->parent == 0)
2012                 return (EINVAL);
2013         return (BUS_SETUP_INTR(dev->parent, dev, r, flags,
2014                                handler, arg, cookiep));
2015 }
2016
2017 int
2018 bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
2019 {
2020         if (dev->parent == 0)
2021                 return (EINVAL);
2022         return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
2023 }
2024
2025 int
2026 bus_set_resource(device_t dev, int type, int rid,
2027                  u_long start, u_long count)
2028 {
2029         return BUS_SET_RESOURCE(device_get_parent(dev), dev, type, rid,
2030                                 start, count);
2031 }
2032
2033 int
2034 bus_get_resource(device_t dev, int type, int rid,
2035                  u_long *startp, u_long *countp)
2036 {
2037         return BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2038                                 startp, countp);
2039 }
2040
2041 u_long
2042 bus_get_resource_start(device_t dev, int type, int rid)
2043 {
2044         u_long start, count;
2045         int error;
2046
2047         error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2048                                  &start, &count);
2049         if (error)
2050                 return 0;
2051         return start;
2052 }
2053
2054 u_long
2055 bus_get_resource_count(device_t dev, int type, int rid)
2056 {
2057         u_long start, count;
2058         int error;
2059
2060         error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2061                                  &start, &count);
2062         if (error)
2063                 return 0;
2064         return count;
2065 }
2066
2067 void
2068 bus_delete_resource(device_t dev, int type, int rid)
2069 {
2070         BUS_DELETE_RESOURCE(device_get_parent(dev), dev, type, rid);
2071 }
2072
2073 static int
2074 root_print_child(device_t dev, device_t child)
2075 {
2076         return (0);
2077 }
2078
2079 static int
2080 root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg,
2081                 void **cookiep)
2082 {
2083         /*
2084          * If an interrupt mapping gets to here something bad has happened.
2085          */
2086         panic("root_setup_intr");
2087 }
2088
2089 static kobj_method_t root_methods[] = {
2090         /* Device interface */
2091         KOBJMETHOD(device_shutdown,     bus_generic_shutdown),
2092         KOBJMETHOD(device_suspend,      bus_generic_suspend),
2093         KOBJMETHOD(device_resume,       bus_generic_resume),
2094
2095         /* Bus interface */
2096         KOBJMETHOD(bus_print_child,     root_print_child),
2097         KOBJMETHOD(bus_read_ivar,       bus_generic_read_ivar),
2098         KOBJMETHOD(bus_write_ivar,      bus_generic_write_ivar),
2099         KOBJMETHOD(bus_setup_intr,      root_setup_intr),
2100
2101         { 0, 0 }
2102 };
2103
2104 static driver_t root_driver = {
2105         "root",
2106         root_methods,
2107         1,                      /* no softc */
2108 };
2109
2110 device_t        root_bus;
2111 devclass_t      root_devclass;
2112
2113 static int
2114 root_bus_module_handler(module_t mod, int what, void* arg)
2115 {
2116     switch (what) {
2117     case MOD_LOAD:
2118         kobj_class_compile((kobj_class_t) &root_driver);
2119         root_bus = make_device(NULL, "root", 0);
2120         root_bus->desc = "System root bus";
2121         kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
2122         root_bus->driver = &root_driver;
2123         root_bus->state = DS_ATTACHED;
2124         root_devclass = devclass_find_internal("root", FALSE);
2125         return 0;
2126
2127     case MOD_SHUTDOWN:
2128         device_shutdown(root_bus);
2129         return 0;
2130     }
2131
2132     return 0;
2133 }
2134
2135 static moduledata_t root_bus_mod = {
2136         "rootbus",
2137         root_bus_module_handler,
2138         0
2139 };
2140 DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
2141
2142 void
2143 root_bus_configure(void)
2144 {
2145     device_t dev;
2146
2147     PDEBUG(("."));
2148
2149     TAILQ_FOREACH(dev, &root_bus->children, link) {
2150             device_probe_and_attach(dev);
2151     }
2152 }
2153
2154 int
2155 driver_module_handler(module_t mod, int what, void *arg)
2156 {
2157         int error, i;
2158         struct driver_module_data *dmd;
2159         devclass_t bus_devclass;
2160
2161         dmd = (struct driver_module_data *)arg;
2162         bus_devclass = devclass_find_internal(dmd->dmd_busname, TRUE);
2163         error = 0;
2164
2165         switch (what) {
2166         case MOD_LOAD:
2167                 if (dmd->dmd_chainevh)
2168                         error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
2169
2170                 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
2171                         PDEBUG(("Loading module: driver %s on bus %s",
2172                                 DRIVERNAME(dmd->dmd_drivers[i]), 
2173                                 dmd->dmd_busname));
2174                         error = devclass_add_driver(bus_devclass,
2175                                                     dmd->dmd_drivers[i]);
2176                 }
2177                 if (error)
2178                         break;
2179
2180                 /*
2181                  * The drivers loaded in this way are assumed to all
2182                  * implement the same devclass.
2183                  */
2184                 *dmd->dmd_devclass =
2185                         devclass_find_internal(dmd->dmd_drivers[0]->name,
2186                                                TRUE);
2187                 break;
2188
2189         case MOD_UNLOAD:
2190                 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
2191                         PDEBUG(("Unloading module: driver %s from bus %s",
2192                                 DRIVERNAME(dmd->dmd_drivers[i]), 
2193                                 dmd->dmd_busname));
2194                         error = devclass_delete_driver(bus_devclass,
2195                                                        dmd->dmd_drivers[i]);
2196                 }
2197
2198                 if (!error && dmd->dmd_chainevh)
2199                         error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
2200                 break;
2201         }
2202
2203         return (error);
2204 }
2205
2206 #ifdef BUS_DEBUG
2207
2208 /* the _short versions avoid iteration by not calling anything that prints
2209  * more than oneliners. I love oneliners.
2210  */
2211
2212 static void
2213 print_device_short(device_t dev, int indent)
2214 {
2215         if (!dev)
2216                 return;
2217
2218         indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
2219                 dev->unit, dev->desc,
2220                 (dev->parent? "":"no "),
2221                 (TAILQ_EMPTY(&dev->children)? "no ":""),
2222                 (dev->flags&DF_ENABLED? "enabled,":"disabled,"),
2223                 (dev->flags&DF_FIXEDCLASS? "fixed,":""),
2224                 (dev->flags&DF_WILDCARD? "wildcard,":""),
2225                 (dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
2226                 (dev->ivars? "":"no "),
2227                 (dev->softc? "":"no "),
2228                 dev->busy));
2229 }
2230
2231 static void
2232 print_device(device_t dev, int indent)
2233 {
2234         if (!dev)
2235                 return;
2236
2237         print_device_short(dev, indent);
2238
2239         indentprintf(("Parent:\n"));
2240         print_device_short(dev->parent, indent+1);
2241         indentprintf(("Driver:\n"));
2242         print_driver_short(dev->driver, indent+1);
2243         indentprintf(("Devclass:\n"));
2244         print_devclass_short(dev->devclass, indent+1);
2245 }
2246
2247 void
2248 print_device_tree_short(device_t dev, int indent)
2249 /* print the device and all its children (indented) */
2250 {
2251         device_t child;
2252
2253         if (!dev)
2254                 return;
2255
2256         print_device_short(dev, indent);
2257
2258         TAILQ_FOREACH(child, &dev->children, link) {
2259                 print_device_tree_short(child, indent+1);
2260         }
2261 }
2262
2263 void
2264 print_device_tree(device_t dev, int indent)
2265 /* print the device and all its children (indented) */
2266 {
2267         device_t child;
2268
2269         if (!dev)
2270                 return;
2271
2272         print_device(dev, indent);
2273
2274         TAILQ_FOREACH(child, &dev->children, link) {
2275                 print_device_tree(child, indent+1);
2276         }
2277 }
2278
2279 static void
2280 print_driver_short(driver_t *driver, int indent)
2281 {
2282         if (!driver)
2283                 return;
2284
2285         indentprintf(("driver %s: softc size = %d\n",
2286                 driver->name, driver->size));
2287 }
2288
2289 static void
2290 print_driver(driver_t *driver, int indent)
2291 {
2292         if (!driver)
2293                 return;
2294
2295         print_driver_short(driver, indent);
2296 }
2297
2298
2299 static void
2300 print_driver_list(driver_list_t drivers, int indent)
2301 {
2302         driverlink_t driver;
2303
2304         TAILQ_FOREACH(driver, &drivers, link) {
2305                 print_driver(driver->driver, indent);
2306         }
2307 }
2308
2309 static void
2310 print_devclass_short(devclass_t dc, int indent)
2311 {
2312         if ( !dc )
2313                 return;
2314
2315         indentprintf(("devclass %s: max units = %d\n",
2316                 dc->name, dc->maxunit));
2317 }
2318
2319 static void
2320 print_devclass(devclass_t dc, int indent)
2321 {
2322         int i;
2323
2324         if ( !dc )
2325                 return;
2326
2327         print_devclass_short(dc, indent);
2328         indentprintf(("Drivers:\n"));
2329         print_driver_list(dc->drivers, indent+1);
2330
2331         indentprintf(("Devices:\n"));
2332         for (i = 0; i < dc->maxunit; i++)
2333                 if (dc->devices[i])
2334                         print_device(dc->devices[i], indent+1);
2335 }
2336
2337 void
2338 print_devclass_list_short(void)
2339 {
2340         devclass_t dc;
2341
2342         printf("Short listing of devclasses, drivers & devices:\n");
2343         TAILQ_FOREACH(dc, &devclasses, link) {
2344                 print_devclass_short(dc, 0);
2345         }
2346 }
2347
2348 void
2349 print_devclass_list(void)
2350 {
2351         devclass_t dc;
2352
2353         printf("Full listing of devclasses, drivers & devices:\n");
2354         TAILQ_FOREACH(dc, &devclasses, link) {
2355                 print_devclass(dc, 0);
2356         }
2357 }
2358
2359 #endif