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