source: rtems-libbsd/freebsd/kern/subr_bus.c @ fb4c8a9

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since fb4c8a9 was fb4c8a9, checked in by Jennifer Averett <jennifer.averett@…>, on 05/23/12 at 19:53:12

Added pcib for Nics.

  • Property mode set to 100644
File size: 110.1 KB
Line 
1#include <freebsd/machine/rtems-bsd-config.h>
2
3/*-
4 * Copyright (c) 1997,1998,2003 Doug Rabson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <freebsd/sys/cdefs.h>
30__FBSDID("$FreeBSD$");
31
32#include <freebsd/local/opt_bus.h>
33
34#include <freebsd/sys/param.h>
35#include <freebsd/sys/conf.h>
36#include <freebsd/sys/filio.h>
37#include <freebsd/sys/lock.h>
38#include <freebsd/sys/kernel.h>
39#include <freebsd/sys/kobj.h>
40#include <freebsd/sys/limits.h>
41#include <freebsd/sys/malloc.h>
42#include <freebsd/sys/module.h>
43#include <freebsd/sys/mutex.h>
44#include <freebsd/sys/poll.h>
45#include <freebsd/sys/proc.h>
46#include <freebsd/sys/condvar.h>
47#include <freebsd/sys/queue.h>
48#include <freebsd/machine/bus.h>
49#include <freebsd/sys/rman.h>
50#include <freebsd/sys/selinfo.h>
51#include <freebsd/sys/signalvar.h>
52#include <freebsd/sys/sysctl.h>
53#include <freebsd/sys/systm.h>
54#include <freebsd/sys/uio.h>
55#include <freebsd/sys/bus.h>
56#include <freebsd/sys/interrupt.h>
57
58#include <freebsd/machine/stdarg.h>
59
60#include <freebsd/vm/uma.h>
61
62SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
63SYSCTL_NODE(, OID_AUTO, dev, CTLFLAG_RW, NULL, NULL);
64
65/*
66 * Used to attach drivers to devclasses.
67 */
68typedef struct driverlink *driverlink_t;
69struct driverlink {
70        kobj_class_t    driver;
71        TAILQ_ENTRY(driverlink) link;   /* list of drivers in devclass */
72        int             pass;
73        TAILQ_ENTRY(driverlink) passlink;
74};
75
76/*
77 * Forward declarations
78 */
79typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t;
80typedef TAILQ_HEAD(driver_list, driverlink) driver_list_t;
81typedef TAILQ_HEAD(device_list, device) device_list_t;
82
83struct devclass {
84        TAILQ_ENTRY(devclass) link;
85        devclass_t      parent;         /* parent in devclass hierarchy */
86        driver_list_t   drivers;     /* bus devclasses store drivers for bus */
87        char            *name;
88        device_t        *devices;       /* array of devices indexed by unit */
89        int             maxunit;        /* size of devices array */
90        int             flags;
91#define DC_HAS_CHILDREN         1
92
93#ifndef __rtems__
94        struct sysctl_ctx_list sysctl_ctx;
95        struct sysctl_oid *sysctl_tree;
96#endif /* __rtems__ */
97};
98
99/**
100 * @brief Implementation of device.
101 */
102struct device {
103        /*
104         * A device is a kernel object. The first field must be the
105         * current ops table for the object.
106         */
107        KOBJ_FIELDS;
108
109        /*
110         * Device hierarchy.
111         */
112        TAILQ_ENTRY(device)     link;   /**< list of devices in parent */
113        TAILQ_ENTRY(device)     devlink; /**< global device list membership */
114        device_t        parent;         /**< parent of this device  */
115        device_list_t   children;       /**< list of child devices */
116
117        /*
118         * Details of this device.
119         */
120        driver_t        *driver;        /**< current driver */
121        devclass_t      devclass;       /**< current device class */
122        int             unit;           /**< current unit number */
123        char*           nameunit;       /**< name+unit e.g. foodev0 */
124        char*           desc;           /**< driver specific description */
125        int             busy;           /**< count of calls to device_busy() */
126        device_state_t  state;          /**< current device state  */
127        u_int32_t       devflags;       /**< api level flags for device_get_flags() */
128        u_int           flags;          /**< internal device flags  */
129#define DF_ENABLED      0x01            /* device should be probed/attached */
130#define DF_FIXEDCLASS   0x02            /* devclass specified at create time */
131#define DF_WILDCARD     0x04            /* unit was originally wildcard */
132#define DF_DESCMALLOCED 0x08            /* description was malloced */
133#define DF_QUIET        0x10            /* don't print verbose attach message */
134#define DF_DONENOMATCH  0x20            /* don't execute DEVICE_NOMATCH again */
135#define DF_EXTERNALSOFTC 0x40           /* softc not allocated by us */
136#define DF_REBID        0x80            /* Can rebid after attach */
137        u_int   order;                  /**< order from device_add_child_ordered() */
138        void    *ivars;                 /**< instance variables  */
139        void    *softc;                 /**< current driver's variables  */
140
141#ifndef __rtems__
142        struct sysctl_ctx_list sysctl_ctx; /**< state for sysctl variables  */
143        struct sysctl_oid *sysctl_tree; /**< state for sysctl variables */
144#endif /* __rtems__ */
145};
146
147static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures");
148static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc");
149
150#ifdef BUS_DEBUG
151
152static int bus_debug = 1;
153#ifndef __rtems__
154TUNABLE_INT("bus.debug", &bus_debug);
155SYSCTL_INT(_debug, OID_AUTO, bus_debug, CTLFLAG_RW, &bus_debug, 0,
156    "Debug bus code");
157#endif /* __rtems__ */
158
159#define PDEBUG(a)       if (bus_debug) {printf("%s:%d: ", __func__, __LINE__), printf a; printf("\n");}
160#define DEVICENAME(d)   ((d)? device_get_name(d): "no device")
161#define DRIVERNAME(d)   ((d)? d->name : "no driver")
162#define DEVCLANAME(d)   ((d)? d->name : "no devclass")
163
164/**
165 * Produce the indenting, indent*2 spaces plus a '.' ahead of that to
166 * prevent syslog from deleting initial spaces
167 */
168#define indentprintf(p) do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf("  "); printf p ; } while (0)
169
170static void print_device_short(device_t dev, int indent);
171static void print_device(device_t dev, int indent);
172void print_device_tree_short(device_t dev, int indent);
173void print_device_tree(device_t dev, int indent);
174static void print_driver_short(driver_t *driver, int indent);
175static void print_driver(driver_t *driver, int indent);
176static void print_driver_list(driver_list_t drivers, int indent);
177static void print_devclass_short(devclass_t dc, int indent);
178static void print_devclass(devclass_t dc, int indent);
179void print_devclass_list_short(void);
180void print_devclass_list(void);
181
182#else
183/* Make the compiler ignore the function calls */
184#define PDEBUG(a)                       /* nop */
185#define DEVICENAME(d)                   /* nop */
186#define DRIVERNAME(d)                   /* nop */
187#define DEVCLANAME(d)                   /* nop */
188
189#define print_device_short(d,i)         /* nop */
190#define print_device(d,i)               /* nop */
191#define print_device_tree_short(d,i)    /* nop */
192#define print_device_tree(d,i)          /* nop */
193#define print_driver_short(d,i)         /* nop */
194#define print_driver(d,i)               /* nop */
195#define print_driver_list(d,i)          /* nop */
196#define print_devclass_short(d,i)       /* nop */
197#define print_devclass(d,i)             /* nop */
198#define print_devclass_list_short()     /* nop */
199#define print_devclass_list()           /* nop */
200#endif
201
202#ifndef __rtems__
203/*
204 * dev sysctl tree
205 */
206
207enum {
208        DEVCLASS_SYSCTL_PARENT,
209};
210
211static int
212devclass_sysctl_handler(SYSCTL_HANDLER_ARGS)
213{
214        devclass_t dc = (devclass_t)arg1;
215        const char *value;
216
217        switch (arg2) {
218        case DEVCLASS_SYSCTL_PARENT:
219                value = dc->parent ? dc->parent->name : "";
220                break;
221        default:
222                return (EINVAL);
223        }
224        return (SYSCTL_OUT(req, value, strlen(value)));
225}
226
227static void
228devclass_sysctl_init(devclass_t dc)
229{
230
231        if (dc->sysctl_tree != NULL)
232                return;
233        sysctl_ctx_init(&dc->sysctl_ctx);
234        dc->sysctl_tree = SYSCTL_ADD_NODE(&dc->sysctl_ctx,
235            SYSCTL_STATIC_CHILDREN(_dev), OID_AUTO, dc->name,
236            CTLFLAG_RD, NULL, "");
237        SYSCTL_ADD_PROC(&dc->sysctl_ctx, SYSCTL_CHILDREN(dc->sysctl_tree),
238            OID_AUTO, "%parent", CTLFLAG_RD,
239            dc, DEVCLASS_SYSCTL_PARENT, devclass_sysctl_handler, "A",
240            "parent class");
241}
242
243enum {
244        DEVICE_SYSCTL_DESC,
245        DEVICE_SYSCTL_DRIVER,
246        DEVICE_SYSCTL_LOCATION,
247        DEVICE_SYSCTL_PNPINFO,
248        DEVICE_SYSCTL_PARENT,
249};
250
251static int
252device_sysctl_handler(SYSCTL_HANDLER_ARGS)
253{
254        device_t dev = (device_t)arg1;
255        const char *value;
256        char *buf;
257        int error;
258
259        buf = NULL;
260        switch (arg2) {
261        case DEVICE_SYSCTL_DESC:
262                value = dev->desc ? dev->desc : "";
263                break;
264        case DEVICE_SYSCTL_DRIVER:
265                value = dev->driver ? dev->driver->name : "";
266                break;
267        case DEVICE_SYSCTL_LOCATION:
268                value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
269                bus_child_location_str(dev, buf, 1024);
270                break;
271        case DEVICE_SYSCTL_PNPINFO:
272                value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
273                bus_child_pnpinfo_str(dev, buf, 1024);
274                break;
275        case DEVICE_SYSCTL_PARENT:
276                value = dev->parent ? dev->parent->nameunit : "";
277                break;
278        default:
279                return (EINVAL);
280        }
281        error = SYSCTL_OUT(req, value, strlen(value));
282        if (buf != NULL)
283                free(buf, M_BUS);
284        return (error);
285}
286#endif /* __rtems__ */
287
288static void
289device_sysctl_init(device_t dev)
290{
291#ifndef __rtems__
292        devclass_t dc = dev->devclass;
293
294        if (dev->sysctl_tree != NULL)
295                return;
296        devclass_sysctl_init(dc);
297        sysctl_ctx_init(&dev->sysctl_ctx);
298        dev->sysctl_tree = SYSCTL_ADD_NODE(&dev->sysctl_ctx,
299            SYSCTL_CHILDREN(dc->sysctl_tree), OID_AUTO,
300            dev->nameunit + strlen(dc->name),
301            CTLFLAG_RD, NULL, "");
302        SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
303            OID_AUTO, "%desc", CTLFLAG_RD,
304            dev, DEVICE_SYSCTL_DESC, device_sysctl_handler, "A",
305            "device description");
306        SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
307            OID_AUTO, "%driver", CTLFLAG_RD,
308            dev, DEVICE_SYSCTL_DRIVER, device_sysctl_handler, "A",
309            "device driver name");
310        SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
311            OID_AUTO, "%location", CTLFLAG_RD,
312            dev, DEVICE_SYSCTL_LOCATION, device_sysctl_handler, "A",
313            "device location relative to parent");
314        SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
315            OID_AUTO, "%pnpinfo", CTLFLAG_RD,
316            dev, DEVICE_SYSCTL_PNPINFO, device_sysctl_handler, "A",
317            "device identification");
318        SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
319            OID_AUTO, "%parent", CTLFLAG_RD,
320            dev, DEVICE_SYSCTL_PARENT, device_sysctl_handler, "A",
321            "parent device");
322#endif /* __rtems__ */
323}
324
325static void
326device_sysctl_update(device_t dev)
327{
328#ifndef __rtems__
329        devclass_t dc = dev->devclass;
330
331        if (dev->sysctl_tree == NULL)
332                return;
333        sysctl_rename_oid(dev->sysctl_tree, dev->nameunit + strlen(dc->name));
334#endif /* __rtems__ */
335}
336
337static void
338device_sysctl_fini(device_t dev)
339{
340#ifndef __rtems__
341        if (dev->sysctl_tree == NULL)
342                return;
343        sysctl_ctx_free(&dev->sysctl_ctx);
344        dev->sysctl_tree = NULL;
345#endif /* __rtems__ */
346}
347
348/*
349 * /dev/devctl implementation
350 */
351
352/*
353 * This design allows only one reader for /dev/devctl.  This is not desirable
354 * in the long run, but will get a lot of hair out of this implementation.
355 * Maybe we should make this device a clonable device.
356 *
357 * Also note: we specifically do not attach a device to the device_t tree
358 * to avoid potential chicken and egg problems.  One could argue that all
359 * of this belongs to the root node.  One could also further argue that the
360 * sysctl interface that we have not might more properly be an ioctl
361 * interface, but at this stage of the game, I'm not inclined to rock that
362 * boat.
363 *
364 * I'm also not sure that the SIGIO support is done correctly or not, as
365 * I copied it from a driver that had SIGIO support that likely hasn't been
366 * tested since 3.4 or 2.2.8!
367 */
368
369#ifndef __rtems__
370/* Deprecated way to adjust queue length */
371static int sysctl_devctl_disable(SYSCTL_HANDLER_ARGS);
372/* XXX Need to support old-style tunable hw.bus.devctl_disable" */
373SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_disable, CTLTYPE_INT | CTLFLAG_RW, NULL,
374    0, sysctl_devctl_disable, "I", "devctl disable -- deprecated");
375#endif /* __rtems__ */
376
377#define DEVCTL_DEFAULT_QUEUE_LEN 1000
378#ifndef __rtems__
379static int sysctl_devctl_queue(SYSCTL_HANDLER_ARGS);
380#endif /* __rtems__ */
381static int devctl_queue_length = DEVCTL_DEFAULT_QUEUE_LEN;
382#ifndef __rtems__
383TUNABLE_INT("hw.bus.devctl_queue", &devctl_queue_length);
384SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_queue, CTLTYPE_INT | CTLFLAG_RW, NULL,
385    0, sysctl_devctl_queue, "I", "devctl queue length");
386
387static d_open_t         devopen;
388static d_close_t        devclose;
389static d_read_t         devread;
390static d_ioctl_t        devioctl;
391static d_poll_t         devpoll;
392
393static struct cdevsw dev_cdevsw = {
394        .d_version =    D_VERSION,
395        .d_flags =      D_NEEDGIANT,
396        .d_open =       devopen,
397        .d_close =      devclose,
398        .d_read =       devread,
399        .d_ioctl =      devioctl,
400        .d_poll =       devpoll,
401        .d_name =       "devctl",
402};
403
404struct dev_event_info
405{
406        char *dei_data;
407        TAILQ_ENTRY(dev_event_info) dei_link;
408};
409
410TAILQ_HEAD(devq, dev_event_info);
411
412static struct dev_softc
413{
414        int     inuse;
415        int     nonblock;
416        int     queued;
417        struct mtx mtx;
418        struct cv cv;
419        struct selinfo sel;
420        struct devq devq;
421        struct proc *async_proc;
422} devsoftc;
423
424static struct cdev *devctl_dev;
425#else /* __rtems__ */
426#define devctl_disable 0
427#endif /* __rtems__ */
428
429static void
430devinit(void)
431{
432#ifndef __rtems__
433        devctl_dev = make_dev(&dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
434            "devctl");
435        mtx_init(&devsoftc.mtx, "dev mtx", "devd", MTX_DEF);
436        cv_init(&devsoftc.cv, "dev cv");
437        TAILQ_INIT(&devsoftc.devq);
438#endif /* __rtems__ */
439}
440
441#ifndef __rtems__
442static int
443devopen(struct cdev *dev, int oflags, int devtype, struct thread *td)
444{
445        if (devsoftc.inuse)
446                return (EBUSY);
447        /* move to init */
448        devsoftc.inuse = 1;
449        devsoftc.nonblock = 0;
450        devsoftc.async_proc = NULL;
451        return (0);
452}
453
454static int
455devclose(struct cdev *dev, int fflag, int devtype, struct thread *td)
456{
457        devsoftc.inuse = 0;
458        mtx_lock(&devsoftc.mtx);
459        cv_broadcast(&devsoftc.cv);
460        mtx_unlock(&devsoftc.mtx);
461        devsoftc.async_proc = NULL;
462        return (0);
463}
464
465/*
466 * The read channel for this device is used to report changes to
467 * userland in realtime.  We are required to free the data as well as
468 * the n1 object because we allocate them separately.  Also note that
469 * we return one record at a time.  If you try to read this device a
470 * character at a time, you will lose the rest of the data.  Listening
471 * programs are expected to cope.
472 */
473static int
474devread(struct cdev *dev, struct uio *uio, int ioflag)
475{
476        struct dev_event_info *n1;
477        int rv;
478
479        mtx_lock(&devsoftc.mtx);
480        while (TAILQ_EMPTY(&devsoftc.devq)) {
481                if (devsoftc.nonblock) {
482                        mtx_unlock(&devsoftc.mtx);
483                        return (EAGAIN);
484                }
485                rv = cv_wait_sig(&devsoftc.cv, &devsoftc.mtx);
486                if (rv) {
487                        /*
488                         * Need to translate ERESTART to EINTR here? -- jake
489                         */
490                        mtx_unlock(&devsoftc.mtx);
491                        return (rv);
492                }
493        }
494        n1 = TAILQ_FIRST(&devsoftc.devq);
495        TAILQ_REMOVE(&devsoftc.devq, n1, dei_link);
496        devsoftc.queued--;
497        mtx_unlock(&devsoftc.mtx);
498        rv = uiomove(n1->dei_data, strlen(n1->dei_data), uio);
499        free(n1->dei_data, M_BUS);
500        free(n1, M_BUS);
501        return (rv);
502}
503
504static  int
505devioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
506{
507        switch (cmd) {
508
509        case FIONBIO:
510                if (*(int*)data)
511                        devsoftc.nonblock = 1;
512                else
513                        devsoftc.nonblock = 0;
514                return (0);
515        case FIOASYNC:
516                if (*(int*)data)
517                        devsoftc.async_proc = td->td_proc;
518                else
519                        devsoftc.async_proc = NULL;
520                return (0);
521
522                /* (un)Support for other fcntl() calls. */
523        case FIOCLEX:
524        case FIONCLEX:
525        case FIONREAD:
526        case FIOSETOWN:
527        case FIOGETOWN:
528        default:
529                break;
530        }
531        return (ENOTTY);
532}
533
534static  int
535devpoll(struct cdev *dev, int events, struct thread *td)
536{
537        int     revents = 0;
538
539        mtx_lock(&devsoftc.mtx);
540        if (events & (POLLIN | POLLRDNORM)) {
541                if (!TAILQ_EMPTY(&devsoftc.devq))
542                        revents = events & (POLLIN | POLLRDNORM);
543                else
544                        selrecord(td, &devsoftc.sel);
545        }
546        mtx_unlock(&devsoftc.mtx);
547
548        return (revents);
549}
550
551/**
552 * @brief Return whether the userland process is running
553 */
554boolean_t
555devctl_process_running(void)
556{
557        return (devsoftc.inuse == 1);
558}
559#endif /* __rtems__ */
560
561/**
562 * @brief Queue data to be read from the devctl device
563 *
564 * Generic interface to queue data to the devctl device.  It is
565 * assumed that @p data is properly formatted.  It is further assumed
566 * that @p data is allocated using the M_BUS malloc type.
567 */
568void
569devctl_queue_data_f(char *data, int flags)
570{
571#ifndef __rtems__
572        struct dev_event_info *n1 = NULL, *n2 = NULL;
573        struct proc *p;
574#endif /* __rtems__ */
575
576        if (strlen(data) == 0)
577                goto out;
578#ifndef __rtems__
579        if (devctl_queue_length == 0)
580                goto out;
581        n1 = malloc(sizeof(*n1), M_BUS, flags);
582        if (n1 == NULL)
583                goto out;
584        n1->dei_data = data;
585        mtx_lock(&devsoftc.mtx);
586        if (devctl_queue_length == 0) {
587                mtx_unlock(&devsoftc.mtx);
588                free(n1->dei_data, M_BUS);
589                free(n1, M_BUS);
590                return;
591        }
592        /* Leave at least one spot in the queue... */
593        while (devsoftc.queued > devctl_queue_length - 1) {
594                n2 = TAILQ_FIRST(&devsoftc.devq);
595                TAILQ_REMOVE(&devsoftc.devq, n2, dei_link);
596                free(n2->dei_data, M_BUS);
597                free(n2, M_BUS);
598                devsoftc.queued--;
599        }
600        TAILQ_INSERT_TAIL(&devsoftc.devq, n1, dei_link);
601        devsoftc.queued++;
602        cv_broadcast(&devsoftc.cv);
603        mtx_unlock(&devsoftc.mtx);
604        selwakeup(&devsoftc.sel);
605        p = devsoftc.async_proc;
606        if (p != NULL) {
607                PROC_LOCK(p);
608                psignal(p, SIGIO);
609                PROC_UNLOCK(p);
610        }
611#else /* __rtems__ */
612        printf("devctl: %s", data);
613#endif /* __rtems__ */
614out:
615        /*
616         * We have to free data on all error paths since the caller
617         * assumes it will be free'd when this item is dequeued.
618         */
619        free(data, M_BUS);
620        return;
621}
622
623void
624devctl_queue_data(char *data)
625{
626
627        devctl_queue_data_f(data, M_NOWAIT);
628}
629
630/**
631 * @brief Send a 'notification' to userland, using standard ways
632 */
633void
634devctl_notify_f(const char *system, const char *subsystem, const char *type,
635    const char *data, int flags)
636{
637        int len = 0;
638        char *msg;
639
640        if (system == NULL)
641                return;         /* BOGUS!  Must specify system. */
642        if (subsystem == NULL)
643                return;         /* BOGUS!  Must specify subsystem. */
644        if (type == NULL)
645                return;         /* BOGUS!  Must specify type. */
646        len += strlen(" system=") + strlen(system);
647        len += strlen(" subsystem=") + strlen(subsystem);
648        len += strlen(" type=") + strlen(type);
649        /* add in the data message plus newline. */
650        if (data != NULL)
651                len += strlen(data);
652        len += 3;       /* '!', '\n', and NUL */
653        msg = malloc(len, M_BUS, flags);
654        if (msg == NULL)
655                return;         /* Drop it on the floor */
656        if (data != NULL)
657                snprintf(msg, len, "!system=%s subsystem=%s type=%s %s\n",
658                    system, subsystem, type, data);
659        else
660                snprintf(msg, len, "!system=%s subsystem=%s type=%s\n",
661                    system, subsystem, type);
662        devctl_queue_data_f(msg, flags);
663}
664
665void
666devctl_notify(const char *system, const char *subsystem, const char *type,
667    const char *data)
668{
669
670        devctl_notify_f(system, subsystem, type, data, M_NOWAIT);
671}
672
673/*
674 * Common routine that tries to make sending messages as easy as possible.
675 * We allocate memory for the data, copy strings into that, but do not
676 * free it unless there's an error.  The dequeue part of the driver should
677 * free the data.  We don't send data when the device is disabled.  We do
678 * send data, even when we have no listeners, because we wish to avoid
679 * races relating to startup and restart of listening applications.
680 *
681 * devaddq is designed to string together the type of event, with the
682 * object of that event, plus the plug and play info and location info
683 * for that event.  This is likely most useful for devices, but less
684 * useful for other consumers of this interface.  Those should use
685 * the devctl_queue_data() interface instead.
686 */
687static void
688devaddq(const char *type, const char *what, device_t dev)
689{
690        char *data = NULL;
691        char *loc = NULL;
692        char *pnp = NULL;
693        const char *parstr;
694
695        if (!devctl_queue_length)/* Rare race, but lost races safely discard */
696                return;
697        data = malloc(1024, M_BUS, M_NOWAIT);
698        if (data == NULL)
699                goto bad;
700
701        /* get the bus specific location of this device */
702        loc = malloc(1024, M_BUS, M_NOWAIT);
703        if (loc == NULL)
704                goto bad;
705        *loc = '\0';
706        bus_child_location_str(dev, loc, 1024);
707
708        /* Get the bus specific pnp info of this device */
709        pnp = malloc(1024, M_BUS, M_NOWAIT);
710        if (pnp == NULL)
711                goto bad;
712        *pnp = '\0';
713        bus_child_pnpinfo_str(dev, pnp, 1024);
714
715        /* Get the parent of this device, or / if high enough in the tree. */
716        if (device_get_parent(dev) == NULL)
717                parstr = ".";   /* Or '/' ? */
718        else
719                parstr = device_get_nameunit(device_get_parent(dev));
720        /* String it all together. */
721        snprintf(data, 1024, "%s%s at %s %s on %s\n", type, what, loc, pnp,
722          parstr);
723        free(loc, M_BUS);
724        free(pnp, M_BUS);
725        devctl_queue_data(data);
726        return;
727bad:
728        free(pnp, M_BUS);
729        free(loc, M_BUS);
730        free(data, M_BUS);
731        return;
732}
733
734/*
735 * A device was added to the tree.  We are called just after it successfully
736 * attaches (that is, probe and attach success for this device).  No call
737 * is made if a device is merely parented into the tree.  See devnomatch
738 * if probe fails.  If attach fails, no notification is sent (but maybe
739 * we should have a different message for this).
740 */
741static void
742devadded(device_t dev)
743{
744        char *pnp = NULL;
745        char *tmp = NULL;
746
747        pnp = malloc(1024, M_BUS, M_NOWAIT);
748        if (pnp == NULL)
749                goto fail;
750        tmp = malloc(1024, M_BUS, M_NOWAIT);
751        if (tmp == NULL)
752                goto fail;
753        *pnp = '\0';
754        bus_child_pnpinfo_str(dev, pnp, 1024);
755        snprintf(tmp, 1024, "%s %s", device_get_nameunit(dev), pnp);
756        devaddq("+", tmp, dev);
757fail:
758        if (pnp != NULL)
759                free(pnp, M_BUS);
760        if (tmp != NULL)
761                free(tmp, M_BUS);
762        return;
763}
764
765/*
766 * A device was removed from the tree.  We are called just before this
767 * happens.
768 */
769static void
770devremoved(device_t dev)
771{
772        char *pnp = NULL;
773        char *tmp = NULL;
774
775        pnp = malloc(1024, M_BUS, M_NOWAIT);
776        if (pnp == NULL)
777                goto fail;
778        tmp = malloc(1024, M_BUS, M_NOWAIT);
779        if (tmp == NULL)
780                goto fail;
781        *pnp = '\0';
782        bus_child_pnpinfo_str(dev, pnp, 1024);
783        snprintf(tmp, 1024, "%s %s", device_get_nameunit(dev), pnp);
784        devaddq("-", tmp, dev);
785fail:
786        if (pnp != NULL)
787                free(pnp, M_BUS);
788        if (tmp != NULL)
789                free(tmp, M_BUS);
790        return;
791}
792
793/*
794 * Called when there's no match for this device.  This is only called
795 * the first time that no match happens, so we don't keep getting this
796 * message.  Should that prove to be undesirable, we can change it.
797 * This is called when all drivers that can attach to a given bus
798 * decline to accept this device.  Other errrors may not be detected.
799 */
800static void
801devnomatch(device_t dev)
802{
803        devaddq("?", "", dev);
804}
805
806#ifndef __rtems__
807static int
808sysctl_devctl_disable(SYSCTL_HANDLER_ARGS)
809{
810        struct dev_event_info *n1;
811        int dis, error;
812
813        dis = devctl_queue_length == 0;
814        error = sysctl_handle_int(oidp, &dis, 0, req);
815        if (error || !req->newptr)
816                return (error);
817        mtx_lock(&devsoftc.mtx);
818        if (dis) {
819                while (!TAILQ_EMPTY(&devsoftc.devq)) {
820                        n1 = TAILQ_FIRST(&devsoftc.devq);
821                        TAILQ_REMOVE(&devsoftc.devq, n1, dei_link);
822                        free(n1->dei_data, M_BUS);
823                        free(n1, M_BUS);
824                }
825                devsoftc.queued = 0;
826                devctl_queue_length = 0;
827        } else {
828                devctl_queue_length = DEVCTL_DEFAULT_QUEUE_LEN;
829        }
830        mtx_unlock(&devsoftc.mtx);
831        return (0);
832}
833
834static int
835sysctl_devctl_queue(SYSCTL_HANDLER_ARGS)
836{
837        struct dev_event_info *n1;
838        int q, error;
839
840        q = devctl_queue_length;
841        error = sysctl_handle_int(oidp, &q, 0, req);
842        if (error || !req->newptr)
843                return (error);
844        if (q < 0)
845                return (EINVAL);
846        mtx_lock(&devsoftc.mtx);
847        devctl_queue_length = q;
848        while (devsoftc.queued > devctl_queue_length) {
849                n1 = TAILQ_FIRST(&devsoftc.devq);
850                TAILQ_REMOVE(&devsoftc.devq, n1, dei_link);
851                free(n1->dei_data, M_BUS);
852                free(n1, M_BUS);
853                devsoftc.queued--;
854        }
855        mtx_unlock(&devsoftc.mtx);
856        return (0);
857}
858
859/* End of /dev/devctl code */
860#endif /* __rtems__ */
861
862static TAILQ_HEAD(,device)      bus_data_devices;
863static int bus_data_generation = 1;
864
865static kobj_method_t null_methods[] = {
866        KOBJMETHOD_END
867};
868
869DEFINE_CLASS(null, null_methods, 0);
870
871/*
872 * Bus pass implementation
873 */
874
875static driver_list_t passes = TAILQ_HEAD_INITIALIZER(passes);
876int bus_current_pass = BUS_PASS_ROOT;
877
878/**
879 * @internal
880 * @brief Register the pass level of a new driver attachment
881 *
882 * Register a new driver attachment's pass level.  If no driver
883 * attachment with the same pass level has been added, then @p new
884 * will be added to the global passes list.
885 *
886 * @param new           the new driver attachment
887 */
888static void
889driver_register_pass(struct driverlink *new)
890{
891        struct driverlink *dl;
892
893        /* We only consider pass numbers during boot. */
894        if (bus_current_pass == BUS_PASS_DEFAULT)
895                return;
896
897        /*
898         * Walk the passes list.  If we already know about this pass
899         * then there is nothing to do.  If we don't, then insert this
900         * driver link into the list.
901         */
902        TAILQ_FOREACH(dl, &passes, passlink) {
903                if (dl->pass < new->pass)
904                        continue;
905                if (dl->pass == new->pass)
906                        return;
907                TAILQ_INSERT_BEFORE(dl, new, passlink);
908                return;
909        }
910        TAILQ_INSERT_TAIL(&passes, new, passlink);
911}
912
913/**
914 * @brief Raise the current bus pass
915 *
916 * Raise the current bus pass level to @p pass.  Call the BUS_NEW_PASS()
917 * method on the root bus to kick off a new device tree scan for each
918 * new pass level that has at least one driver.
919 */
920void
921bus_set_pass(int pass)
922{
923        struct driverlink *dl;
924
925        if (bus_current_pass > pass)
926                panic("Attempt to lower bus pass level");
927
928        TAILQ_FOREACH(dl, &passes, passlink) {
929                /* Skip pass values below the current pass level. */
930                if (dl->pass <= bus_current_pass)
931                        continue;
932
933                /*
934                 * Bail once we hit a driver with a pass level that is
935                 * too high.
936                 */
937                if (dl->pass > pass)
938                        break;
939
940                /*
941                 * Raise the pass level to the next level and rescan
942                 * the tree.
943                 */
944                bus_current_pass = dl->pass;
945                BUS_NEW_PASS(root_bus);
946        }
947
948        /*
949         * If there isn't a driver registered for the requested pass,
950         * then bus_current_pass might still be less than 'pass'.  Set
951         * it to 'pass' in that case.
952         */
953        if (bus_current_pass < pass)
954                bus_current_pass = pass;
955        KASSERT(bus_current_pass == pass, ("Failed to update bus pass level"));
956}
957
958/*
959 * Devclass implementation
960 */
961
962static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
963
964/**
965 * @internal
966 * @brief Find or create a device class
967 *
968 * If a device class with the name @p classname exists, return it,
969 * otherwise if @p create is non-zero create and return a new device
970 * class.
971 *
972 * If @p parentname is non-NULL, the parent of the devclass is set to
973 * the devclass of that name.
974 *
975 * @param classname     the devclass name to find or create
976 * @param parentname    the parent devclass name or @c NULL
977 * @param create        non-zero to create a devclass
978 */
979static devclass_t
980devclass_find_internal(const char *classname, const char *parentname,
981                       int create)
982{
983        devclass_t dc;
984
985        PDEBUG(("looking for %s", classname));
986        if (!classname)
987                return (NULL);
988
989        TAILQ_FOREACH(dc, &devclasses, link) {
990                if (!strcmp(dc->name, classname))
991                        break;
992        }
993
994        if (create && !dc) {
995                PDEBUG(("creating %s", classname));
996                dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,
997                    M_BUS, M_NOWAIT | M_ZERO);
998                if (!dc)
999                        return (NULL);
1000                dc->parent = NULL;
1001                dc->name = (char*) (dc + 1);
1002                strcpy(dc->name, classname);
1003                TAILQ_INIT(&dc->drivers);
1004                TAILQ_INSERT_TAIL(&devclasses, dc, link);
1005
1006                bus_data_generation_update();
1007        }
1008
1009        /*
1010         * If a parent class is specified, then set that as our parent so
1011         * that this devclass will support drivers for the parent class as
1012         * well.  If the parent class has the same name don't do this though
1013         * as it creates a cycle that can trigger an infinite loop in
1014         * device_probe_child() if a device exists for which there is no
1015         * suitable driver.
1016         */
1017        if (parentname && dc && !dc->parent &&
1018            strcmp(classname, parentname) != 0) {
1019                dc->parent = devclass_find_internal(parentname, NULL, TRUE);
1020                dc->parent->flags |= DC_HAS_CHILDREN;
1021        }
1022
1023        return (dc);
1024}
1025
1026/**
1027 * @brief Create a device class
1028 *
1029 * If a device class with the name @p classname exists, return it,
1030 * otherwise create and return a new device class.
1031 *
1032 * @param classname     the devclass name to find or create
1033 */
1034devclass_t
1035devclass_create(const char *classname)
1036{
1037        return (devclass_find_internal(classname, NULL, TRUE));
1038}
1039
1040/**
1041 * @brief Find a device class
1042 *
1043 * If a device class with the name @p classname exists, return it,
1044 * otherwise return @c NULL.
1045 *
1046 * @param classname     the devclass name to find
1047 */
1048devclass_t
1049devclass_find(const char *classname)
1050{
1051        return (devclass_find_internal(classname, NULL, FALSE));
1052}
1053
1054/**
1055 * @brief Register that a device driver has been added to a devclass
1056 *
1057 * Register that a device driver has been added to a devclass.  This
1058 * is called by devclass_add_driver to accomplish the recursive
1059 * notification of all the children classes of dc, as well as dc.
1060 * Each layer will have BUS_DRIVER_ADDED() called for all instances of
1061 * the devclass.  We do a full search here of the devclass list at
1062 * each iteration level to save storing children-lists in the devclass
1063 * structure.  If we ever move beyond a few dozen devices doing this,
1064 * we may need to reevaluate...
1065 *
1066 * @param dc            the devclass to edit
1067 * @param driver        the driver that was just added
1068 */
1069static void
1070devclass_driver_added(devclass_t dc, driver_t *driver)
1071{
1072        devclass_t parent;
1073        int i;
1074
1075        /*
1076         * Call BUS_DRIVER_ADDED for any existing busses in this class.
1077         */
1078        for (i = 0; i < dc->maxunit; i++)
1079                if (dc->devices[i] && device_is_attached(dc->devices[i]))
1080                        BUS_DRIVER_ADDED(dc->devices[i], driver);
1081
1082        /*
1083         * Walk through the children classes.  Since we only keep a
1084         * single parent pointer around, we walk the entire list of
1085         * devclasses looking for children.  We set the
1086         * DC_HAS_CHILDREN flag when a child devclass is created on
1087         * the parent, so we only walk the list for those devclasses
1088         * that have children.
1089         */
1090        if (!(dc->flags & DC_HAS_CHILDREN))
1091                return;
1092        parent = dc;
1093        TAILQ_FOREACH(dc, &devclasses, link) {
1094                if (dc->parent == parent)
1095                        devclass_driver_added(dc, driver);
1096        }
1097}
1098
1099/**
1100 * @brief Add a device driver to a device class
1101 *
1102 * Add a device driver to a devclass. This is normally called
1103 * automatically by DRIVER_MODULE(). The BUS_DRIVER_ADDED() method of
1104 * all devices in the devclass will be called to allow them to attempt
1105 * to re-probe any unmatched children.
1106 *
1107 * @param dc            the devclass to edit
1108 * @param driver        the driver to register
1109 */
1110static int
1111devclass_add_driver(devclass_t dc, driver_t *driver, int pass, devclass_t *dcp)
1112{
1113        driverlink_t dl;
1114        const char *parentname;
1115
1116        PDEBUG(("%s", DRIVERNAME(driver)));
1117
1118        /* Don't allow invalid pass values. */
1119        if (pass <= BUS_PASS_ROOT)
1120                return (EINVAL);
1121
1122        dl = malloc(sizeof *dl, M_BUS, M_NOWAIT|M_ZERO);
1123        if (!dl)
1124                return (ENOMEM);
1125
1126        /*
1127         * Compile the driver's methods. Also increase the reference count
1128         * so that the class doesn't get freed when the last instance
1129         * goes. This means we can safely use static methods and avoids a
1130         * double-free in devclass_delete_driver.
1131         */
1132        kobj_class_compile((kobj_class_t) driver);
1133
1134        /*
1135         * If the driver has any base classes, make the
1136         * devclass inherit from the devclass of the driver's
1137         * first base class. This will allow the system to
1138         * search for drivers in both devclasses for children
1139         * of a device using this driver.
1140         */
1141        if (driver->baseclasses)
1142                parentname = driver->baseclasses[0]->name;
1143        else
1144                parentname = NULL;
1145        *dcp = devclass_find_internal(driver->name, parentname, TRUE);
1146
1147        dl->driver = driver;
1148        TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
1149        driver->refs++;         /* XXX: kobj_mtx */
1150        dl->pass = pass;
1151        driver_register_pass(dl);
1152
1153        devclass_driver_added(dc, driver);
1154        bus_data_generation_update();
1155        return (0);
1156}
1157
1158/**
1159 * @brief Delete a device driver from a device class
1160 *
1161 * Delete a device driver from a devclass. This is normally called
1162 * automatically by DRIVER_MODULE().
1163 *
1164 * If the driver is currently attached to any devices,
1165 * devclass_delete_driver() will first attempt to detach from each
1166 * device. If one of the detach calls fails, the driver will not be
1167 * deleted.
1168 *
1169 * @param dc            the devclass to edit
1170 * @param driver        the driver to unregister
1171 */
1172static int
1173devclass_delete_driver(devclass_t busclass, driver_t *driver)
1174{
1175        devclass_t dc = devclass_find(driver->name);
1176        driverlink_t dl;
1177        device_t dev;
1178        int i;
1179        int error;
1180
1181        PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
1182
1183        if (!dc)
1184                return (0);
1185
1186        /*
1187         * Find the link structure in the bus' list of drivers.
1188         */
1189        TAILQ_FOREACH(dl, &busclass->drivers, link) {
1190                if (dl->driver == driver)
1191                        break;
1192        }
1193
1194        if (!dl) {
1195                PDEBUG(("%s not found in %s list", driver->name,
1196                    busclass->name));
1197                return (ENOENT);
1198        }
1199
1200        /*
1201         * Disassociate from any devices.  We iterate through all the
1202         * devices in the devclass of the driver and detach any which are
1203         * using the driver and which have a parent in the devclass which
1204         * we are deleting from.
1205         *
1206         * Note that since a driver can be in multiple devclasses, we
1207         * should not detach devices which are not children of devices in
1208         * the affected devclass.
1209         */
1210        for (i = 0; i < dc->maxunit; i++) {
1211                if (dc->devices[i]) {
1212                        dev = dc->devices[i];
1213                        if (dev->driver == driver && dev->parent &&
1214                            dev->parent->devclass == busclass) {
1215                                if ((error = device_detach(dev)) != 0)
1216                                        return (error);
1217                                device_set_driver(dev, NULL);
1218                        }
1219                }
1220        }
1221
1222        TAILQ_REMOVE(&busclass->drivers, dl, link);
1223        free(dl, M_BUS);
1224
1225        /* XXX: kobj_mtx */
1226        driver->refs--;
1227        if (driver->refs == 0)
1228                kobj_class_free((kobj_class_t) driver);
1229
1230        bus_data_generation_update();
1231        return (0);
1232}
1233
1234/**
1235 * @brief Quiesces a set of device drivers from a device class
1236 *
1237 * Quiesce a device driver from a devclass. This is normally called
1238 * automatically by DRIVER_MODULE().
1239 *
1240 * If the driver is currently attached to any devices,
1241 * devclass_quiesece_driver() will first attempt to quiesce each
1242 * device.
1243 *
1244 * @param dc            the devclass to edit
1245 * @param driver        the driver to unregister
1246 */
1247static int
1248devclass_quiesce_driver(devclass_t busclass, driver_t *driver)
1249{
1250        devclass_t dc = devclass_find(driver->name);
1251        driverlink_t dl;
1252        device_t dev;
1253        int i;
1254        int error;
1255
1256        PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
1257
1258        if (!dc)
1259                return (0);
1260
1261        /*
1262         * Find the link structure in the bus' list of drivers.
1263         */
1264        TAILQ_FOREACH(dl, &busclass->drivers, link) {
1265                if (dl->driver == driver)
1266                        break;
1267        }
1268
1269        if (!dl) {
1270                PDEBUG(("%s not found in %s list", driver->name,
1271                    busclass->name));
1272                return (ENOENT);
1273        }
1274
1275        /*
1276         * Quiesce all devices.  We iterate through all the devices in
1277         * the devclass of the driver and quiesce any which are using
1278         * the driver and which have a parent in the devclass which we
1279         * are quiescing.
1280         *
1281         * Note that since a driver can be in multiple devclasses, we
1282         * should not quiesce devices which are not children of
1283         * devices in the affected devclass.
1284         */
1285        for (i = 0; i < dc->maxunit; i++) {
1286                if (dc->devices[i]) {
1287                        dev = dc->devices[i];
1288                        if (dev->driver == driver && dev->parent &&
1289                            dev->parent->devclass == busclass) {
1290                                if ((error = device_quiesce(dev)) != 0)
1291                                        return (error);
1292                        }
1293                }
1294        }
1295
1296        return (0);
1297}
1298
1299/**
1300 * @internal
1301 */
1302static driverlink_t
1303devclass_find_driver_internal(devclass_t dc, const char *classname)
1304{
1305        driverlink_t dl;
1306
1307        PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc)));
1308
1309        TAILQ_FOREACH(dl, &dc->drivers, link) {
1310                if (!strcmp(dl->driver->name, classname))
1311                        return (dl);
1312        }
1313
1314        PDEBUG(("not found"));
1315        return (NULL);
1316}
1317
1318/**
1319 * @brief Return the name of the devclass
1320 */
1321const char *
1322devclass_get_name(devclass_t dc)
1323{
1324        return (dc->name);
1325}
1326
1327/**
1328 * @brief Find a device given a unit number
1329 *
1330 * @param dc            the devclass to search
1331 * @param unit          the unit number to search for
1332 *
1333 * @returns             the device with the given unit number or @c
1334 *                      NULL if there is no such device
1335 */
1336device_t
1337devclass_get_device(devclass_t dc, int unit)
1338{
1339        if (dc == NULL || unit < 0 || unit >= dc->maxunit)
1340                return (NULL);
1341        return (dc->devices[unit]);
1342}
1343
1344/**
1345 * @brief Find the softc field of a device given a unit number
1346 *
1347 * @param dc            the devclass to search
1348 * @param unit          the unit number to search for
1349 *
1350 * @returns             the softc field of the device with the given
1351 *                      unit number or @c NULL if there is no such
1352 *                      device
1353 */
1354void *
1355devclass_get_softc(devclass_t dc, int unit)
1356{
1357        device_t dev;
1358
1359        dev = devclass_get_device(dc, unit);
1360        if (!dev)
1361                return (NULL);
1362
1363        return (device_get_softc(dev));
1364}
1365
1366/**
1367 * @brief Get a list of devices in the devclass
1368 *
1369 * An array containing a list of all the devices in the given devclass
1370 * is allocated and returned in @p *devlistp. The number of devices
1371 * in the array is returned in @p *devcountp. The caller should free
1372 * the array using @c free(p, M_TEMP), even if @p *devcountp is 0.
1373 *
1374 * @param dc            the devclass to examine
1375 * @param devlistp      points at location for array pointer return
1376 *                      value
1377 * @param devcountp     points at location for array size return value
1378 *
1379 * @retval 0            success
1380 * @retval ENOMEM       the array allocation failed
1381 */
1382int
1383devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp)
1384{
1385        int count, i;
1386        device_t *list;
1387
1388        count = devclass_get_count(dc);
1389        list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
1390        if (!list)
1391                return (ENOMEM);
1392
1393        count = 0;
1394        for (i = 0; i < dc->maxunit; i++) {
1395                if (dc->devices[i]) {
1396                        list[count] = dc->devices[i];
1397                        count++;
1398                }
1399        }
1400
1401        *devlistp = list;
1402        *devcountp = count;
1403
1404        return (0);
1405}
1406
1407/**
1408 * @brief Get a list of drivers in the devclass
1409 *
1410 * An array containing a list of pointers to all the drivers in the
1411 * given devclass is allocated and returned in @p *listp.  The number
1412 * of drivers in the array is returned in @p *countp. The caller should
1413 * free the array using @c free(p, M_TEMP).
1414 *
1415 * @param dc            the devclass to examine
1416 * @param listp         gives location for array pointer return value
1417 * @param countp        gives location for number of array elements
1418 *                      return value
1419 *
1420 * @retval 0            success
1421 * @retval ENOMEM       the array allocation failed
1422 */
1423int
1424devclass_get_drivers(devclass_t dc, driver_t ***listp, int *countp)
1425{
1426        driverlink_t dl;
1427        driver_t **list;
1428        int count;
1429
1430        count = 0;
1431        TAILQ_FOREACH(dl, &dc->drivers, link)
1432                count++;
1433        list = malloc(count * sizeof(driver_t *), M_TEMP, M_NOWAIT);
1434        if (list == NULL)
1435                return (ENOMEM);
1436
1437        count = 0;
1438        TAILQ_FOREACH(dl, &dc->drivers, link) {
1439                list[count] = dl->driver;
1440                count++;
1441        }
1442        *listp = list;
1443        *countp = count;
1444
1445        return (0);
1446}
1447
1448/**
1449 * @brief Get the number of devices in a devclass
1450 *
1451 * @param dc            the devclass to examine
1452 */
1453int
1454devclass_get_count(devclass_t dc)
1455{
1456        int count, i;
1457
1458        count = 0;
1459        for (i = 0; i < dc->maxunit; i++)
1460                if (dc->devices[i])
1461                        count++;
1462        return (count);
1463}
1464
1465/**
1466 * @brief Get the maximum unit number used in a devclass
1467 *
1468 * Note that this is one greater than the highest currently-allocated
1469 * unit.  If a null devclass_t is passed in, -1 is returned to indicate
1470 * that not even the devclass has been allocated yet.
1471 *
1472 * @param dc            the devclass to examine
1473 */
1474int
1475devclass_get_maxunit(devclass_t dc)
1476{
1477        if (dc == NULL)
1478                return (-1);
1479        return (dc->maxunit);
1480}
1481
1482/**
1483 * @brief Find a free unit number in a devclass
1484 *
1485 * This function searches for the first unused unit number greater
1486 * that or equal to @p unit.
1487 *
1488 * @param dc            the devclass to examine
1489 * @param unit          the first unit number to check
1490 */
1491int
1492devclass_find_free_unit(devclass_t dc, int unit)
1493{
1494        if (dc == NULL)
1495                return (unit);
1496        while (unit < dc->maxunit && dc->devices[unit] != NULL)
1497                unit++;
1498        return (unit);
1499}
1500
1501/**
1502 * @brief Set the parent of a devclass
1503 *
1504 * The parent class is normally initialised automatically by
1505 * DRIVER_MODULE().
1506 *
1507 * @param dc            the devclass to edit
1508 * @param pdc           the new parent devclass
1509 */
1510void
1511devclass_set_parent(devclass_t dc, devclass_t pdc)
1512{
1513        dc->parent = pdc;
1514}
1515
1516/**
1517 * @brief Get the parent of a devclass
1518 *
1519 * @param dc            the devclass to examine
1520 */
1521devclass_t
1522devclass_get_parent(devclass_t dc)
1523{
1524        return (dc->parent);
1525}
1526
1527struct sysctl_ctx_list *
1528devclass_get_sysctl_ctx(devclass_t dc)
1529{
1530#ifndef __rtems__
1531        return (&dc->sysctl_ctx);
1532#else /* __rtems__ */
1533        return (NULL);
1534#endif /* __rtems__ */
1535}
1536
1537struct sysctl_oid *
1538devclass_get_sysctl_tree(devclass_t dc)
1539{
1540#ifndef __rtems__
1541        return (dc->sysctl_tree);
1542#else /* __rtems__ */
1543        return (NULL);
1544#endif /* __rtems__ */
1545}
1546
1547/**
1548 * @internal
1549 * @brief Allocate a unit number
1550 *
1551 * On entry, @p *unitp is the desired unit number (or @c -1 if any
1552 * will do). The allocated unit number is returned in @p *unitp.
1553
1554 * @param dc            the devclass to allocate from
1555 * @param unitp         points at the location for the allocated unit
1556 *                      number
1557 *
1558 * @retval 0            success
1559 * @retval EEXIST       the requested unit number is already allocated
1560 * @retval ENOMEM       memory allocation failure
1561 */
1562static int
1563devclass_alloc_unit(devclass_t dc, device_t dev, int *unitp)
1564{
1565        const char *s;
1566        int unit = *unitp;
1567
1568        PDEBUG(("unit %d in devclass %s", unit, DEVCLANAME(dc)));
1569
1570        /* Ask the parent bus if it wants to wire this device. */
1571        if (unit == -1)
1572                BUS_HINT_DEVICE_UNIT(device_get_parent(dev), dev, dc->name,
1573                    &unit);
1574
1575        /* If we were given a wired unit number, check for existing device */
1576        /* XXX imp XXX */
1577        if (unit != -1) {
1578                if (unit >= 0 && unit < dc->maxunit &&
1579                    dc->devices[unit] != NULL) {
1580                        if (bootverbose)
1581                                printf("%s: %s%d already exists; skipping it\n",
1582                                    dc->name, dc->name, *unitp);
1583                        return (EEXIST);
1584                }
1585        } else {
1586                /* Unwired device, find the next available slot for it */
1587                unit = 0;
1588                for (unit = 0;; unit++) {
1589#ifndef __rtems__
1590                        /* If there is an "at" hint for a unit then skip it. */
1591                        if (resource_string_value(dc->name, unit, "at", &s) ==
1592                            0)
1593                                continue;
1594#endif /* __rtems__ */
1595
1596                        /* If this device slot is already in use, skip it. */
1597                        if (unit < dc->maxunit && dc->devices[unit] != NULL)
1598                                continue;
1599
1600                        break;
1601                }
1602        }
1603
1604        /*
1605         * We've selected a unit beyond the length of the table, so let's
1606         * extend the table to make room for all units up to and including
1607         * this one.
1608         */
1609        if (unit >= dc->maxunit) {
1610                device_t *newlist, *oldlist;
1611                int newsize;
1612
1613                oldlist = dc->devices;
1614                newsize = roundup((unit + 1), MINALLOCSIZE / sizeof(device_t));
1615                newlist = malloc(sizeof(device_t) * newsize, M_BUS, M_NOWAIT);
1616                if (!newlist)
1617                        return (ENOMEM);
1618                if (oldlist != NULL)
1619                        bcopy(oldlist, newlist, sizeof(device_t) * dc->maxunit);
1620                bzero(newlist + dc->maxunit,
1621                    sizeof(device_t) * (newsize - dc->maxunit));
1622                dc->devices = newlist;
1623                dc->maxunit = newsize;
1624                if (oldlist != NULL)
1625                        free(oldlist, M_BUS);
1626        }
1627        PDEBUG(("now: unit %d in devclass %s", unit, DEVCLANAME(dc)));
1628
1629        *unitp = unit;
1630        return (0);
1631}
1632
1633/**
1634 * @internal
1635 * @brief Add a device to a devclass
1636 *
1637 * A unit number is allocated for the device (using the device's
1638 * preferred unit number if any) and the device is registered in the
1639 * devclass. This allows the device to be looked up by its unit
1640 * number, e.g. by decoding a dev_t minor number.
1641 *
1642 * @param dc            the devclass to add to
1643 * @param dev           the device to add
1644 *
1645 * @retval 0            success
1646 * @retval EEXIST       the requested unit number is already allocated
1647 * @retval ENOMEM       memory allocation failure
1648 */
1649static int
1650devclass_add_device(devclass_t dc, device_t dev)
1651{
1652        int buflen, error;
1653
1654        PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
1655
1656        buflen = snprintf(NULL, 0, "%s%d$", dc->name, INT_MAX);
1657        if (buflen < 0)
1658                return (ENOMEM);
1659        dev->nameunit = malloc(buflen, M_BUS, M_NOWAIT|M_ZERO);
1660        if (!dev->nameunit)
1661                return (ENOMEM);
1662
1663        if ((error = devclass_alloc_unit(dc, dev, &dev->unit)) != 0) {
1664                free(dev->nameunit, M_BUS);
1665                dev->nameunit = NULL;
1666                return (error);
1667        }
1668        dc->devices[dev->unit] = dev;
1669        dev->devclass = dc;
1670        snprintf(dev->nameunit, buflen, "%s%d", dc->name, dev->unit);
1671
1672        return (0);
1673}
1674
1675/**
1676 * @internal
1677 * @brief Delete a device from a devclass
1678 *
1679 * The device is removed from the devclass's device list and its unit
1680 * number is freed.
1681
1682 * @param dc            the devclass to delete from
1683 * @param dev           the device to delete
1684 *
1685 * @retval 0            success
1686 */
1687static int
1688devclass_delete_device(devclass_t dc, device_t dev)
1689{
1690        if (!dc || !dev)
1691                return (0);
1692
1693        PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
1694
1695        if (dev->devclass != dc || dc->devices[dev->unit] != dev)
1696                panic("devclass_delete_device: inconsistent device class");
1697        dc->devices[dev->unit] = NULL;
1698        if (dev->flags & DF_WILDCARD)
1699                dev->unit = -1;
1700        dev->devclass = NULL;
1701        free(dev->nameunit, M_BUS);
1702        dev->nameunit = NULL;
1703
1704        return (0);
1705}
1706
1707/**
1708 * @internal
1709 * @brief Make a new device and add it as a child of @p parent
1710 *
1711 * @param parent        the parent of the new device
1712 * @param name          the devclass name of the new device or @c NULL
1713 *                      to leave the devclass unspecified
1714 * @parem unit          the unit number of the new device of @c -1 to
1715 *                      leave the unit number unspecified
1716 *
1717 * @returns the new device
1718 */
1719static device_t
1720make_device(device_t parent, const char *name, int unit)
1721{
1722        device_t dev;
1723        devclass_t dc;
1724
1725        PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
1726
1727        if (name) {
1728                dc = devclass_find_internal(name, NULL, TRUE);
1729                if (!dc) {
1730                        printf("make_device: can't find device class %s\n",
1731                            name);
1732                        return (NULL);
1733                }
1734        } else {
1735                dc = NULL;
1736        }
1737
1738        dev = malloc(sizeof(struct device), M_BUS, M_NOWAIT|M_ZERO);
1739        if (!dev)
1740                return (NULL);
1741
1742        dev->parent = parent;
1743        TAILQ_INIT(&dev->children);
1744        kobj_init((kobj_t) dev, &null_class);
1745        dev->driver = NULL;
1746        dev->devclass = NULL;
1747        dev->unit = unit;
1748        dev->nameunit = NULL;
1749        dev->desc = NULL;
1750        dev->busy = 0;
1751        dev->devflags = 0;
1752        dev->flags = DF_ENABLED;
1753        dev->order = 0;
1754        if (unit == -1)
1755                dev->flags |= DF_WILDCARD;
1756        if (name) {
1757                dev->flags |= DF_FIXEDCLASS;
1758                if (devclass_add_device(dc, dev)) {
1759                        kobj_delete((kobj_t) dev, M_BUS);
1760                        return (NULL);
1761                }
1762        }
1763        dev->ivars = NULL;
1764        dev->softc = NULL;
1765
1766        dev->state = DS_NOTPRESENT;
1767
1768        TAILQ_INSERT_TAIL(&bus_data_devices, dev, devlink);
1769        bus_data_generation_update();
1770
1771        return (dev);
1772}
1773
1774/**
1775 * @internal
1776 * @brief Print a description of a device.
1777 */
1778static int
1779device_print_child(device_t dev, device_t child)
1780{
1781        int retval = 0;
1782
1783        if (device_is_alive(child))
1784                retval += BUS_PRINT_CHILD(dev, child);
1785        else
1786                retval += device_printf(child, " not found\n");
1787
1788        return (retval);
1789}
1790
1791/**
1792 * @brief Create a new device
1793 *
1794 * This creates a new device and adds it as a child of an existing
1795 * parent device. The new device will be added after the last existing
1796 * child with order zero.
1797 *
1798 * @param dev           the device which will be the parent of the
1799 *                      new child device
1800 * @param name          devclass name for new device or @c NULL if not
1801 *                      specified
1802 * @param unit          unit number for new device or @c -1 if not
1803 *                      specified
1804 *
1805 * @returns             the new device
1806 */
1807device_t
1808device_add_child(device_t dev, const char *name, int unit)
1809{
1810        return (device_add_child_ordered(dev, 0, name, unit));
1811}
1812
1813/**
1814 * @brief Create a new device
1815 *
1816 * This creates a new device and adds it as a child of an existing
1817 * parent device. The new device will be added after the last existing
1818 * child with the same order.
1819 *
1820 * @param dev           the device which will be the parent of the
1821 *                      new child device
1822 * @param order         a value which is used to partially sort the
1823 *                      children of @p dev - devices created using
1824 *                      lower values of @p order appear first in @p
1825 *                      dev's list of children
1826 * @param name          devclass name for new device or @c NULL if not
1827 *                      specified
1828 * @param unit          unit number for new device or @c -1 if not
1829 *                      specified
1830 *
1831 * @returns             the new device
1832 */
1833device_t
1834device_add_child_ordered(device_t dev, u_int order, const char *name, int unit)
1835{
1836        device_t child;
1837        device_t place;
1838
1839        PDEBUG(("%s at %s with order %u as unit %d",
1840            name, DEVICENAME(dev), order, unit));
1841
1842        child = make_device(dev, name, unit);
1843        if (child == NULL)
1844                return (child);
1845        child->order = order;
1846
1847        TAILQ_FOREACH(place, &dev->children, link) {
1848                if (place->order > order)
1849                        break;
1850        }
1851
1852        if (place) {
1853                /*
1854                 * The device 'place' is the first device whose order is
1855                 * greater than the new child.
1856                 */
1857                TAILQ_INSERT_BEFORE(place, child, link);
1858        } else {
1859                /*
1860                 * The new child's order is greater or equal to the order of
1861                 * any existing device. Add the child to the tail of the list.
1862                 */
1863                TAILQ_INSERT_TAIL(&dev->children, child, link);
1864        }
1865
1866        bus_data_generation_update();
1867        return (child);
1868}
1869
1870/**
1871 * @brief Delete a device
1872 *
1873 * This function deletes a device along with all of its children. If
1874 * the device currently has a driver attached to it, the device is
1875 * detached first using device_detach().
1876 *
1877 * @param dev           the parent device
1878 * @param child         the device to delete
1879 *
1880 * @retval 0            success
1881 * @retval non-zero     a unit error code describing the error
1882 */
1883int
1884device_delete_child(device_t dev, device_t child)
1885{
1886        int error;
1887        device_t grandchild;
1888
1889        PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
1890
1891        /* remove children first */
1892        while ( (grandchild = TAILQ_FIRST(&child->children)) ) {
1893                error = device_delete_child(child, grandchild);
1894                if (error)
1895                        return (error);
1896        }
1897
1898        if ((error = device_detach(child)) != 0)
1899                return (error);
1900        if (child->devclass)
1901                devclass_delete_device(child->devclass, child);
1902        TAILQ_REMOVE(&dev->children, child, link);
1903        TAILQ_REMOVE(&bus_data_devices, child, devlink);
1904        kobj_delete((kobj_t) child, M_BUS);
1905
1906        bus_data_generation_update();
1907        return (0);
1908}
1909
1910/**
1911 * @brief Find a device given a unit number
1912 *
1913 * This is similar to devclass_get_devices() but only searches for
1914 * devices which have @p dev as a parent.
1915 *
1916 * @param dev           the parent device to search
1917 * @param unit          the unit number to search for.  If the unit is -1,
1918 *                      return the first child of @p dev which has name
1919 *                      @p classname (that is, the one with the lowest unit.)
1920 *
1921 * @returns             the device with the given unit number or @c
1922 *                      NULL if there is no such device
1923 */
1924device_t
1925device_find_child(device_t dev, const char *classname, int unit)
1926{
1927        devclass_t dc;
1928        device_t child;
1929
1930        dc = devclass_find(classname);
1931        if (!dc)
1932                return (NULL);
1933
1934        if (unit != -1) {
1935                child = devclass_get_device(dc, unit);
1936                if (child && child->parent == dev)
1937                        return (child);
1938        } else {
1939                for (unit = 0; unit < devclass_get_maxunit(dc); unit++) {
1940                        child = devclass_get_device(dc, unit);
1941                        if (child && child->parent == dev)
1942                                return (child);
1943                }
1944        }
1945        return (NULL);
1946}
1947
1948/**
1949 * @internal
1950 */
1951static driverlink_t
1952first_matching_driver(devclass_t dc, device_t dev)
1953{
1954        if (dev->devclass)
1955                return (devclass_find_driver_internal(dc, dev->devclass->name));
1956        return (TAILQ_FIRST(&dc->drivers));
1957}
1958
1959/**
1960 * @internal
1961 */
1962static driverlink_t
1963next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
1964{
1965        if (dev->devclass) {
1966                driverlink_t dl;
1967                for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link))
1968                        if (!strcmp(dev->devclass->name, dl->driver->name))
1969                                return (dl);
1970                return (NULL);
1971        }
1972        return (TAILQ_NEXT(last, link));
1973}
1974
1975/**
1976 * @internal
1977 */
1978int
1979device_probe_child(device_t dev, device_t child)
1980{
1981        devclass_t dc;
1982        driverlink_t best = NULL;
1983        driverlink_t dl;
1984        int result, pri = 0;
1985        int hasclass = (child->devclass != NULL);
1986
1987        GIANT_REQUIRED;
1988
1989        dc = dev->devclass;
1990        if (!dc)
1991                panic("device_probe_child: parent device has no devclass");
1992
1993        /*
1994         * If the state is already probed, then return.  However, don't
1995         * return if we can rebid this object.
1996         */
1997        if (child->state == DS_ALIVE && (child->flags & DF_REBID) == 0)
1998                return (0);
1999
2000        for (; dc; dc = dc->parent) {
2001                for (dl = first_matching_driver(dc, child);
2002                     dl;
2003                     dl = next_matching_driver(dc, child, dl)) {
2004
2005                        /* If this driver's pass is too high, then ignore it. */
2006                        if (dl->pass > bus_current_pass)
2007                                continue;
2008
2009                        PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
2010                        device_set_driver(child, dl->driver);
2011                        if (!hasclass) {
2012                                if (device_set_devclass(child, dl->driver->name)) {
2013                                        printf("driver bug: Unable to set devclass (devname: %s)\n",
2014                                            (child ? device_get_name(child) :
2015                                                "no device"));
2016                                        device_set_driver(child, NULL);
2017                                        continue;
2018                                }
2019                        }
2020
2021#ifndef __rtems__
2022                        /* Fetch any flags for the device before probing. */
2023                        resource_int_value(dl->driver->name, child->unit,
2024                            "flags", &child->devflags);
2025#endif /* __rtems__ */
2026
2027                        result = DEVICE_PROBE(child);
2028
2029                        /* Reset flags and devclass before the next probe. */
2030                        child->devflags = 0;
2031                        if (!hasclass)
2032                                device_set_devclass(child, NULL);
2033
2034                        /*
2035                         * If the driver returns SUCCESS, there can be
2036                         * no higher match for this device.
2037                         */
2038                        if (result == 0) {
2039                                best = dl;
2040                                pri = 0;
2041                                break;
2042                        }
2043
2044                        /*
2045                         * The driver returned an error so it
2046                         * certainly doesn't match.
2047                         */
2048                        if (result > 0) {
2049                                device_set_driver(child, NULL);
2050                                continue;
2051                        }
2052
2053                        /*
2054                         * A priority lower than SUCCESS, remember the
2055                         * best matching driver. Initialise the value
2056                         * of pri for the first match.
2057                         */
2058                        if (best == NULL || result > pri) {
2059                                /*
2060                                 * Probes that return BUS_PROBE_NOWILDCARD
2061                                 * or lower only match when they are set
2062                                 * in stone by the parent bus.
2063                                 */
2064                                if (result <= BUS_PROBE_NOWILDCARD &&
2065                                    child->flags & DF_WILDCARD)
2066                                        continue;
2067                                best = dl;
2068                                pri = result;
2069                                continue;
2070                        }
2071                }
2072                /*
2073                 * If we have an unambiguous match in this devclass,
2074                 * don't look in the parent.
2075                 */
2076                if (best && pri == 0)
2077                        break;
2078        }
2079
2080        /*
2081         * If we found a driver, change state and initialise the devclass.
2082         */
2083        /* XXX What happens if we rebid and got no best? */
2084        if (best) {
2085                /*
2086                 * If this device was atached, and we were asked to
2087                 * rescan, and it is a different driver, then we have
2088                 * to detach the old driver and reattach this new one.
2089                 * Note, we don't have to check for DF_REBID here
2090                 * because if the state is > DS_ALIVE, we know it must
2091                 * be.
2092                 *
2093                 * This assumes that all DF_REBID drivers can have
2094                 * their probe routine called at any time and that
2095                 * they are idempotent as well as completely benign in
2096                 * normal operations.
2097                 *
2098                 * We also have to make sure that the detach
2099                 * succeeded, otherwise we fail the operation (or
2100                 * maybe it should just fail silently?  I'm torn).
2101                 */
2102                if (child->state > DS_ALIVE && best->driver != child->driver)
2103                        if ((result = device_detach(dev)) != 0)
2104                                return (result);
2105
2106                /* Set the winning driver, devclass, and flags. */
2107                if (!child->devclass) {
2108                        result = device_set_devclass(child, best->driver->name);
2109                        if (result != 0)
2110                                return (result);
2111                }
2112                device_set_driver(child, best->driver);
2113#ifndef __rtems__
2114                resource_int_value(best->driver->name, child->unit,
2115                    "flags", &child->devflags);
2116#endif /* __rtems__ */
2117
2118                if (pri < 0) {
2119                        /*
2120                         * A bit bogus. Call the probe method again to make
2121                         * sure that we have the right description.
2122                         */
2123                        DEVICE_PROBE(child);
2124#if 0
2125                        child->flags |= DF_REBID;
2126#endif
2127                } else
2128                        child->flags &= ~DF_REBID;
2129                child->state = DS_ALIVE;
2130
2131                bus_data_generation_update();
2132                return (0);
2133        }
2134
2135        return (ENXIO);
2136}
2137
2138/**
2139 * @brief Return the parent of a device
2140 */
2141device_t
2142device_get_parent(device_t dev)
2143{
2144        return (dev->parent);
2145}
2146
2147/**
2148 * @brief Get a list of children of a device
2149 *
2150 * An array containing a list of all the children of the given device
2151 * is allocated and returned in @p *devlistp. The number of devices
2152 * in the array is returned in @p *devcountp. The caller should free
2153 * the array using @c free(p, M_TEMP).
2154 *
2155 * @param dev           the device to examine
2156 * @param devlistp      points at location for array pointer return
2157 *                      value
2158 * @param devcountp     points at location for array size return value
2159 *
2160 * @retval 0            success
2161 * @retval ENOMEM       the array allocation failed
2162 */
2163int
2164device_get_children(device_t dev, device_t **devlistp, int *devcountp)
2165{
2166        int count;
2167        device_t child;
2168        device_t *list;
2169
2170        count = 0;
2171        TAILQ_FOREACH(child, &dev->children, link) {
2172                count++;
2173        }
2174
2175#ifdef __rtems__
2176        /* malloc(0) may return NULL */
2177        if (count != 0) {
2178#endif /* __rtems__ */
2179        list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
2180        if (!list)
2181                return (ENOMEM);
2182
2183        count = 0;
2184        TAILQ_FOREACH(child, &dev->children, link) {
2185                list[count] = child;
2186                count++;
2187        }
2188#ifdef __rtems__
2189        } else {
2190                list = NULL;
2191        }
2192#endif /* __rtems__ */
2193
2194        *devlistp = list;
2195        *devcountp = count;
2196
2197        return (0);
2198}
2199
2200/**
2201 * @brief Return the current driver for the device or @c NULL if there
2202 * is no driver currently attached
2203 */
2204driver_t *
2205device_get_driver(device_t dev)
2206{
2207        return (dev->driver);
2208}
2209
2210/**
2211 * @brief Return the current devclass for the device or @c NULL if
2212 * there is none.
2213 */
2214devclass_t
2215device_get_devclass(device_t dev)
2216{
2217        return (dev->devclass);
2218}
2219
2220/**
2221 * @brief Return the name of the device's devclass or @c NULL if there
2222 * is none.
2223 */
2224const char *
2225device_get_name(device_t dev)
2226{
2227        if (dev != NULL && dev->devclass)
2228                return (devclass_get_name(dev->devclass));
2229        return (NULL);
2230}
2231
2232/**
2233 * @brief Return a string containing the device's devclass name
2234 * followed by an ascii representation of the device's unit number
2235 * (e.g. @c "foo2").
2236 */
2237const char *
2238device_get_nameunit(device_t dev)
2239{
2240        return (dev->nameunit);
2241}
2242
2243/**
2244 * @brief Return the device's unit number.
2245 */
2246int
2247device_get_unit(device_t dev)
2248{
2249        return (dev->unit);
2250}
2251
2252/**
2253 * @brief Return the device's description string
2254 */
2255const char *
2256device_get_desc(device_t dev)
2257{
2258        return (dev->desc);
2259}
2260
2261/**
2262 * @brief Return the device's flags
2263 */
2264u_int32_t
2265device_get_flags(device_t dev)
2266{
2267        return (dev->devflags);
2268}
2269
2270struct sysctl_ctx_list *
2271device_get_sysctl_ctx(device_t dev)
2272{
2273#ifndef __rtems__
2274        return (&dev->sysctl_ctx);
2275#else /* __rtems__ */
2276        return (NULL);
2277#endif /* __rtems__ */
2278}
2279
2280struct sysctl_oid *
2281device_get_sysctl_tree(device_t dev)
2282{
2283#ifndef __rtems__
2284        return (dev->sysctl_tree);
2285#else /* __rtems__ */
2286        return (NULL);
2287#endif /* __rtems__ */
2288}
2289
2290/**
2291 * @brief Print the name of the device followed by a colon and a space
2292 *
2293 * @returns the number of characters printed
2294 */
2295int
2296device_print_prettyname(device_t dev)
2297{
2298        const char *name = device_get_name(dev);
2299
2300        if (name == NULL)
2301                return (printf("unknown: "));
2302        return (printf("%s%d: ", name, device_get_unit(dev)));
2303}
2304
2305/**
2306 * @brief Print the name of the device followed by a colon, a space
2307 * and the result of calling vprintf() with the value of @p fmt and
2308 * the following arguments.
2309 *
2310 * @returns the number of characters printed
2311 */
2312int
2313device_printf(device_t dev, const char * fmt, ...)
2314{
2315        va_list ap;
2316        int retval;
2317
2318        retval = device_print_prettyname(dev);
2319        va_start(ap, fmt);
2320        retval += vprintf(fmt, ap);
2321        va_end(ap);
2322        return (retval);
2323}
2324
2325/**
2326 * @internal
2327 */
2328static void
2329device_set_desc_internal(device_t dev, const char* desc, int copy)
2330{
2331        if (dev->desc && (dev->flags & DF_DESCMALLOCED)) {
2332                free(dev->desc, M_BUS);
2333                dev->flags &= ~DF_DESCMALLOCED;
2334                dev->desc = NULL;
2335        }
2336
2337        if (copy && desc) {
2338                dev->desc = malloc(strlen(desc) + 1, M_BUS, M_NOWAIT);
2339                if (dev->desc) {
2340                        strcpy(dev->desc, desc);
2341                        dev->flags |= DF_DESCMALLOCED;
2342                }
2343        } else {
2344                /* Avoid a -Wcast-qual warning */
2345                dev->desc = (char *)(uintptr_t) desc;
2346        }
2347
2348        bus_data_generation_update();
2349}
2350
2351/**
2352 * @brief Set the device's description
2353 *
2354 * The value of @c desc should be a string constant that will not
2355 * change (at least until the description is changed in a subsequent
2356 * call to device_set_desc() or device_set_desc_copy()).
2357 */
2358void
2359device_set_desc(device_t dev, const char* desc)
2360{
2361        device_set_desc_internal(dev, desc, FALSE);
2362}
2363
2364/**
2365 * @brief Set the device's description
2366 *
2367 * The string pointed to by @c desc is copied. Use this function if
2368 * the device description is generated, (e.g. with sprintf()).
2369 */
2370void
2371device_set_desc_copy(device_t dev, const char* desc)
2372{
2373        device_set_desc_internal(dev, desc, TRUE);
2374}
2375
2376/**
2377 * @brief Set the device's flags
2378 */
2379void
2380device_set_flags(device_t dev, u_int32_t flags)
2381{
2382        dev->devflags = flags;
2383}
2384
2385/**
2386 * @brief Return the device's softc field
2387 *
2388 * The softc is allocated and zeroed when a driver is attached, based
2389 * on the size field of the driver.
2390 */
2391void *
2392device_get_softc(device_t dev)
2393{
2394        return (dev->softc);
2395}
2396
2397/**
2398 * @brief Set the device's softc field
2399 *
2400 * Most drivers do not need to use this since the softc is allocated
2401 * automatically when the driver is attached.
2402 */
2403void
2404device_set_softc(device_t dev, void *softc)
2405{
2406        if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC))
2407                free(dev->softc, M_BUS_SC);
2408        dev->softc = softc;
2409        if (dev->softc)
2410                dev->flags |= DF_EXTERNALSOFTC;
2411        else
2412                dev->flags &= ~DF_EXTERNALSOFTC;
2413}
2414
2415/**
2416 * @brief Get the device's ivars field
2417 *
2418 * The ivars field is used by the parent device to store per-device
2419 * state (e.g. the physical location of the device or a list of
2420 * resources).
2421 */
2422void *
2423device_get_ivars(device_t dev)
2424{
2425
2426        KASSERT(dev != NULL, ("device_get_ivars(NULL, ...)"));
2427        return (dev->ivars);
2428}
2429
2430/**
2431 * @brief Set the device's ivars field
2432 */
2433void
2434device_set_ivars(device_t dev, void * ivars)
2435{
2436
2437        KASSERT(dev != NULL, ("device_set_ivars(NULL, ...)"));
2438        dev->ivars = ivars;
2439}
2440
2441/**
2442 * @brief Return the device's state
2443 */
2444device_state_t
2445device_get_state(device_t dev)
2446{
2447        return (dev->state);
2448}
2449
2450/**
2451 * @brief Set the DF_ENABLED flag for the device
2452 */
2453void
2454device_enable(device_t dev)
2455{
2456        dev->flags |= DF_ENABLED;
2457}
2458
2459/**
2460 * @brief Clear the DF_ENABLED flag for the device
2461 */
2462void
2463device_disable(device_t dev)
2464{
2465        dev->flags &= ~DF_ENABLED;
2466}
2467
2468/**
2469 * @brief Increment the busy counter for the device
2470 */
2471void
2472device_busy(device_t dev)
2473{
2474        if (dev->state < DS_ATTACHED)
2475                panic("device_busy: called for unattached device");
2476        if (dev->busy == 0 && dev->parent)
2477                device_busy(dev->parent);
2478        dev->busy++;
2479        dev->state = DS_BUSY;
2480}
2481
2482/**
2483 * @brief Decrement the busy counter for the device
2484 */
2485void
2486device_unbusy(device_t dev)
2487{
2488        if (dev->state != DS_BUSY)
2489                panic("device_unbusy: called for non-busy device %s",
2490                    device_get_nameunit(dev));
2491        dev->busy--;
2492        if (dev->busy == 0) {
2493                if (dev->parent)
2494                        device_unbusy(dev->parent);
2495                dev->state = DS_ATTACHED;
2496        }
2497}
2498
2499/**
2500 * @brief Set the DF_QUIET flag for the device
2501 */
2502void
2503device_quiet(device_t dev)
2504{
2505        dev->flags |= DF_QUIET;
2506}
2507
2508/**
2509 * @brief Clear the DF_QUIET flag for the device
2510 */
2511void
2512device_verbose(device_t dev)
2513{
2514        dev->flags &= ~DF_QUIET;
2515}
2516
2517/**
2518 * @brief Return non-zero if the DF_QUIET flag is set on the device
2519 */
2520int
2521device_is_quiet(device_t dev)
2522{
2523        return ((dev->flags & DF_QUIET) != 0);
2524}
2525
2526/**
2527 * @brief Return non-zero if the DF_ENABLED flag is set on the device
2528 */
2529int
2530device_is_enabled(device_t dev)
2531{
2532        return ((dev->flags & DF_ENABLED) != 0);
2533}
2534
2535/**
2536 * @brief Return non-zero if the device was successfully probed
2537 */
2538int
2539device_is_alive(device_t dev)
2540{
2541        return (dev->state >= DS_ALIVE);
2542}
2543
2544/**
2545 * @brief Return non-zero if the device currently has a driver
2546 * attached to it
2547 */
2548int
2549device_is_attached(device_t dev)
2550{
2551        return (dev->state >= DS_ATTACHED);
2552}
2553
2554/**
2555 * @brief Set the devclass of a device
2556 * @see devclass_add_device().
2557 */
2558int
2559device_set_devclass(device_t dev, const char *classname)
2560{
2561        devclass_t dc;
2562        int error;
2563
2564        if (!classname) {
2565                if (dev->devclass)
2566                        devclass_delete_device(dev->devclass, dev);
2567                return (0);
2568        }
2569
2570        if (dev->devclass) {
2571                printf("device_set_devclass: device class already set\n");
2572                return (EINVAL);
2573        }
2574
2575        dc = devclass_find_internal(classname, NULL, TRUE);
2576        if (!dc)
2577                return (ENOMEM);
2578
2579        error = devclass_add_device(dc, dev);
2580
2581        bus_data_generation_update();
2582        return (error);
2583}
2584
2585/**
2586 * @brief Set the driver of a device
2587 *
2588 * @retval 0            success
2589 * @retval EBUSY        the device already has a driver attached
2590 * @retval ENOMEM       a memory allocation failure occurred
2591 */
2592int
2593device_set_driver(device_t dev, driver_t *driver)
2594{
2595        if (dev->state >= DS_ATTACHED)
2596                return (EBUSY);
2597
2598        if (dev->driver == driver)
2599                return (0);
2600
2601        if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
2602                free(dev->softc, M_BUS_SC);
2603                dev->softc = NULL;
2604        }
2605        kobj_delete((kobj_t) dev, NULL);
2606        dev->driver = driver;
2607        if (driver) {
2608                kobj_init((kobj_t) dev, (kobj_class_t) driver);
2609                if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) {
2610                        dev->softc = malloc(driver->size, M_BUS_SC,
2611                            M_NOWAIT | M_ZERO);
2612                        if (!dev->softc) {
2613                                kobj_delete((kobj_t) dev, NULL);
2614                                kobj_init((kobj_t) dev, &null_class);
2615                                dev->driver = NULL;
2616                                return (ENOMEM);
2617                        }
2618                }
2619        } else {
2620                kobj_init((kobj_t) dev, &null_class);
2621        }
2622
2623        bus_data_generation_update();
2624        return (0);
2625}
2626
2627/**
2628 * @brief Probe a device, and return this status.
2629 *
2630 * This function is the core of the device autoconfiguration
2631 * system. Its purpose is to select a suitable driver for a device and
2632 * then call that driver to initialise the hardware appropriately. The
2633 * driver is selected by calling the DEVICE_PROBE() method of a set of
2634 * candidate drivers and then choosing the driver which returned the
2635 * best value. This driver is then attached to the device using
2636 * device_attach().
2637 *
2638 * The set of suitable drivers is taken from the list of drivers in
2639 * the parent device's devclass. If the device was originally created
2640 * with a specific class name (see device_add_child()), only drivers
2641 * with that name are probed, otherwise all drivers in the devclass
2642 * are probed. If no drivers return successful probe values in the
2643 * parent devclass, the search continues in the parent of that
2644 * devclass (see devclass_get_parent()) if any.
2645 *
2646 * @param dev           the device to initialise
2647 *
2648 * @retval 0            success
2649 * @retval ENXIO        no driver was found
2650 * @retval ENOMEM       memory allocation failure
2651 * @retval non-zero     some other unix error code
2652 * @retval -1           Device already attached
2653 */
2654int
2655device_probe(device_t dev)
2656{
2657        int error;
2658
2659        GIANT_REQUIRED;
2660
2661        if (dev->state >= DS_ALIVE && (dev->flags & DF_REBID) == 0)
2662                return (-1);
2663
2664        if (!(dev->flags & DF_ENABLED)) {
2665                if (bootverbose && device_get_name(dev) != NULL) {
2666                        device_print_prettyname(dev);
2667                        printf("not probed (disabled)\n");
2668                }
2669                return (-1);
2670        }
2671        if ((error = device_probe_child(dev->parent, dev)) != 0) {             
2672                if (bus_current_pass == BUS_PASS_DEFAULT &&
2673                    !(dev->flags & DF_DONENOMATCH)) {
2674                        BUS_PROBE_NOMATCH(dev->parent, dev);
2675                        devnomatch(dev);
2676                        dev->flags |= DF_DONENOMATCH;
2677                }
2678                return (error);
2679        }
2680        return (0);
2681}
2682
2683/**
2684 * @brief Probe a device and attach a driver if possible
2685 *
2686 * calls device_probe() and attaches if that was successful.
2687 */
2688int
2689device_probe_and_attach(device_t dev)
2690{
2691        int error;
2692
2693        GIANT_REQUIRED;
2694
2695        error = device_probe(dev);
2696        if (error == -1)
2697                return (0);
2698        else if (error != 0)
2699                return (error);
2700        return (device_attach(dev));
2701}
2702
2703/**
2704 * @brief Attach a device driver to a device
2705 *
2706 * This function is a wrapper around the DEVICE_ATTACH() driver
2707 * method. In addition to calling DEVICE_ATTACH(), it initialises the
2708 * device's sysctl tree, optionally prints a description of the device
2709 * and queues a notification event for user-based device management
2710 * services.
2711 *
2712 * Normally this function is only called internally from
2713 * device_probe_and_attach().
2714 *
2715 * @param dev           the device to initialise
2716 *
2717 * @retval 0            success
2718 * @retval ENXIO        no driver was found
2719 * @retval ENOMEM       memory allocation failure
2720 * @retval non-zero     some other unix error code
2721 */
2722int
2723device_attach(device_t dev)
2724{
2725        int error;
2726
2727        device_sysctl_init(dev);
2728        if (!device_is_quiet(dev))
2729                device_print_child(dev->parent, dev);
2730        if ((error = DEVICE_ATTACH(dev)) != 0) {
2731                printf("device_attach: %s%d attach returned %d\n",
2732                    dev->driver->name, dev->unit, error);
2733                /* Unset the class; set in device_probe_child */
2734                if (dev->devclass == NULL)
2735                        device_set_devclass(dev, NULL);
2736                device_set_driver(dev, NULL);
2737                device_sysctl_fini(dev);
2738                dev->state = DS_NOTPRESENT;
2739                return (error);
2740        }
2741        device_sysctl_update(dev);
2742        dev->state = DS_ATTACHED;
2743        devadded(dev);
2744        return (0);
2745}
2746
2747/**
2748 * @brief Detach a driver from a device
2749 *
2750 * This function is a wrapper around the DEVICE_DETACH() driver
2751 * method. If the call to DEVICE_DETACH() succeeds, it calls
2752 * BUS_CHILD_DETACHED() for the parent of @p dev, queues a
2753 * notification event for user-based device management services and
2754 * cleans up the device's sysctl tree.
2755 *
2756 * @param dev           the device to un-initialise
2757 *
2758 * @retval 0            success
2759 * @retval ENXIO        no driver was found
2760 * @retval ENOMEM       memory allocation failure
2761 * @retval non-zero     some other unix error code
2762 */
2763int
2764device_detach(device_t dev)
2765{
2766        int error;
2767
2768        GIANT_REQUIRED;
2769
2770        PDEBUG(("%s", DEVICENAME(dev)));
2771        if (dev->state == DS_BUSY)
2772                return (EBUSY);
2773        if (dev->state != DS_ATTACHED)
2774                return (0);
2775
2776        if ((error = DEVICE_DETACH(dev)) != 0)
2777                return (error);
2778        devremoved(dev);
2779        if (!device_is_quiet(dev))
2780                device_printf(dev, "detached\n");
2781        if (dev->parent)
2782                BUS_CHILD_DETACHED(dev->parent, dev);
2783
2784        if (!(dev->flags & DF_FIXEDCLASS))
2785                devclass_delete_device(dev->devclass, dev);
2786
2787        dev->state = DS_NOTPRESENT;
2788        device_set_driver(dev, NULL);
2789        device_set_desc(dev, NULL);
2790        device_sysctl_fini(dev);
2791
2792        return (0);
2793}
2794
2795/**
2796 * @brief Tells a driver to quiesce itself.
2797 *
2798 * This function is a wrapper around the DEVICE_QUIESCE() driver
2799 * method. If the call to DEVICE_QUIESCE() succeeds.
2800 *
2801 * @param dev           the device to quiesce
2802 *
2803 * @retval 0            success
2804 * @retval ENXIO        no driver was found
2805 * @retval ENOMEM       memory allocation failure
2806 * @retval non-zero     some other unix error code
2807 */
2808int
2809device_quiesce(device_t dev)
2810{
2811
2812        PDEBUG(("%s", DEVICENAME(dev)));
2813        if (dev->state == DS_BUSY)
2814                return (EBUSY);
2815        if (dev->state != DS_ATTACHED)
2816                return (0);
2817
2818        return (DEVICE_QUIESCE(dev));
2819}
2820
2821/**
2822 * @brief Notify a device of system shutdown
2823 *
2824 * This function calls the DEVICE_SHUTDOWN() driver method if the
2825 * device currently has an attached driver.
2826 *
2827 * @returns the value returned by DEVICE_SHUTDOWN()
2828 */
2829int
2830device_shutdown(device_t dev)
2831{
2832        if (dev->state < DS_ATTACHED)
2833                return (0);
2834        return (DEVICE_SHUTDOWN(dev));
2835}
2836
2837/**
2838 * @brief Set the unit number of a device
2839 *
2840 * This function can be used to override the unit number used for a
2841 * device (e.g. to wire a device to a pre-configured unit number).
2842 */
2843int
2844device_set_unit(device_t dev, int unit)
2845{
2846        devclass_t dc;
2847        int err;
2848
2849        dc = device_get_devclass(dev);
2850        if (unit < dc->maxunit && dc->devices[unit])
2851                return (EBUSY);
2852        err = devclass_delete_device(dc, dev);
2853        if (err)
2854                return (err);
2855        dev->unit = unit;
2856        err = devclass_add_device(dc, dev);
2857        if (err)
2858                return (err);
2859
2860        bus_data_generation_update();
2861        return (0);
2862}
2863
2864/*======================================*/
2865/*
2866 * Some useful method implementations to make life easier for bus drivers.
2867 */
2868
2869/**
2870 * @brief Initialise a resource list.
2871 *
2872 * @param rl            the resource list to initialise
2873 */
2874void
2875resource_list_init(struct resource_list *rl)
2876{
2877        STAILQ_INIT(rl);
2878}
2879
2880/**
2881 * @brief Reclaim memory used by a resource list.
2882 *
2883 * This function frees the memory for all resource entries on the list
2884 * (if any).
2885 *
2886 * @param rl            the resource list to free               
2887 */
2888void
2889resource_list_free(struct resource_list *rl)
2890{
2891        struct resource_list_entry *rle;
2892
2893        while ((rle = STAILQ_FIRST(rl)) != NULL) {
2894                if (rle->res)
2895                        panic("resource_list_free: resource entry is busy");
2896                STAILQ_REMOVE_HEAD(rl, link);
2897                free(rle, M_BUS);
2898        }
2899}
2900
2901/**
2902 * @brief Add a resource entry.
2903 *
2904 * This function adds a resource entry using the given @p type, @p
2905 * start, @p end and @p count values. A rid value is chosen by
2906 * searching sequentially for the first unused rid starting at zero.
2907 *
2908 * @param rl            the resource list to edit
2909 * @param type          the resource entry type (e.g. SYS_RES_MEMORY)
2910 * @param start         the start address of the resource
2911 * @param end           the end address of the resource
2912 * @param count         XXX end-start+1
2913 */
2914int
2915resource_list_add_next(struct resource_list *rl, int type, u_long start,
2916    u_long end, u_long count)
2917{
2918        int rid;
2919
2920        rid = 0;
2921        while (resource_list_find(rl, type, rid) != NULL)
2922                rid++;
2923        resource_list_add(rl, type, rid, start, end, count);
2924        return (rid);
2925}
2926
2927/**
2928 * @brief Add or modify a resource entry.
2929 *
2930 * If an existing entry exists with the same type and rid, it will be
2931 * modified using the given values of @p start, @p end and @p
2932 * count. If no entry exists, a new one will be created using the
2933 * given values.  The resource list entry that matches is then returned.
2934 *
2935 * @param rl            the resource list to edit
2936 * @param type          the resource entry type (e.g. SYS_RES_MEMORY)
2937 * @param rid           the resource identifier
2938 * @param start         the start address of the resource
2939 * @param end           the end address of the resource
2940 * @param count         XXX end-start+1
2941 */
2942struct resource_list_entry *
2943resource_list_add(struct resource_list *rl, int type, int rid,
2944    u_long start, u_long end, u_long count)
2945{
2946        struct resource_list_entry *rle;
2947
2948        rle = resource_list_find(rl, type, rid);
2949        if (!rle) {
2950                rle = malloc(sizeof(struct resource_list_entry), M_BUS,
2951                    M_NOWAIT);
2952                if (!rle)
2953                        panic("resource_list_add: can't record entry");
2954                STAILQ_INSERT_TAIL(rl, rle, link);
2955                rle->type = type;
2956                rle->rid = rid;
2957                rle->res = NULL;
2958        }
2959
2960        if (rle->res)
2961                panic("resource_list_add: resource entry is busy");
2962
2963        rle->start = start;
2964        rle->end = end;
2965        rle->count = count;
2966        return (rle);
2967}
2968
2969/**
2970 * @brief Find a resource entry by type and rid.
2971 *
2972 * @param rl            the resource list to search
2973 * @param type          the resource entry type (e.g. SYS_RES_MEMORY)
2974 * @param rid           the resource identifier
2975 *
2976 * @returns the resource entry pointer or NULL if there is no such
2977 * entry.
2978 */
2979struct resource_list_entry *
2980resource_list_find(struct resource_list *rl, int type, int rid)
2981{
2982        struct resource_list_entry *rle;
2983
2984        STAILQ_FOREACH(rle, rl, link) {
2985                if (rle->type == type && rle->rid == rid)
2986                        return (rle);
2987        }
2988        return (NULL);
2989}
2990
2991/**
2992 * @brief Delete a resource entry.
2993 *
2994 * @param rl            the resource list to edit
2995 * @param type          the resource entry type (e.g. SYS_RES_MEMORY)
2996 * @param rid           the resource identifier
2997 */
2998void
2999resource_list_delete(struct resource_list *rl, int type, int rid)
3000{
3001        struct resource_list_entry *rle = resource_list_find(rl, type, rid);
3002
3003        if (rle) {
3004                if (rle->res != NULL)
3005                        panic("resource_list_delete: resource has not been released");
3006                STAILQ_REMOVE(rl, rle, resource_list_entry, link);
3007                free(rle, M_BUS);
3008        }
3009}
3010
3011/**
3012 * @brief Helper function for implementing BUS_ALLOC_RESOURCE()
3013 *
3014 * Implement BUS_ALLOC_RESOURCE() by looking up a resource from the list
3015 * and passing the allocation up to the parent of @p bus. This assumes
3016 * that the first entry of @c device_get_ivars(child) is a struct
3017 * resource_list. This also handles 'passthrough' allocations where a
3018 * child is a remote descendant of bus by passing the allocation up to
3019 * the parent of bus.
3020 *
3021 * Typically, a bus driver would store a list of child resources
3022 * somewhere in the child device's ivars (see device_get_ivars()) and
3023 * its implementation of BUS_ALLOC_RESOURCE() would find that list and
3024 * then call resource_list_alloc() to perform the allocation.
3025 *
3026 * @param rl            the resource list to allocate from
3027 * @param bus           the parent device of @p child
3028 * @param child         the device which is requesting an allocation
3029 * @param type          the type of resource to allocate
3030 * @param rid           a pointer to the resource identifier
3031 * @param start         hint at the start of the resource range - pass
3032 *                      @c 0UL for any start address
3033 * @param end           hint at the end of the resource range - pass
3034 *                      @c ~0UL for any end address
3035 * @param count         hint at the size of range required - pass @c 1
3036 *                      for any size
3037 * @param flags         any extra flags to control the resource
3038 *                      allocation - see @c RF_XXX flags in
3039 *                      <sys/rman.h> for details
3040 *
3041 * @returns             the resource which was allocated or @c NULL if no
3042 *                      resource could be allocated
3043 */
3044struct resource *
3045resource_list_alloc(struct resource_list *rl, device_t bus, device_t child,
3046    int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
3047{
3048        struct resource_list_entry *rle = NULL;
3049        int passthrough = (device_get_parent(child) != bus);
3050        int isdefault = (start == 0UL && end == ~0UL);
3051
3052        if (passthrough) {
3053                return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
3054                    type, rid, start, end, count, flags));
3055        }
3056
3057        rle = resource_list_find(rl, type, *rid);
3058
3059        if (!rle)
3060                return (NULL);          /* no resource of that type/rid */
3061
3062        if (rle->res)
3063                panic("resource_list_alloc: resource entry is busy");
3064
3065        if (isdefault) {
3066                start = rle->start;
3067                count = ulmax(count, rle->count);
3068                end = ulmax(rle->end, start + count - 1);
3069        }
3070
3071        rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
3072            type, rid, start, end, count, flags);
3073
3074        /*
3075         * Record the new range.
3076         */
3077        if (rle->res) {
3078                rle->start = rman_get_start(rle->res);
3079                rle->end = rman_get_end(rle->res);
3080                rle->count = count;
3081        }
3082
3083        return (rle->res);
3084}
3085
3086/**
3087 * @brief Helper function for implementing BUS_RELEASE_RESOURCE()
3088 *
3089 * Implement BUS_RELEASE_RESOURCE() using a resource list. Normally
3090 * used with resource_list_alloc().
3091 *
3092 * @param rl            the resource list which was allocated from
3093 * @param bus           the parent device of @p child
3094 * @param child         the device which is requesting a release
3095 * @param type          the type of resource to allocate
3096 * @param rid           the resource identifier
3097 * @param res           the resource to release
3098 *
3099 * @retval 0            success
3100 * @retval non-zero     a standard unix error code indicating what
3101 *                      error condition prevented the operation
3102 */
3103int
3104resource_list_release(struct resource_list *rl, device_t bus, device_t child,
3105    int type, int rid, struct resource *res)
3106{
3107        struct resource_list_entry *rle = NULL;
3108        int passthrough = (device_get_parent(child) != bus);
3109        int error;
3110
3111        if (passthrough) {
3112                return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
3113                    type, rid, res));
3114        }
3115
3116        rle = resource_list_find(rl, type, rid);
3117
3118        if (!rle)
3119                panic("resource_list_release: can't find resource");
3120        if (!rle->res)
3121                panic("resource_list_release: resource entry is not busy");
3122
3123        error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
3124            type, rid, res);
3125        if (error)
3126                return (error);
3127
3128        rle->res = NULL;
3129        return (0);
3130}
3131
3132/**
3133 * @brief Print a description of resources in a resource list
3134 *
3135 * Print all resources of a specified type, for use in BUS_PRINT_CHILD().
3136 * The name is printed if at least one resource of the given type is available.
3137 * The format is used to print resource start and end.
3138 *
3139 * @param rl            the resource list to print
3140 * @param name          the name of @p type, e.g. @c "memory"
3141 * @param type          type type of resource entry to print
3142 * @param format        printf(9) format string to print resource
3143 *                      start and end values
3144 *
3145 * @returns             the number of characters printed
3146 */
3147int
3148resource_list_print_type(struct resource_list *rl, const char *name, int type,
3149    const char *format)
3150{
3151        struct resource_list_entry *rle;
3152        int printed, retval;
3153
3154        printed = 0;
3155        retval = 0;
3156        /* Yes, this is kinda cheating */
3157        STAILQ_FOREACH(rle, rl, link) {
3158                if (rle->type == type) {
3159                        if (printed == 0)
3160                                retval += printf(" %s ", name);
3161                        else
3162                                retval += printf(",");
3163                        printed++;
3164                        retval += printf(format, rle->start);
3165                        if (rle->count > 1) {
3166                                retval += printf("-");
3167                                retval += printf(format, rle->start +
3168                                                 rle->count - 1);
3169                        }
3170                }
3171        }
3172        return (retval);
3173}
3174
3175/**
3176 * @brief Releases all the resources in a list.
3177 *
3178 * @param rl            The resource list to purge.
3179 *
3180 * @returns             nothing
3181 */
3182void
3183resource_list_purge(struct resource_list *rl)
3184{
3185        struct resource_list_entry *rle;
3186
3187        while ((rle = STAILQ_FIRST(rl)) != NULL) {
3188                if (rle->res)
3189                        bus_release_resource(rman_get_device(rle->res),
3190                            rle->type, rle->rid, rle->res);
3191                STAILQ_REMOVE_HEAD(rl, link);
3192                free(rle, M_BUS);
3193        }
3194}
3195
3196device_t
3197bus_generic_add_child(device_t dev, u_int order, const char *name, int unit)
3198{
3199
3200        return (device_add_child_ordered(dev, order, name, unit));
3201}
3202
3203/**
3204 * @brief Helper function for implementing DEVICE_PROBE()
3205 *
3206 * This function can be used to help implement the DEVICE_PROBE() for
3207 * a bus (i.e. a device which has other devices attached to it). It
3208 * calls the DEVICE_IDENTIFY() method of each driver in the device's
3209 * devclass.
3210 */
3211int
3212bus_generic_probe(device_t dev)
3213{
3214        devclass_t dc = dev->devclass;
3215        driverlink_t dl;
3216
3217        TAILQ_FOREACH(dl, &dc->drivers, link) {
3218                /*
3219                 * If this driver's pass is too high, then ignore it.
3220                 * For most drivers in the default pass, this will
3221                 * never be true.  For early-pass drivers they will
3222                 * only call the identify routines of eligible drivers
3223                 * when this routine is called.  Drivers for later
3224                 * passes should have their identify routines called
3225                 * on early-pass busses during BUS_NEW_PASS().
3226                 */
3227                if (dl->pass > bus_current_pass)
3228                                continue;
3229                DEVICE_IDENTIFY(dl->driver, dev);
3230        }
3231
3232        return (0);
3233}
3234
3235/**
3236 * @brief Helper function for implementing DEVICE_ATTACH()
3237 *
3238 * This function can be used to help implement the DEVICE_ATTACH() for
3239 * a bus. It calls device_probe_and_attach() for each of the device's
3240 * children.
3241 */
3242int
3243bus_generic_attach(device_t dev)
3244{
3245        device_t child;
3246
3247        TAILQ_FOREACH(child, &dev->children, link) {
3248                device_probe_and_attach(child);
3249        }
3250
3251        return (0);
3252}
3253
3254/**
3255 * @brief Helper function for implementing DEVICE_DETACH()
3256 *
3257 * This function can be used to help implement the DEVICE_DETACH() for
3258 * a bus. It calls device_detach() for each of the device's
3259 * children.
3260 */
3261int
3262bus_generic_detach(device_t dev)
3263{
3264        device_t child;
3265        int error;
3266
3267        if (dev->state != DS_ATTACHED)
3268                return (EBUSY);
3269
3270        TAILQ_FOREACH(child, &dev->children, link) {
3271                if ((error = device_detach(child)) != 0)
3272                        return (error);
3273        }
3274
3275        return (0);
3276}
3277
3278/**
3279 * @brief Helper function for implementing DEVICE_SHUTDOWN()
3280 *
3281 * This function can be used to help implement the DEVICE_SHUTDOWN()
3282 * for a bus. It calls device_shutdown() for each of the device's
3283 * children.
3284 */
3285int
3286bus_generic_shutdown(device_t dev)
3287{
3288        device_t child;
3289
3290        TAILQ_FOREACH(child, &dev->children, link) {
3291                device_shutdown(child);
3292        }
3293
3294        return (0);
3295}
3296
3297/**
3298 * @brief Helper function for implementing DEVICE_SUSPEND()
3299 *
3300 * This function can be used to help implement the DEVICE_SUSPEND()
3301 * for a bus. It calls DEVICE_SUSPEND() for each of the device's
3302 * children. If any call to DEVICE_SUSPEND() fails, the suspend
3303 * operation is aborted and any devices which were suspended are
3304 * resumed immediately by calling their DEVICE_RESUME() methods.
3305 */
3306int
3307bus_generic_suspend(device_t dev)
3308{
3309        int             error;
3310        device_t        child, child2;
3311
3312        TAILQ_FOREACH(child, &dev->children, link) {
3313                error = DEVICE_SUSPEND(child);
3314                if (error) {
3315                        for (child2 = TAILQ_FIRST(&dev->children);
3316                             child2 && child2 != child;
3317                             child2 = TAILQ_NEXT(child2, link))
3318                                DEVICE_RESUME(child2);
3319                        return (error);
3320                }
3321        }
3322        return (0);
3323}
3324
3325/**
3326 * @brief Helper function for implementing DEVICE_RESUME()
3327 *
3328 * This function can be used to help implement the DEVICE_RESUME() for
3329 * a bus. It calls DEVICE_RESUME() on each of the device's children.
3330 */
3331int
3332bus_generic_resume(device_t dev)
3333{
3334        device_t        child;
3335
3336        TAILQ_FOREACH(child, &dev->children, link) {
3337                DEVICE_RESUME(child);
3338                /* if resume fails, there's nothing we can usefully do... */
3339        }
3340        return (0);
3341}
3342
3343/**
3344 * @brief Helper function for implementing BUS_PRINT_CHILD().
3345 *
3346 * This function prints the first part of the ascii representation of
3347 * @p child, including its name, unit and description (if any - see
3348 * device_set_desc()).
3349 *
3350 * @returns the number of characters printed
3351 */
3352int
3353bus_print_child_header(device_t dev, device_t child)
3354{
3355        int     retval = 0;
3356
3357        if (device_get_desc(child)) {
3358                retval += device_printf(child, "<%s>", device_get_desc(child));
3359        } else {
3360                retval += printf("%s", device_get_nameunit(child));
3361        }
3362
3363        return (retval);
3364}
3365
3366/**
3367 * @brief Helper function for implementing BUS_PRINT_CHILD().
3368 *
3369 * This function prints the last part of the ascii representation of
3370 * @p child, which consists of the string @c " on " followed by the
3371 * name and unit of the @p dev.
3372 *
3373 * @returns the number of characters printed
3374 */
3375int
3376bus_print_child_footer(device_t dev, device_t child)
3377{
3378        return (printf(" on %s\n", device_get_nameunit(dev)));
3379}
3380
3381/**
3382 * @brief Helper function for implementing BUS_PRINT_CHILD().
3383 *
3384 * This function simply calls bus_print_child_header() followed by
3385 * bus_print_child_footer().
3386 *
3387 * @returns the number of characters printed
3388 */
3389int
3390bus_generic_print_child(device_t dev, device_t child)
3391{
3392        int     retval = 0;
3393
3394        retval += bus_print_child_header(dev, child);
3395        retval += bus_print_child_footer(dev, child);
3396
3397        return (retval);
3398}
3399
3400/**
3401 * @brief Stub function for implementing BUS_READ_IVAR().
3402 *
3403 * @returns ENOENT
3404 */
3405int
3406bus_generic_read_ivar(device_t dev, device_t child, int index,
3407    uintptr_t * result)
3408{
3409        return (ENOENT);
3410}
3411
3412/**
3413 * @brief Stub function for implementing BUS_WRITE_IVAR().
3414 *
3415 * @returns ENOENT
3416 */
3417int
3418bus_generic_write_ivar(device_t dev, device_t child, int index,
3419    uintptr_t value)
3420{
3421        return (ENOENT);
3422}
3423
3424/**
3425 * @brief Stub function for implementing BUS_GET_RESOURCE_LIST().
3426 *
3427 * @returns NULL
3428 */
3429struct resource_list *
3430bus_generic_get_resource_list(device_t dev, device_t child)
3431{
3432        return (NULL);
3433}
3434
3435/**
3436 * @brief Helper function for implementing BUS_DRIVER_ADDED().
3437 *
3438 * This implementation of BUS_DRIVER_ADDED() simply calls the driver's
3439 * DEVICE_IDENTIFY() method to allow it to add new children to the bus
3440 * and then calls device_probe_and_attach() for each unattached child.
3441 */
3442void
3443bus_generic_driver_added(device_t dev, driver_t *driver)
3444{
3445        device_t child;
3446
3447        DEVICE_IDENTIFY(driver, dev);
3448        TAILQ_FOREACH(child, &dev->children, link) {
3449                if (child->state == DS_NOTPRESENT ||
3450                    (child->flags & DF_REBID))
3451                        device_probe_and_attach(child);
3452        }
3453}
3454
3455/**
3456 * @brief Helper function for implementing BUS_NEW_PASS().
3457 *
3458 * This implementing of BUS_NEW_PASS() first calls the identify
3459 * routines for any drivers that probe at the current pass.  Then it
3460 * walks the list of devices for this bus.  If a device is already
3461 * attached, then it calls BUS_NEW_PASS() on that device.  If the
3462 * device is not already attached, it attempts to attach a driver to
3463 * it.
3464 */
3465void
3466bus_generic_new_pass(device_t dev)
3467{
3468        driverlink_t dl;
3469        devclass_t dc;
3470        device_t child;
3471
3472        dc = dev->devclass;
3473        TAILQ_FOREACH(dl, &dc->drivers, link) {
3474                if (dl->pass == bus_current_pass)
3475                        DEVICE_IDENTIFY(dl->driver, dev);
3476        }
3477        TAILQ_FOREACH(child, &dev->children, link) {
3478                if (child->state >= DS_ATTACHED)
3479                        BUS_NEW_PASS(child);
3480                else if (child->state == DS_NOTPRESENT)
3481                        device_probe_and_attach(child);
3482        }
3483}
3484
3485/**
3486 * @brief Helper function for implementing BUS_SETUP_INTR().
3487 *
3488 * This simple implementation of BUS_SETUP_INTR() simply calls the
3489 * BUS_SETUP_INTR() method of the parent of @p dev.
3490 */
3491int
3492bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
3493    int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
3494    void **cookiep)
3495{
3496        /* Propagate up the bus hierarchy until someone handles it. */
3497        if (dev->parent)
3498                return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
3499                    filter, intr, arg, cookiep));
3500        return (EINVAL);
3501}
3502
3503/**
3504 * @brief Helper function for implementing BUS_TEARDOWN_INTR().
3505 *
3506 * This simple implementation of BUS_TEARDOWN_INTR() simply calls the
3507 * BUS_TEARDOWN_INTR() method of the parent of @p dev.
3508 */
3509int
3510bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
3511    void *cookie)
3512{
3513        /* Propagate up the bus hierarchy until someone handles it. */
3514        if (dev->parent)
3515                return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
3516        return (EINVAL);
3517}
3518
3519/**
3520 * @brief Helper function for implementing BUS_ALLOC_RESOURCE().
3521 *
3522 * This simple implementation of BUS_ALLOC_RESOURCE() simply calls the
3523 * BUS_ALLOC_RESOURCE() method of the parent of @p dev.
3524 */
3525struct resource *
3526bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
3527    u_long start, u_long end, u_long count, u_int flags)
3528{
3529        /* Propagate up the bus hierarchy until someone handles it. */
3530        if (dev->parent)
3531                return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid,
3532                    start, end, count, flags));
3533        return (NULL);
3534}
3535
3536/**
3537 * @brief Helper function for implementing BUS_RELEASE_RESOURCE().
3538 *
3539 * This simple implementation of BUS_RELEASE_RESOURCE() simply calls the
3540 * BUS_RELEASE_RESOURCE() method of the parent of @p dev.
3541 */
3542int
3543bus_generic_release_resource(device_t dev, device_t child, int type, int rid,
3544    struct resource *r)
3545{
3546        /* Propagate up the bus hierarchy until someone handles it. */
3547        if (dev->parent)
3548                return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid,
3549                    r));
3550        return (EINVAL);
3551}
3552
3553/**
3554 * @brief Helper function for implementing BUS_ACTIVATE_RESOURCE().
3555 *
3556 * This simple implementation of BUS_ACTIVATE_RESOURCE() simply calls the
3557 * BUS_ACTIVATE_RESOURCE() method of the parent of @p dev.
3558 */
3559int
3560bus_generic_activate_resource(device_t dev, device_t child, int type, int rid,
3561    struct resource *r)
3562{
3563        /* Propagate up the bus hierarchy until someone handles it. */
3564        if (dev->parent)
3565                return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid,
3566                    r));
3567        return (EINVAL);
3568}
3569
3570/**
3571 * @brief Helper function for implementing BUS_DEACTIVATE_RESOURCE().
3572 *
3573 * This simple implementation of BUS_DEACTIVATE_RESOURCE() simply calls the
3574 * BUS_DEACTIVATE_RESOURCE() method of the parent of @p dev.
3575 */
3576int
3577bus_generic_deactivate_resource(device_t dev, device_t child, int type,
3578    int rid, struct resource *r)
3579{
3580        /* Propagate up the bus hierarchy until someone handles it. */
3581        if (dev->parent)
3582                return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
3583                    r));
3584        return (EINVAL);
3585}
3586
3587/**
3588 * @brief Helper function for implementing BUS_BIND_INTR().
3589 *
3590 * This simple implementation of BUS_BIND_INTR() simply calls the
3591 * BUS_BIND_INTR() method of the parent of @p dev.
3592 */
3593int
3594bus_generic_bind_intr(device_t dev, device_t child, struct resource *irq,
3595    int cpu)
3596{
3597
3598        /* Propagate up the bus hierarchy until someone handles it. */
3599        if (dev->parent)
3600                return (BUS_BIND_INTR(dev->parent, child, irq, cpu));
3601        return (EINVAL);
3602}
3603
3604/**
3605 * @brief Helper function for implementing BUS_CONFIG_INTR().
3606 *
3607 * This simple implementation of BUS_CONFIG_INTR() simply calls the
3608 * BUS_CONFIG_INTR() method of the parent of @p dev.
3609 */
3610int
3611bus_generic_config_intr(device_t dev, int irq, enum intr_trigger trig,
3612    enum intr_polarity pol)
3613{
3614
3615        /* Propagate up the bus hierarchy until someone handles it. */
3616        if (dev->parent)
3617                return (BUS_CONFIG_INTR(dev->parent, irq, trig, pol));
3618        return (EINVAL);
3619}
3620
3621/**
3622 * @brief Helper function for implementing BUS_DESCRIBE_INTR().
3623 *
3624 * This simple implementation of BUS_DESCRIBE_INTR() simply calls the
3625 * BUS_DESCRIBE_INTR() method of the parent of @p dev.
3626 */
3627int
3628bus_generic_describe_intr(device_t dev, device_t child, struct resource *irq,
3629    void *cookie, const char *descr)
3630{
3631
3632        /* Propagate up the bus hierarchy until someone handles it. */
3633        if (dev->parent)
3634                return (BUS_DESCRIBE_INTR(dev->parent, child, irq, cookie,
3635                    descr));
3636        return (EINVAL);
3637}
3638
3639/**
3640 * @brief Helper function for implementing BUS_GET_DMA_TAG().
3641 *
3642 * This simple implementation of BUS_GET_DMA_TAG() simply calls the
3643 * BUS_GET_DMA_TAG() method of the parent of @p dev.
3644 */
3645bus_dma_tag_t
3646bus_generic_get_dma_tag(device_t dev, device_t child)
3647{
3648
3649        /* Propagate up the bus hierarchy until someone handles it. */
3650        if (dev->parent != NULL)
3651                return (BUS_GET_DMA_TAG(dev->parent, child));
3652        return (NULL);
3653}
3654
3655/**
3656 * @brief Helper function for implementing BUS_GET_RESOURCE().
3657 *
3658 * This implementation of BUS_GET_RESOURCE() uses the
3659 * resource_list_find() function to do most of the work. It calls
3660 * BUS_GET_RESOURCE_LIST() to find a suitable resource list to
3661 * search.
3662 */
3663int
3664bus_generic_rl_get_resource(device_t dev, device_t child, int type, int rid,
3665    u_long *startp, u_long *countp)
3666{
3667        struct resource_list *          rl = NULL;
3668        struct resource_list_entry *    rle = NULL;
3669
3670        rl = BUS_GET_RESOURCE_LIST(dev, child);
3671        if (!rl)
3672                return (EINVAL);
3673
3674        rle = resource_list_find(rl, type, rid);
3675        if (!rle)
3676                return (ENOENT);
3677
3678        if (startp)
3679                *startp = rle->start;
3680        if (countp)
3681                *countp = rle->count;
3682
3683        return (0);
3684}
3685
3686/**
3687 * @brief Helper function for implementing BUS_SET_RESOURCE().
3688 *
3689 * This implementation of BUS_SET_RESOURCE() uses the
3690 * resource_list_add() function to do most of the work. It calls
3691 * BUS_GET_RESOURCE_LIST() to find a suitable resource list to
3692 * edit.
3693 */
3694int
3695bus_generic_rl_set_resource(device_t dev, device_t child, int type, int rid,
3696    u_long start, u_long count)
3697{
3698        struct resource_list *          rl = NULL;
3699
3700        rl = BUS_GET_RESOURCE_LIST(dev, child);
3701        if (!rl)
3702                return (EINVAL);
3703
3704        resource_list_add(rl, type, rid, start, (start + count - 1), count);
3705
3706        return (0);
3707}
3708
3709/**
3710 * @brief Helper function for implementing BUS_DELETE_RESOURCE().
3711 *
3712 * This implementation of BUS_DELETE_RESOURCE() uses the
3713 * resource_list_delete() function to do most of the work. It calls
3714 * BUS_GET_RESOURCE_LIST() to find a suitable resource list to
3715 * edit.
3716 */
3717void
3718bus_generic_rl_delete_resource(device_t dev, device_t child, int type, int rid)
3719{
3720        struct resource_list *          rl = NULL;
3721
3722        rl = BUS_GET_RESOURCE_LIST(dev, child);
3723        if (!rl)
3724                return;
3725
3726        resource_list_delete(rl, type, rid);
3727
3728        return;
3729}
3730
3731/**
3732 * @brief Helper function for implementing BUS_RELEASE_RESOURCE().
3733 *
3734 * This implementation of BUS_RELEASE_RESOURCE() uses the
3735 * resource_list_release() function to do most of the work. It calls
3736 * BUS_GET_RESOURCE_LIST() to find a suitable resource list.
3737 */
3738int
3739bus_generic_rl_release_resource(device_t dev, device_t child, int type,
3740    int rid, struct resource *r)
3741{
3742        struct resource_list *          rl = NULL;
3743
3744        rl = BUS_GET_RESOURCE_LIST(dev, child);
3745        if (!rl)
3746                return (EINVAL);
3747
3748        return (resource_list_release(rl, dev, child, type, rid, r));
3749}
3750
3751/**
3752 * @brief Helper function for implementing BUS_ALLOC_RESOURCE().
3753 *
3754 * This implementation of BUS_ALLOC_RESOURCE() uses the
3755 * resource_list_alloc() function to do most of the work. It calls
3756 * BUS_GET_RESOURCE_LIST() to find a suitable resource list.
3757 */
3758struct resource *
3759bus_generic_rl_alloc_resource(device_t dev, device_t child, int type,
3760    int *rid, u_long start, u_long end, u_long count, u_int flags)
3761{
3762        struct resource_list *          rl = NULL;
3763
3764        rl = BUS_GET_RESOURCE_LIST(dev, child);
3765        if (!rl)
3766                return (NULL);
3767
3768        return (resource_list_alloc(rl, dev, child, type, rid,
3769            start, end, count, flags));
3770}
3771
3772/**
3773 * @brief Helper function for implementing BUS_CHILD_PRESENT().
3774 *
3775 * This simple implementation of BUS_CHILD_PRESENT() simply calls the
3776 * BUS_CHILD_PRESENT() method of the parent of @p dev.
3777 */
3778int
3779bus_generic_child_present(device_t dev, device_t child)
3780{
3781        return (BUS_CHILD_PRESENT(device_get_parent(dev), dev));
3782}
3783
3784/*
3785 * Some convenience functions to make it easier for drivers to use the
3786 * resource-management functions.  All these really do is hide the
3787 * indirection through the parent's method table, making for slightly
3788 * less-wordy code.  In the future, it might make sense for this code
3789 * to maintain some sort of a list of resources allocated by each device.
3790 */
3791
3792int
3793bus_alloc_resources(device_t dev, struct resource_spec *rs,
3794    struct resource **res)
3795{
3796        int i;
3797
3798        for (i = 0; rs[i].type != -1; i++)
3799                res[i] = NULL;
3800        for (i = 0; rs[i].type != -1; i++) {
3801                res[i] = bus_alloc_resource_any(dev,
3802                    rs[i].type, &rs[i].rid, rs[i].flags);
3803                if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) {
3804                        bus_release_resources(dev, rs, res);
3805                        return (ENXIO);
3806                }
3807        }
3808        return (0);
3809}
3810
3811void
3812bus_release_resources(device_t dev, const struct resource_spec *rs,
3813    struct resource **res)
3814{
3815        int i;
3816
3817        for (i = 0; rs[i].type != -1; i++)
3818                if (res[i] != NULL) {
3819                        bus_release_resource(
3820                            dev, rs[i].type, rs[i].rid, res[i]);
3821                        res[i] = NULL;
3822                }
3823}
3824
3825/**
3826 * @brief Wrapper function for BUS_ALLOC_RESOURCE().
3827 *
3828 * This function simply calls the BUS_ALLOC_RESOURCE() method of the
3829 * parent of @p dev.
3830 */
3831struct resource *
3832bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end,
3833    u_long count, u_int flags)
3834{
3835        if (dev->parent == NULL)
3836                return (NULL);
3837        return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
3838            count, flags));
3839}
3840
3841/**
3842 * @brief Wrapper function for BUS_ACTIVATE_RESOURCE().
3843 *
3844 * This function simply calls the BUS_ACTIVATE_RESOURCE() method of the
3845 * parent of @p dev.
3846 */
3847int
3848bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
3849{
3850        if (dev->parent == NULL)
3851                return (EINVAL);
3852        return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
3853}
3854
3855/**
3856 * @brief Wrapper function for BUS_DEACTIVATE_RESOURCE().
3857 *
3858 * This function simply calls the BUS_DEACTIVATE_RESOURCE() method of the
3859 * parent of @p dev.
3860 */
3861int
3862bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
3863{
3864        if (dev->parent == NULL)
3865                return (EINVAL);
3866        return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
3867}
3868
3869/**
3870 * @brief Wrapper function for BUS_RELEASE_RESOURCE().
3871 *
3872 * This function simply calls the BUS_RELEASE_RESOURCE() method of the
3873 * parent of @p dev.
3874 */
3875int
3876bus_release_resource(device_t dev, int type, int rid, struct resource *r)
3877{
3878        if (dev->parent == NULL)
3879                return (EINVAL);
3880        return (BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r));
3881}
3882
3883/**
3884 * @brief Wrapper function for BUS_SETUP_INTR().
3885 *
3886 * This function simply calls the BUS_SETUP_INTR() method of the
3887 * parent of @p dev.
3888 */
3889int
3890bus_setup_intr(device_t dev, struct resource *r, int flags,
3891    driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep)
3892{
3893        int error;
3894
3895        if (dev->parent == NULL)
3896                return (EINVAL);
3897        error = BUS_SETUP_INTR(dev->parent, dev, r, flags, filter, handler,
3898            arg, cookiep);
3899        if (error != 0)
3900                return (error);
3901        if (handler != NULL && !(flags & INTR_MPSAFE))
3902                device_printf(dev, "[GIANT-LOCKED]\n");
3903        if (bootverbose && (flags & INTR_MPSAFE))
3904                device_printf(dev, "[MPSAFE]\n");
3905        if (filter != NULL) {
3906                if (handler == NULL)
3907                        device_printf(dev, "[FILTER]\n");
3908                else
3909                        device_printf(dev, "[FILTER+ITHREAD]\n");
3910        } else
3911                device_printf(dev, "[ITHREAD]\n");
3912        return (0);
3913}
3914
3915/**
3916 * @brief Wrapper function for BUS_TEARDOWN_INTR().
3917 *
3918 * This function simply calls the BUS_TEARDOWN_INTR() method of the
3919 * parent of @p dev.
3920 */
3921int
3922bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
3923{
3924        if (dev->parent == NULL)
3925                return (EINVAL);
3926        return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
3927}
3928
3929/**
3930 * @brief Wrapper function for BUS_BIND_INTR().
3931 *
3932 * This function simply calls the BUS_BIND_INTR() method of the
3933 * parent of @p dev.
3934 */
3935int
3936bus_bind_intr(device_t dev, struct resource *r, int cpu)
3937{
3938        if (dev->parent == NULL)
3939                return (EINVAL);
3940        return (BUS_BIND_INTR(dev->parent, dev, r, cpu));
3941}
3942
3943/**
3944 * @brief Wrapper function for BUS_DESCRIBE_INTR().
3945 *
3946 * This function first formats the requested description into a
3947 * temporary buffer and then calls the BUS_DESCRIBE_INTR() method of
3948 * the parent of @p dev.
3949 */
3950int
3951bus_describe_intr(device_t dev, struct resource *irq, void *cookie,
3952    const char *fmt, ...)
3953{
3954        va_list ap;
3955        char descr[MAXCOMLEN + 1];
3956
3957        if (dev->parent == NULL)
3958                return (EINVAL);
3959        va_start(ap, fmt);
3960        vsnprintf(descr, sizeof(descr), fmt, ap);
3961        va_end(ap);
3962        return (BUS_DESCRIBE_INTR(dev->parent, dev, irq, cookie, descr));
3963}
3964
3965/**
3966 * @brief Wrapper function for BUS_SET_RESOURCE().
3967 *
3968 * This function simply calls the BUS_SET_RESOURCE() method of the
3969 * parent of @p dev.
3970 */
3971int
3972bus_set_resource(device_t dev, int type, int rid,
3973    u_long start, u_long count)
3974{
3975        return (BUS_SET_RESOURCE(device_get_parent(dev), dev, type, rid,
3976            start, count));
3977}
3978
3979/**
3980 * @brief Wrapper function for BUS_GET_RESOURCE().
3981 *
3982 * This function simply calls the BUS_GET_RESOURCE() method of the
3983 * parent of @p dev.
3984 */
3985int
3986bus_get_resource(device_t dev, int type, int rid,
3987    u_long *startp, u_long *countp)
3988{
3989        return (BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
3990            startp, countp));
3991}
3992
3993/**
3994 * @brief Wrapper function for BUS_GET_RESOURCE().
3995 *
3996 * This function simply calls the BUS_GET_RESOURCE() method of the
3997 * parent of @p dev and returns the start value.
3998 */
3999u_long
4000bus_get_resource_start(device_t dev, int type, int rid)
4001{
4002        u_long start, count;
4003        int error;
4004
4005        error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
4006            &start, &count);
4007        if (error)
4008                return (0);
4009        return (start);
4010}
4011
4012/**
4013 * @brief Wrapper function for BUS_GET_RESOURCE().
4014 *
4015 * This function simply calls the BUS_GET_RESOURCE() method of the
4016 * parent of @p dev and returns the count value.
4017 */
4018u_long
4019bus_get_resource_count(device_t dev, int type, int rid)
4020{
4021        u_long start, count;
4022        int error;
4023
4024        error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
4025            &start, &count);
4026        if (error)
4027                return (0);
4028        return (count);
4029}
4030
4031/**
4032 * @brief Wrapper function for BUS_DELETE_RESOURCE().
4033 *
4034 * This function simply calls the BUS_DELETE_RESOURCE() method of the
4035 * parent of @p dev.
4036 */
4037void
4038bus_delete_resource(device_t dev, int type, int rid)
4039{
4040        BUS_DELETE_RESOURCE(device_get_parent(dev), dev, type, rid);
4041}
4042
4043/**
4044 * @brief Wrapper function for BUS_CHILD_PRESENT().
4045 *
4046 * This function simply calls the BUS_CHILD_PRESENT() method of the
4047 * parent of @p dev.
4048 */
4049int
4050bus_child_present(device_t child)
4051{
4052        return (BUS_CHILD_PRESENT(device_get_parent(child), child));
4053}
4054
4055/**
4056 * @brief Wrapper function for BUS_CHILD_PNPINFO_STR().
4057 *
4058 * This function simply calls the BUS_CHILD_PNPINFO_STR() method of the
4059 * parent of @p dev.
4060 */
4061int
4062bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen)
4063{
4064        device_t parent;
4065
4066        parent = device_get_parent(child);
4067        if (parent == NULL) {
4068                *buf = '\0';
4069                return (0);
4070        }
4071        return (BUS_CHILD_PNPINFO_STR(parent, child, buf, buflen));
4072}
4073
4074/**
4075 * @brief Wrapper function for BUS_CHILD_LOCATION_STR().
4076 *
4077 * This function simply calls the BUS_CHILD_LOCATION_STR() method of the
4078 * parent of @p dev.
4079 */
4080int
4081bus_child_location_str(device_t child, char *buf, size_t buflen)
4082{
4083        device_t parent;
4084
4085        parent = device_get_parent(child);
4086        if (parent == NULL) {
4087                *buf = '\0';
4088                return (0);
4089        }
4090        return (BUS_CHILD_LOCATION_STR(parent, child, buf, buflen));
4091}
4092
4093/**
4094 * @brief Wrapper function for BUS_GET_DMA_TAG().
4095 *
4096 * This function simply calls the BUS_GET_DMA_TAG() method of the
4097 * parent of @p dev.
4098 */
4099bus_dma_tag_t
4100bus_get_dma_tag(device_t dev)
4101{
4102        device_t parent;
4103
4104        parent = device_get_parent(dev);
4105        if (parent == NULL)
4106                return (NULL);
4107        return (BUS_GET_DMA_TAG(parent, dev));
4108}
4109
4110/* Resume all devices and then notify userland that we're up again. */
4111static int
4112root_resume(device_t dev)
4113{
4114        int error;
4115
4116        error = bus_generic_resume(dev);
4117        if (error == 0)
4118                devctl_notify("kern", "power", "resume", NULL);
4119        return (error);
4120}
4121
4122static int
4123root_print_child(device_t dev, device_t child)
4124{
4125        int     retval = 0;
4126
4127        retval += bus_print_child_header(dev, child);
4128        retval += printf("\n");
4129
4130        return (retval);
4131}
4132
4133static int
4134root_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
4135    driver_filter_t *filter, driver_intr_t *intr, void *arg, void **cookiep)
4136{
4137        /*
4138         * If an interrupt mapping gets to here something bad has happened.
4139         */
4140        panic("root_setup_intr");
4141}
4142
4143/*
4144 * If we get here, assume that the device is permanant and really is
4145 * present in the system.  Removable bus drivers are expected to intercept
4146 * this call long before it gets here.  We return -1 so that drivers that
4147 * really care can check vs -1 or some ERRNO returned higher in the food
4148 * chain.
4149 */
4150static int
4151root_child_present(device_t dev, device_t child)
4152{
4153        return (-1);
4154}
4155
4156static kobj_method_t root_methods[] = {
4157        /* Device interface */
4158        KOBJMETHOD(device_shutdown,     bus_generic_shutdown),
4159        KOBJMETHOD(device_suspend,      bus_generic_suspend),
4160        KOBJMETHOD(device_resume,       root_resume),
4161
4162        /* Bus interface */
4163        KOBJMETHOD(bus_print_child,     root_print_child),
4164        KOBJMETHOD(bus_read_ivar,       bus_generic_read_ivar),
4165        KOBJMETHOD(bus_write_ivar,      bus_generic_write_ivar),
4166        KOBJMETHOD(bus_setup_intr,      root_setup_intr),
4167        KOBJMETHOD(bus_child_present,   root_child_present),
4168
4169        KOBJMETHOD_END
4170};
4171
4172static driver_t root_driver = {
4173        "root",
4174        root_methods,
4175        1,                      /* no softc */
4176};
4177
4178device_t        root_bus;
4179devclass_t      root_devclass;
4180
4181static int
4182root_bus_module_handler(module_t mod, int what, void* arg)
4183{
4184        switch (what) {
4185        case MOD_LOAD:
4186                TAILQ_INIT(&bus_data_devices);
4187                kobj_class_compile((kobj_class_t) &root_driver);
4188                root_bus = make_device(NULL, "root", 0);
4189                root_bus->desc = "System root bus";
4190                kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
4191                root_bus->driver = &root_driver;
4192                root_bus->state = DS_ATTACHED;
4193                root_devclass = devclass_find_internal("root", NULL, FALSE);
4194                devinit();
4195                return (0);
4196
4197        case MOD_SHUTDOWN:
4198                device_shutdown(root_bus);
4199                return (0);
4200        default:
4201                return (EOPNOTSUPP);
4202        }
4203
4204        return (0);
4205}
4206
4207static moduledata_t root_bus_mod = {
4208        "rootbus",
4209        root_bus_module_handler,
4210        NULL
4211};
4212DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
4213
4214/**
4215 * @brief Automatically configure devices
4216 *
4217 * This function begins the autoconfiguration process by calling
4218 * device_probe_and_attach() for each child of the @c root0 device.
4219 */
4220void
4221root_bus_configure(void)
4222{
4223
4224        PDEBUG(("."));
4225
4226        /* Eventually this will be split up, but this is sufficient for now. */
4227        bus_set_pass(BUS_PASS_DEFAULT);
4228}
4229
4230/**
4231 * @brief Module handler for registering device drivers
4232 *
4233 * This module handler is used to automatically register device
4234 * drivers when modules are loaded. If @p what is MOD_LOAD, it calls
4235 * devclass_add_driver() for the driver described by the
4236 * driver_module_data structure pointed to by @p arg
4237 */
4238int
4239driver_module_handler(module_t mod, int what, void *arg)
4240{
4241        struct driver_module_data *dmd;
4242        devclass_t bus_devclass;
4243        kobj_class_t driver;
4244        int error, pass;
4245
4246        dmd = (struct driver_module_data *)arg;
4247        bus_devclass = devclass_find_internal(dmd->dmd_busname, NULL, TRUE);
4248        error = 0;
4249
4250        switch (what) {
4251        case MOD_LOAD:
4252                if (dmd->dmd_chainevh)
4253                        error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
4254
4255                pass = dmd->dmd_pass;
4256                driver = dmd->dmd_driver;
4257                PDEBUG(("Loading module: driver %s on bus %s (pass %d)",
4258                    DRIVERNAME(driver), dmd->dmd_busname, pass));
4259                error = devclass_add_driver(bus_devclass, driver, pass,
4260                    dmd->dmd_devclass);
4261                break;
4262
4263        case MOD_UNLOAD:
4264                PDEBUG(("Unloading module: driver %s from bus %s",
4265                    DRIVERNAME(dmd->dmd_driver),
4266                    dmd->dmd_busname));
4267                error = devclass_delete_driver(bus_devclass,
4268                    dmd->dmd_driver);
4269
4270                if (!error && dmd->dmd_chainevh)
4271                        error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
4272                break;
4273        case MOD_QUIESCE:
4274                PDEBUG(("Quiesce module: driver %s from bus %s",
4275                    DRIVERNAME(dmd->dmd_driver),
4276                    dmd->dmd_busname));
4277                error = devclass_quiesce_driver(bus_devclass,
4278                    dmd->dmd_driver);
4279
4280                if (!error && dmd->dmd_chainevh)
4281                        error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
4282                break;
4283        default:
4284                error = EOPNOTSUPP;
4285                break;
4286        }
4287
4288        return (error);
4289}
4290
4291#ifndef __rtems__
4292/**
4293 * @brief Enumerate all hinted devices for this bus.
4294 *
4295 * Walks through the hints for this bus and calls the bus_hinted_child
4296 * routine for each one it fines.  It searches first for the specific
4297 * bus that's being probed for hinted children (eg isa0), and then for
4298 * generic children (eg isa).
4299 *
4300 * @param       dev     bus device to enumerate
4301 */
4302void
4303bus_enumerate_hinted_children(device_t bus)
4304{
4305        int i;
4306        const char *dname, *busname;
4307        int dunit;
4308
4309        /*
4310         * enumerate all devices on the specific bus
4311         */
4312        busname = device_get_nameunit(bus);
4313        i = 0;
4314        while (resource_find_match(&i, &dname, &dunit, "at", busname) == 0)
4315                BUS_HINTED_CHILD(bus, dname, dunit);
4316
4317        /*
4318         * and all the generic ones.
4319         */
4320        busname = device_get_name(bus);
4321        i = 0;
4322        while (resource_find_match(&i, &dname, &dunit, "at", busname) == 0)
4323                BUS_HINTED_CHILD(bus, dname, dunit);
4324}
4325#endif /* __rtems__ */
4326
4327#ifdef BUS_DEBUG
4328
4329/* the _short versions avoid iteration by not calling anything that prints
4330 * more than oneliners. I love oneliners.
4331 */
4332
4333static void
4334print_device_short(device_t dev, int indent)
4335{
4336        if (!dev)
4337                return;
4338
4339        indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
4340            dev->unit, dev->desc,
4341            (dev->parent? "":"no "),
4342            (TAILQ_EMPTY(&dev->children)? "no ":""),
4343            (dev->flags&DF_ENABLED? "enabled,":"disabled,"),
4344            (dev->flags&DF_FIXEDCLASS? "fixed,":""),
4345            (dev->flags&DF_WILDCARD? "wildcard,":""),
4346            (dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
4347            (dev->flags&DF_REBID? "rebiddable,":""),
4348            (dev->ivars? "":"no "),
4349            (dev->softc? "":"no "),
4350            dev->busy));
4351}
4352
4353static void
4354print_device(device_t dev, int indent)
4355{
4356        if (!dev)
4357                return;
4358
4359        print_device_short(dev, indent);
4360
4361        indentprintf(("Parent:\n"));
4362        print_device_short(dev->parent, indent+1);
4363        indentprintf(("Driver:\n"));
4364        print_driver_short(dev->driver, indent+1);
4365        indentprintf(("Devclass:\n"));
4366        print_devclass_short(dev->devclass, indent+1);
4367}
4368
4369void
4370print_device_tree_short(device_t dev, int indent)
4371/* print the device and all its children (indented) */
4372{
4373        device_t child;
4374
4375        if (!dev)
4376                return;
4377
4378        print_device_short(dev, indent);
4379
4380        TAILQ_FOREACH(child, &dev->children, link) {
4381                print_device_tree_short(child, indent+1);
4382        }
4383}
4384
4385void
4386print_device_tree(device_t dev, int indent)
4387/* print the device and all its children (indented) */
4388{
4389        device_t child;
4390
4391        if (!dev)
4392                return;
4393
4394        print_device(dev, indent);
4395
4396        TAILQ_FOREACH(child, &dev->children, link) {
4397                print_device_tree(child, indent+1);
4398        }
4399}
4400
4401static void
4402print_driver_short(driver_t *driver, int indent)
4403{
4404        if (!driver)
4405                return;
4406
4407        indentprintf(("driver %s: softc size = %zd\n",
4408            driver->name, driver->size));
4409}
4410
4411static void
4412print_driver(driver_t *driver, int indent)
4413{
4414        if (!driver)
4415                return;
4416
4417        print_driver_short(driver, indent);
4418}
4419
4420
4421static void
4422print_driver_list(driver_list_t drivers, int indent)
4423{
4424        driverlink_t driver;
4425
4426        TAILQ_FOREACH(driver, &drivers, link) {
4427                print_driver(driver->driver, indent);
4428        }
4429}
4430
4431static void
4432print_devclass_short(devclass_t dc, int indent)
4433{
4434        if ( !dc )
4435                return;
4436
4437        indentprintf(("devclass %s: max units = %d\n", dc->name, dc->maxunit));
4438}
4439
4440static void
4441print_devclass(devclass_t dc, int indent)
4442{
4443        int i;
4444
4445        if ( !dc )
4446                return;
4447
4448        print_devclass_short(dc, indent);
4449        indentprintf(("Drivers:\n"));
4450        print_driver_list(dc->drivers, indent+1);
4451
4452        indentprintf(("Devices:\n"));
4453        for (i = 0; i < dc->maxunit; i++)
4454                if (dc->devices[i])
4455                        print_device(dc->devices[i], indent+1);
4456}
4457
4458void
4459print_devclass_list_short(void)
4460{
4461        devclass_t dc;
4462
4463        printf("Short listing of devclasses, drivers & devices:\n");
4464        TAILQ_FOREACH(dc, &devclasses, link) {
4465                print_devclass_short(dc, 0);
4466        }
4467}
4468
4469void
4470print_devclass_list(void)
4471{
4472        devclass_t dc;
4473
4474        printf("Full listing of devclasses, drivers & devices:\n");
4475        TAILQ_FOREACH(dc, &devclasses, link) {
4476                print_devclass(dc, 0);
4477        }
4478}
4479
4480#endif
4481
4482#ifndef __rtems__
4483/*
4484 * User-space access to the device tree.
4485 *
4486 * We implement a small set of nodes:
4487 *
4488 * hw.bus                       Single integer read method to obtain the
4489 *                              current generation count.
4490 * hw.bus.devices               Reads the entire device tree in flat space.
4491 * hw.bus.rman                  Resource manager interface
4492 *
4493 * We might like to add the ability to scan devclasses and/or drivers to
4494 * determine what else is currently loaded/available.
4495 */
4496
4497static int
4498sysctl_bus(SYSCTL_HANDLER_ARGS)
4499{
4500        struct u_businfo        ubus;
4501
4502        ubus.ub_version = BUS_USER_VERSION;
4503        ubus.ub_generation = bus_data_generation;
4504
4505        return (SYSCTL_OUT(req, &ubus, sizeof(ubus)));
4506}
4507SYSCTL_NODE(_hw_bus, OID_AUTO, info, CTLFLAG_RW, sysctl_bus,
4508    "bus-related data");
4509
4510static int
4511sysctl_devices(SYSCTL_HANDLER_ARGS)
4512{
4513        int                     *name = (int *)arg1;
4514        u_int                   namelen = arg2;
4515        int                     index;
4516        struct device           *dev;
4517        struct u_device         udev;   /* XXX this is a bit big */
4518        int                     error;
4519
4520        if (namelen != 2)
4521                return (EINVAL);
4522
4523        if (bus_data_generation_check(name[0]))
4524                return (EINVAL);
4525
4526        index = name[1];
4527
4528        /*
4529         * Scan the list of devices, looking for the requested index.
4530         */
4531        TAILQ_FOREACH(dev, &bus_data_devices, devlink) {
4532                if (index-- == 0)
4533                        break;
4534        }
4535        if (dev == NULL)
4536                return (ENOENT);
4537
4538        /*
4539         * Populate the return array.
4540         */
4541        bzero(&udev, sizeof(udev));
4542        udev.dv_handle = (uintptr_t)dev;
4543        udev.dv_parent = (uintptr_t)dev->parent;
4544        if (dev->nameunit != NULL)
4545                strlcpy(udev.dv_name, dev->nameunit, sizeof(udev.dv_name));
4546        if (dev->desc != NULL)
4547                strlcpy(udev.dv_desc, dev->desc, sizeof(udev.dv_desc));
4548        if (dev->driver != NULL && dev->driver->name != NULL)
4549                strlcpy(udev.dv_drivername, dev->driver->name,
4550                    sizeof(udev.dv_drivername));
4551        bus_child_pnpinfo_str(dev, udev.dv_pnpinfo, sizeof(udev.dv_pnpinfo));
4552        bus_child_location_str(dev, udev.dv_location, sizeof(udev.dv_location));
4553        udev.dv_devflags = dev->devflags;
4554        udev.dv_flags = dev->flags;
4555        udev.dv_state = dev->state;
4556        error = SYSCTL_OUT(req, &udev, sizeof(udev));
4557        return (error);
4558}
4559
4560SYSCTL_NODE(_hw_bus, OID_AUTO, devices, CTLFLAG_RD, sysctl_devices,
4561    "system device tree");
4562#endif /* __rtems__ */
4563
4564int
4565bus_data_generation_check(int generation)
4566{
4567        if (generation != bus_data_generation)
4568                return (1);
4569
4570        /* XXX generate optimised lists here? */
4571        return (0);
4572}
4573
4574void
4575bus_data_generation_update(void)
4576{
4577        bus_data_generation++;
4578}
4579
4580#ifndef __rtems__
4581int
4582bus_free_resource(device_t dev, int type, struct resource *r)
4583{
4584        if (r == NULL)
4585                return (0);
4586        return (bus_release_resource(dev, type, rman_get_rid(r), r));
4587}
4588#endif /* __rtems__ */
Note: See TracBrowser for help on using the repository browser.