]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/subr_bus.c
This commit was generated by cvs2svn to compensate for changes in r95415,
[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) && driver->size > 0) {
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 int
1140 resource_list_add_next(struct resource_list *rl, int type,
1141     u_long start, u_long end, u_long count)
1142 {
1143         int     rid;
1144
1145         rid = 0;
1146         while (resource_list_find(rl, type, rid)) rid++;
1147         resource_list_add(rl, type, rid, start, end, count);
1148
1149         return (rid);
1150 }
1151
1152 void
1153 resource_list_add(struct resource_list *rl, int type, int rid,
1154     u_long start, u_long end, u_long count)
1155 {
1156         struct resource_list_entry *rle;
1157
1158         rle = resource_list_find(rl, type, rid);
1159         if (!rle) {
1160                 rle = malloc(sizeof(struct resource_list_entry), M_BUS,
1161                     M_NOWAIT);
1162                 if (!rle)
1163                         panic("resource_list_add: can't record entry");
1164                 SLIST_INSERT_HEAD(rl, rle, link);
1165                 rle->type = type;
1166                 rle->rid = rid;
1167                 rle->res = NULL;
1168         }
1169
1170         if (rle->res)
1171                 panic("resource_list_add: resource entry is busy");
1172
1173         rle->start = start;
1174         rle->end = end;
1175         rle->count = count;
1176 }
1177
1178 struct resource_list_entry *
1179 resource_list_find(struct resource_list *rl, int type, int rid)
1180 {
1181         struct resource_list_entry *rle;
1182
1183         SLIST_FOREACH(rle, rl, link) {
1184                 if (rle->type == type && rle->rid == rid)
1185                         return (rle);
1186         }
1187         return (NULL);
1188 }
1189
1190 void
1191 resource_list_delete(struct resource_list *rl, int type, int rid)
1192 {
1193         struct resource_list_entry *rle = resource_list_find(rl, type, rid);
1194
1195         if (rle) {
1196                 if (rle->res != NULL)
1197                         panic("resource_list_delete: resource has not been released");
1198                 SLIST_REMOVE(rl, rle, resource_list_entry, link);
1199                 free(rle, M_BUS);
1200         }
1201 }
1202
1203 struct resource *
1204 resource_list_alloc(struct resource_list *rl, device_t bus, device_t child,
1205     int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
1206 {
1207         struct resource_list_entry *rle = 0;
1208         int passthrough = (device_get_parent(child) != bus);
1209         int isdefault = (start == 0UL && end == ~0UL);
1210
1211         if (passthrough) {
1212                 return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1213                     type, rid, start, end, count, flags));
1214         }
1215
1216         rle = resource_list_find(rl, type, *rid);
1217
1218         if (!rle)
1219                 return (NULL);          /* no resource of that type/rid */
1220
1221         if (rle->res)
1222                 panic("resource_list_alloc: resource entry is busy");
1223
1224         if (isdefault) {
1225                 start = rle->start;
1226                 count = ulmax(count, rle->count);
1227                 end = ulmax(rle->end, start + count - 1);
1228         }
1229
1230         rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1231             type, rid, start, end, count, flags);
1232
1233         /*
1234          * Record the new range.
1235          */
1236         if (rle->res) {
1237                 rle->start = rman_get_start(rle->res);
1238                 rle->end = rman_get_end(rle->res);
1239                 rle->count = count;
1240         }
1241
1242         return (rle->res);
1243 }
1244
1245 int
1246 resource_list_release(struct resource_list *rl, device_t bus, device_t child,
1247     int type, int rid, struct resource *res)
1248 {
1249         struct resource_list_entry *rle = 0;
1250         int passthrough = (device_get_parent(child) != bus);
1251         int error;
1252
1253         if (passthrough) {
1254                 return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1255                     type, rid, res));
1256         }
1257
1258         rle = resource_list_find(rl, type, rid);
1259
1260         if (!rle)
1261                 panic("resource_list_release: can't find resource");
1262         if (!rle->res)
1263                 panic("resource_list_release: resource entry is not busy");
1264
1265         error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1266             type, rid, res);
1267         if (error)
1268                 return (error);
1269
1270         rle->res = NULL;
1271         return (0);
1272 }
1273
1274 int
1275 resource_list_print_type(struct resource_list *rl, const char *name, int type,
1276     const char *format)
1277 {
1278         struct resource_list_entry *rle;
1279         int printed, retval;
1280
1281         printed = 0;
1282         retval = 0;
1283         /* Yes, this is kinda cheating */
1284         SLIST_FOREACH(rle, rl, link) {
1285                 if (rle->type == type) {
1286                         if (printed == 0)
1287                                 retval += printf(" %s ", name);
1288                         else
1289                                 retval += printf(",");
1290                         printed++;
1291                         retval += printf(format, rle->start);
1292                         if (rle->count > 1) {
1293                                 retval += printf("-");
1294                                 retval += printf(format, rle->start +
1295                                                  rle->count - 1);
1296                         }
1297                 }
1298         }
1299         return (retval);
1300 }
1301
1302 /*
1303  * Call DEVICE_IDENTIFY for each driver.
1304  */
1305 int
1306 bus_generic_probe(device_t dev)
1307 {
1308         devclass_t dc = dev->devclass;
1309         driverlink_t dl;
1310
1311         TAILQ_FOREACH(dl, &dc->drivers, link) {
1312                 DEVICE_IDENTIFY(dl->driver, dev);
1313         }
1314
1315         return (0);
1316 }
1317
1318 int
1319 bus_generic_attach(device_t dev)
1320 {
1321         device_t child;
1322
1323         TAILQ_FOREACH(child, &dev->children, link) {
1324                 device_probe_and_attach(child);
1325         }
1326
1327         return (0);
1328 }
1329
1330 int
1331 bus_generic_detach(device_t dev)
1332 {
1333         device_t child;
1334         int error;
1335
1336         if (dev->state != DS_ATTACHED)
1337                 return (EBUSY);
1338
1339         TAILQ_FOREACH(child, &dev->children, link) {
1340                 if ((error = device_detach(child)) != 0)
1341                         return (error);
1342         }
1343
1344         return (0);
1345 }
1346
1347 int
1348 bus_generic_shutdown(device_t dev)
1349 {
1350         device_t child;
1351
1352         TAILQ_FOREACH(child, &dev->children, link) {
1353                 device_shutdown(child);
1354         }
1355
1356         return (0);
1357 }
1358
1359 int
1360 bus_generic_suspend(device_t dev)
1361 {
1362         int             error;
1363         device_t        child, child2;
1364
1365         TAILQ_FOREACH(child, &dev->children, link) {
1366                 error = DEVICE_SUSPEND(child);
1367                 if (error) {
1368                         for (child2 = TAILQ_FIRST(&dev->children);
1369                              child2 && child2 != child;
1370                              child2 = TAILQ_NEXT(child2, link))
1371                                 DEVICE_RESUME(child2);
1372                         return (error);
1373                 }
1374         }
1375         return (0);
1376 }
1377
1378 int
1379 bus_generic_resume(device_t dev)
1380 {
1381         device_t        child;
1382
1383         TAILQ_FOREACH(child, &dev->children, link) {
1384                 DEVICE_RESUME(child);
1385                 /* if resume fails, there's nothing we can usefully do... */
1386         }
1387         return (0);
1388 }
1389
1390 int
1391 bus_print_child_header (device_t dev, device_t child)
1392 {
1393         int     retval = 0;
1394
1395         if (device_get_desc(child)) {
1396                 retval += device_printf(child, "<%s>", device_get_desc(child));
1397         } else {
1398                 retval += printf("%s", device_get_nameunit(child));
1399         }
1400
1401         return (retval);
1402 }
1403
1404 int
1405 bus_print_child_footer (device_t dev, device_t child)
1406 {
1407         return (printf(" on %s\n", device_get_nameunit(dev)));
1408 }
1409
1410 int
1411 bus_generic_print_child(device_t dev, device_t child)
1412 {
1413         int     retval = 0;
1414
1415         retval += bus_print_child_header(dev, child);
1416         retval += bus_print_child_footer(dev, child);
1417
1418         return (retval);
1419 }
1420
1421 int
1422 bus_generic_read_ivar(device_t dev, device_t child, int index,
1423     uintptr_t * result)
1424 {
1425         return (ENOENT);
1426 }
1427
1428 int
1429 bus_generic_write_ivar(device_t dev, device_t child, int index,
1430     uintptr_t value)
1431 {
1432         return (ENOENT);
1433 }
1434
1435 struct resource_list *
1436 bus_generic_get_resource_list (device_t dev, device_t child)
1437 {
1438         return (NULL);
1439 }
1440
1441 void
1442 bus_generic_driver_added(device_t dev, driver_t *driver)
1443 {
1444         device_t child;
1445
1446         DEVICE_IDENTIFY(driver, dev);
1447         TAILQ_FOREACH(child, &dev->children, link) {
1448                 if (child->state == DS_NOTPRESENT)
1449                         device_probe_and_attach(child);
1450         }
1451 }
1452
1453 int
1454 bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1455     int flags, driver_intr_t *intr, void *arg, void **cookiep)
1456 {
1457         /* Propagate up the bus hierarchy until someone handles it. */
1458         if (dev->parent)
1459                 return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
1460                     intr, arg, cookiep));
1461         return (EINVAL);
1462 }
1463
1464 int
1465 bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
1466     void *cookie)
1467 {
1468         /* Propagate up the bus hierarchy until someone handles it. */
1469         if (dev->parent)
1470                 return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
1471         return (EINVAL);
1472 }
1473
1474 struct resource *
1475 bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
1476     u_long start, u_long end, u_long count, u_int flags)
1477 {
1478         /* Propagate up the bus hierarchy until someone handles it. */
1479         if (dev->parent)
1480                 return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid,
1481                     start, end, count, flags));
1482         return (NULL);
1483 }
1484
1485 int
1486 bus_generic_release_resource(device_t dev, device_t child, int type, int rid,
1487     struct resource *r)
1488 {
1489         /* Propagate up the bus hierarchy until someone handles it. */
1490         if (dev->parent)
1491                 return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid,
1492                     r));
1493         return (EINVAL);
1494 }
1495
1496 int
1497 bus_generic_activate_resource(device_t dev, device_t child, int type, int rid,
1498     struct resource *r)
1499 {
1500         /* Propagate up the bus hierarchy until someone handles it. */
1501         if (dev->parent)
1502                 return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid,
1503                     r));
1504         return (EINVAL);
1505 }
1506
1507 int
1508 bus_generic_deactivate_resource(device_t dev, device_t child, int type,
1509     int rid, struct resource *r)
1510 {
1511         /* Propagate up the bus hierarchy until someone handles it. */
1512         if (dev->parent)
1513                 return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
1514                     r));
1515         return (EINVAL);
1516 }
1517
1518 int
1519 bus_generic_rl_get_resource (device_t dev, device_t child, int type, int rid,
1520     u_long *startp, u_long *countp)
1521 {
1522         struct resource_list *          rl = NULL;
1523         struct resource_list_entry *    rle = NULL;
1524
1525         rl = BUS_GET_RESOURCE_LIST(dev, child);
1526         if (!rl)
1527                 return (EINVAL);
1528
1529         rle = resource_list_find(rl, type, rid);
1530         if (!rle)
1531                 return (ENOENT);
1532
1533         if (startp)
1534                 *startp = rle->start;
1535         if (countp)
1536                 *countp = rle->count;
1537
1538         return (0);
1539 }
1540
1541 int
1542 bus_generic_rl_set_resource (device_t dev, device_t child, int type, int rid,
1543     u_long start, u_long count)
1544 {
1545         struct resource_list *          rl = NULL;
1546
1547         rl = BUS_GET_RESOURCE_LIST(dev, child);
1548         if (!rl)
1549                 return (EINVAL);
1550
1551         resource_list_add(rl, type, rid, start, (start + count - 1), count);
1552
1553         return (0);
1554 }
1555
1556 void
1557 bus_generic_rl_delete_resource (device_t dev, device_t child, int type, int rid)
1558 {
1559         struct resource_list *          rl = NULL;
1560
1561         rl = BUS_GET_RESOURCE_LIST(dev, child);
1562         if (!rl)
1563                 return;
1564
1565         resource_list_delete(rl, type, rid);
1566
1567         return;
1568 }
1569
1570 int
1571 bus_generic_rl_release_resource (device_t dev, device_t child, int type,
1572     int rid, struct resource *r)
1573 {
1574         struct resource_list *          rl = NULL;
1575
1576         rl = BUS_GET_RESOURCE_LIST(dev, child);
1577         if (!rl)
1578                 return (EINVAL);
1579
1580         return (resource_list_release(rl, dev, child, type, rid, r));
1581 }
1582
1583 struct resource *
1584 bus_generic_rl_alloc_resource (device_t dev, device_t child, int type,
1585     int *rid, u_long start, u_long end, u_long count, u_int flags)
1586 {
1587         struct resource_list *          rl = NULL;
1588
1589         rl = BUS_GET_RESOURCE_LIST(dev, child);
1590         if (!rl)
1591                 return (NULL);
1592
1593         return (resource_list_alloc(rl, dev, child, type, rid,
1594             start, end, count, flags));
1595 }
1596
1597 /*
1598  * Some convenience functions to make it easier for drivers to use the
1599  * resource-management functions.  All these really do is hide the
1600  * indirection through the parent's method table, making for slightly
1601  * less-wordy code.  In the future, it might make sense for this code
1602  * to maintain some sort of a list of resources allocated by each device.
1603  */
1604 struct resource *
1605 bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end,
1606     u_long count, u_int flags)
1607 {
1608         if (dev->parent == 0)
1609                 return (0);
1610         return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
1611             count, flags));
1612 }
1613
1614 int
1615 bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
1616 {
1617         if (dev->parent == 0)
1618                 return (EINVAL);
1619         return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
1620 }
1621
1622 int
1623 bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
1624 {
1625         if (dev->parent == 0)
1626                 return (EINVAL);
1627         return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
1628 }
1629
1630 int
1631 bus_release_resource(device_t dev, int type, int rid, struct resource *r)
1632 {
1633         if (dev->parent == 0)
1634                 return (EINVAL);
1635         return (BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r));
1636 }
1637
1638 int
1639 bus_setup_intr(device_t dev, struct resource *r, int flags,
1640     driver_intr_t handler, void *arg, void **cookiep)
1641 {
1642         if (dev->parent == 0)
1643                 return (EINVAL);
1644         return (BUS_SETUP_INTR(dev->parent, dev, r, flags,
1645             handler, arg, cookiep));
1646 }
1647
1648 int
1649 bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
1650 {
1651         if (dev->parent == 0)
1652                 return (EINVAL);
1653         return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
1654 }
1655
1656 int
1657 bus_set_resource(device_t dev, int type, int rid,
1658     u_long start, u_long count)
1659 {
1660         return (BUS_SET_RESOURCE(device_get_parent(dev), dev, type, rid,
1661             start, count));
1662 }
1663
1664 int
1665 bus_get_resource(device_t dev, int type, int rid,
1666     u_long *startp, u_long *countp)
1667 {
1668         return (BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
1669             startp, countp));
1670 }
1671
1672 u_long
1673 bus_get_resource_start(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 (start);
1683 }
1684
1685 u_long
1686 bus_get_resource_count(device_t dev, int type, int rid)
1687 {
1688         u_long start, count;
1689         int error;
1690
1691         error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
1692             &start, &count);
1693         if (error)
1694                 return (0);
1695         return (count);
1696 }
1697
1698 void
1699 bus_delete_resource(device_t dev, int type, int rid)
1700 {
1701         BUS_DELETE_RESOURCE(device_get_parent(dev), dev, type, rid);
1702 }
1703
1704 static int
1705 root_print_child(device_t dev, device_t child)
1706 {
1707         int     retval = 0;
1708
1709         retval += bus_print_child_header(dev, child);
1710         retval += printf("\n");
1711
1712         return (retval);
1713 }
1714
1715 static int
1716 root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg,
1717     void **cookiep)
1718 {
1719         /*
1720          * If an interrupt mapping gets to here something bad has happened.
1721          */
1722         panic("root_setup_intr");
1723 }
1724
1725 static kobj_method_t root_methods[] = {
1726         /* Device interface */
1727         KOBJMETHOD(device_shutdown,     bus_generic_shutdown),
1728         KOBJMETHOD(device_suspend,      bus_generic_suspend),
1729         KOBJMETHOD(device_resume,       bus_generic_resume),
1730
1731         /* Bus interface */
1732         KOBJMETHOD(bus_print_child,     root_print_child),
1733         KOBJMETHOD(bus_read_ivar,       bus_generic_read_ivar),
1734         KOBJMETHOD(bus_write_ivar,      bus_generic_write_ivar),
1735         KOBJMETHOD(bus_setup_intr,      root_setup_intr),
1736
1737         { 0, 0 }
1738 };
1739
1740 static driver_t root_driver = {
1741         "root",
1742         root_methods,
1743         1,                      /* no softc */
1744 };
1745
1746 device_t        root_bus;
1747 devclass_t      root_devclass;
1748
1749 static int
1750 root_bus_module_handler(module_t mod, int what, void* arg)
1751 {
1752         switch (what) {
1753         case MOD_LOAD:
1754                 TAILQ_INIT(&bus_data_devices);
1755                 kobj_class_compile((kobj_class_t) &root_driver);
1756                 root_bus = make_device(NULL, "root", 0);
1757                 root_bus->desc = "System root bus";
1758                 kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
1759                 root_bus->driver = &root_driver;
1760                 root_bus->state = DS_ATTACHED;
1761                 root_devclass = devclass_find_internal("root", FALSE);
1762                 return (0);
1763
1764         case MOD_SHUTDOWN:
1765                 device_shutdown(root_bus);
1766                 return (0);
1767         }
1768
1769         return (0);
1770 }
1771
1772 static moduledata_t root_bus_mod = {
1773         "rootbus",
1774         root_bus_module_handler,
1775         0
1776 };
1777 DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
1778
1779 void
1780 root_bus_configure(void)
1781 {
1782         device_t dev;
1783
1784         PDEBUG(("."));
1785
1786         TAILQ_FOREACH(dev, &root_bus->children, link) {
1787                 device_probe_and_attach(dev);
1788         }
1789 }
1790
1791 int
1792 driver_module_handler(module_t mod, int what, void *arg)
1793 {
1794         int error, i;
1795         struct driver_module_data *dmd;
1796         devclass_t bus_devclass;
1797
1798         dmd = (struct driver_module_data *)arg;
1799         bus_devclass = devclass_find_internal(dmd->dmd_busname, TRUE);
1800         error = 0;
1801
1802         switch (what) {
1803         case MOD_LOAD:
1804                 if (dmd->dmd_chainevh)
1805                         error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
1806
1807                 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
1808                         PDEBUG(("Loading module: driver %s on bus %s",
1809                             DRIVERNAME(dmd->dmd_drivers[i]), dmd->dmd_busname));
1810                         error = devclass_add_driver(bus_devclass,
1811                             dmd->dmd_drivers[i]);
1812                 }
1813                 if (error)
1814                         break;
1815
1816                 /*
1817                  * The drivers loaded in this way are assumed to all
1818                  * implement the same devclass.
1819                  */
1820                 *dmd->dmd_devclass =
1821                     devclass_find_internal(dmd->dmd_drivers[0]->name, TRUE);
1822                 break;
1823
1824         case MOD_UNLOAD:
1825                 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
1826                         PDEBUG(("Unloading module: driver %s from bus %s",
1827                             DRIVERNAME(dmd->dmd_drivers[i]),
1828                             dmd->dmd_busname));
1829                         error = devclass_delete_driver(bus_devclass,
1830                             dmd->dmd_drivers[i]);
1831                 }
1832
1833                 if (!error && dmd->dmd_chainevh)
1834                         error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
1835                 break;
1836         }
1837
1838         return (error);
1839 }
1840
1841 #ifdef BUS_DEBUG
1842
1843 /* the _short versions avoid iteration by not calling anything that prints
1844  * more than oneliners. I love oneliners.
1845  */
1846
1847 static void
1848 print_device_short(device_t dev, int indent)
1849 {
1850         if (!dev)
1851                 return;
1852
1853         indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
1854             dev->unit, dev->desc,
1855             (dev->parent? "":"no "),
1856             (TAILQ_EMPTY(&dev->children)? "no ":""),
1857             (dev->flags&DF_ENABLED? "enabled,":"disabled,"),
1858             (dev->flags&DF_FIXEDCLASS? "fixed,":""),
1859             (dev->flags&DF_WILDCARD? "wildcard,":""),
1860             (dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
1861             (dev->ivars? "":"no "),
1862             (dev->softc? "":"no "),
1863             dev->busy));
1864 }
1865
1866 static void
1867 print_device(device_t dev, int indent)
1868 {
1869         if (!dev)
1870                 return;
1871
1872         print_device_short(dev, indent);
1873
1874         indentprintf(("Parent:\n"));
1875         print_device_short(dev->parent, indent+1);
1876         indentprintf(("Driver:\n"));
1877         print_driver_short(dev->driver, indent+1);
1878         indentprintf(("Devclass:\n"));
1879         print_devclass_short(dev->devclass, indent+1);
1880 }
1881
1882 void
1883 print_device_tree_short(device_t dev, int indent)
1884 /* print the device and all its children (indented) */
1885 {
1886         device_t child;
1887
1888         if (!dev)
1889                 return;
1890
1891         print_device_short(dev, indent);
1892
1893         TAILQ_FOREACH(child, &dev->children, link) {
1894                 print_device_tree_short(child, indent+1);
1895         }
1896 }
1897
1898 void
1899 print_device_tree(device_t dev, int indent)
1900 /* print the device and all its children (indented) */
1901 {
1902         device_t child;
1903
1904         if (!dev)
1905                 return;
1906
1907         print_device(dev, indent);
1908
1909         TAILQ_FOREACH(child, &dev->children, link) {
1910                 print_device_tree(child, indent+1);
1911         }
1912 }
1913
1914 static void
1915 print_driver_short(driver_t *driver, int indent)
1916 {
1917         if (!driver)
1918                 return;
1919
1920         indentprintf(("driver %s: softc size = %d\n",
1921             driver->name, driver->size));
1922 }
1923
1924 static void
1925 print_driver(driver_t *driver, int indent)
1926 {
1927         if (!driver)
1928                 return;
1929
1930         print_driver_short(driver, indent);
1931 }
1932
1933
1934 static void
1935 print_driver_list(driver_list_t drivers, int indent)
1936 {
1937         driverlink_t driver;
1938
1939         TAILQ_FOREACH(driver, &drivers, link) {
1940                 print_driver(driver->driver, indent);
1941         }
1942 }
1943
1944 static void
1945 print_devclass_short(devclass_t dc, int indent)
1946 {
1947         if ( !dc )
1948                 return;
1949
1950         indentprintf(("devclass %s: max units = %d\n", dc->name, dc->maxunit));
1951 }
1952
1953 static void
1954 print_devclass(devclass_t dc, int indent)
1955 {
1956         int i;
1957
1958         if ( !dc )
1959                 return;
1960
1961         print_devclass_short(dc, indent);
1962         indentprintf(("Drivers:\n"));
1963         print_driver_list(dc->drivers, indent+1);
1964
1965         indentprintf(("Devices:\n"));
1966         for (i = 0; i < dc->maxunit; i++)
1967                 if (dc->devices[i])
1968                         print_device(dc->devices[i], indent+1);
1969 }
1970
1971 void
1972 print_devclass_list_short(void)
1973 {
1974         devclass_t dc;
1975
1976         printf("Short listing of devclasses, drivers & devices:\n");
1977         TAILQ_FOREACH(dc, &devclasses, link) {
1978                 print_devclass_short(dc, 0);
1979         }
1980 }
1981
1982 void
1983 print_devclass_list(void)
1984 {
1985         devclass_t dc;
1986
1987         printf("Full listing of devclasses, drivers & devices:\n");
1988         TAILQ_FOREACH(dc, &devclasses, link) {
1989                 print_devclass(dc, 0);
1990         }
1991 }
1992
1993 #endif
1994
1995 /*
1996  * User-space access to the device tree.
1997  *
1998  * We implement a small set of nodes:
1999  *
2000  * hw.bus                       Single integer read method to obtain the
2001  *                              current generation count.
2002  * hw.bus.devices               Reads the entire device tree in flat space.
2003  * hw.bus.rman                  Resource manager interface
2004  *
2005  * We might like to add the ability to scan devclasses and/or drivers to
2006  * determine what else is currently loaded/available.
2007  */
2008 SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
2009
2010 static int
2011 sysctl_bus(SYSCTL_HANDLER_ARGS)
2012 {
2013         struct u_businfo        ubus;
2014
2015         ubus.ub_version = BUS_USER_VERSION;
2016         ubus.ub_generation = bus_data_generation;
2017
2018         return (SYSCTL_OUT(req, &ubus, sizeof(ubus)));
2019 }
2020 SYSCTL_NODE(_hw_bus, OID_AUTO, info, CTLFLAG_RW, sysctl_bus,
2021     "bus-related data");
2022
2023 static int
2024 sysctl_devices(SYSCTL_HANDLER_ARGS)
2025 {
2026         int                     *name = (int *)arg1;
2027         u_int                   namelen = arg2;
2028         int                     index;
2029         struct device           *dev;
2030         struct u_device         udev;   /* XXX this is a bit big */
2031         int                     error;
2032
2033         if (namelen != 2)
2034                 return (EINVAL);
2035
2036         if (bus_data_generation_check(name[0]))
2037                 return (EINVAL);
2038
2039         index = name[1];
2040
2041         /*
2042          * Scan the list of devices, looking for the requested index.
2043          */
2044         TAILQ_FOREACH(dev, &bus_data_devices, devlink) {
2045                 if (index-- == 0)
2046                         break;
2047         }
2048         if (dev == NULL)
2049                 return (ENOENT);
2050
2051         /*
2052          * Populate the return array.
2053          */
2054         udev.dv_handle = (uintptr_t)dev;
2055         udev.dv_parent = (uintptr_t)dev->parent;
2056         if (dev->nameunit == NULL) {
2057                 udev.dv_name[0] = 0;
2058         } else {
2059                 snprintf(udev.dv_name, 32, "%s", dev->nameunit);
2060         }
2061         if (dev->desc == NULL) {
2062                 udev.dv_desc[0] = 0;
2063         } else {
2064                 snprintf(udev.dv_desc, 32, "%s", dev->desc);
2065         }
2066         if ((dev->driver == NULL) || (dev->driver->name == NULL)) {
2067                 udev.dv_drivername[0] = 0;
2068         } else {
2069                 snprintf(udev.dv_drivername, 32, "%s", dev->driver->name);
2070         }
2071         error = SYSCTL_OUT(req, &udev, sizeof(udev));
2072         return (error);
2073 }
2074
2075 SYSCTL_NODE(_hw_bus, OID_AUTO, devices, CTLFLAG_RD, sysctl_devices,
2076     "system device tree");
2077
2078 /*
2079  * Sysctl interface for scanning the resource lists.
2080  *
2081  * We take two input parameters; the index into the list of resource
2082  * managers, and the resource offset into the list.
2083  */
2084 static int
2085 sysctl_rman(SYSCTL_HANDLER_ARGS)
2086 {
2087         int                     *name = (int *)arg1;
2088         u_int                   namelen = arg2;
2089         int                     rman_idx, res_idx;
2090         struct rman             *rm;
2091         struct resource         *res;
2092         struct u_rman           urm;
2093         struct u_resource       ures;
2094         int                     error;
2095
2096         if (namelen != 3)
2097                 return (EINVAL);
2098
2099         if (bus_data_generation_check(name[0]))
2100                 return (EINVAL);
2101         rman_idx = name[1];
2102         res_idx = name[2];
2103
2104         /*
2105          * Find the indexed resource manager
2106          */
2107         TAILQ_FOREACH(rm, &rman_head, rm_link) {
2108                 if (rman_idx-- == 0)
2109                         break;
2110         }
2111         if (rm == NULL)
2112                 return (ENOENT);
2113
2114         /*
2115          * If the resource index is -1, we want details on the
2116          * resource manager.
2117          */
2118         if (res_idx == -1) {
2119                 urm.rm_handle = (uintptr_t)rm;
2120                 snprintf(urm.rm_descr, RM_TEXTLEN, "%s", rm->rm_descr);
2121                 urm.rm_descr[RM_TEXTLEN - 1] = '\0';
2122                 urm.rm_start = rm->rm_start;
2123                 urm.rm_size = rm->rm_end - rm->rm_start + 1;
2124                 urm.rm_type = rm->rm_type;
2125
2126                 error = SYSCTL_OUT(req, &urm, sizeof(urm));
2127                 return (error);
2128         }
2129
2130         /*
2131          * Find the indexed resource and return it.
2132          */
2133         TAILQ_FOREACH(res, &rm->rm_list, r_link) {
2134                 if (res_idx-- == 0) {
2135                         ures.r_handle = (uintptr_t)res;
2136                         ures.r_parent = (uintptr_t)res->r_rm;
2137                         ures.r_device = (uintptr_t)res->r_dev;
2138                         if (res->r_dev != NULL) {
2139                                 if (device_get_name(res->r_dev) != NULL) {
2140                                         snprintf(ures.r_devname, RM_TEXTLEN,
2141                                             "%s%d",
2142                                             device_get_name(res->r_dev),
2143                                             device_get_unit(res->r_dev));
2144                                 } else {
2145                                         snprintf(ures.r_devname, RM_TEXTLEN,
2146                                             "nomatch");
2147                                 }
2148                         } else {
2149                                 ures.r_devname[0] = 0;
2150                         }
2151                         ures.r_start = res->r_start;
2152                         ures.r_size = res->r_end - res->r_start + 1;
2153                         ures.r_flags = res->r_flags;
2154
2155                         error = SYSCTL_OUT(req, &ures, sizeof(ures));
2156                         return (error);
2157                 }
2158         }
2159         return (ENOENT);
2160 }
2161
2162 SYSCTL_NODE(_hw_bus, OID_AUTO, rman, CTLFLAG_RD, sysctl_rman,
2163     "kernel resource manager");
2164
2165 int
2166 bus_data_generation_check(int generation)
2167 {
2168         if (generation != bus_data_generation)
2169                 return (1);
2170
2171         /* XXX generate optimised lists here? */
2172         return (0);
2173 }
2174
2175 void
2176 bus_data_generation_update(void)
2177 {
2178         bus_data_generation++;
2179 }