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

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 1e3e818 was 1e3e818, checked in by Sebastian Huber <sebastian.huber@…>, on 04/18/12 at 15:02:17

Hide device sysctl and resource functions

  • Property mode set to 100644
File size: 110.2 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#ifndef __rtems__
2865/*======================================*/
2866/*
2867 * Some useful method implementations to make life easier for bus drivers.
2868 */
2869
2870/**
2871 * @brief Initialise a resource list.
2872 *
2873 * @param rl            the resource list to initialise
2874 */
2875void
2876resource_list_init(struct resource_list *rl)
2877{
2878        STAILQ_INIT(rl);
2879}
2880
2881/**
2882 * @brief Reclaim memory used by a resource list.
2883 *
2884 * This function frees the memory for all resource entries on the list
2885 * (if any).
2886 *
2887 * @param rl            the resource list to free               
2888 */
2889void
2890resource_list_free(struct resource_list *rl)
2891{
2892        struct resource_list_entry *rle;
2893
2894        while ((rle = STAILQ_FIRST(rl)) != NULL) {
2895                if (rle->res)
2896                        panic("resource_list_free: resource entry is busy");
2897                STAILQ_REMOVE_HEAD(rl, link);
2898                free(rle, M_BUS);
2899        }
2900}
2901
2902/**
2903 * @brief Add a resource entry.
2904 *
2905 * This function adds a resource entry using the given @p type, @p
2906 * start, @p end and @p count values. A rid value is chosen by
2907 * searching sequentially for the first unused rid starting at zero.
2908 *
2909 * @param rl            the resource list to edit
2910 * @param type          the resource entry type (e.g. SYS_RES_MEMORY)
2911 * @param start         the start address of the resource
2912 * @param end           the end address of the resource
2913 * @param count         XXX end-start+1
2914 */
2915int
2916resource_list_add_next(struct resource_list *rl, int type, u_long start,
2917    u_long end, u_long count)
2918{
2919        int rid;
2920
2921        rid = 0;
2922        while (resource_list_find(rl, type, rid) != NULL)
2923                rid++;
2924        resource_list_add(rl, type, rid, start, end, count);
2925        return (rid);
2926}
2927
2928/**
2929 * @brief Add or modify a resource entry.
2930 *
2931 * If an existing entry exists with the same type and rid, it will be
2932 * modified using the given values of @p start, @p end and @p
2933 * count. If no entry exists, a new one will be created using the
2934 * given values.  The resource list entry that matches is then returned.
2935 *
2936 * @param rl            the resource list to edit
2937 * @param type          the resource entry type (e.g. SYS_RES_MEMORY)
2938 * @param rid           the resource identifier
2939 * @param start         the start address of the resource
2940 * @param end           the end address of the resource
2941 * @param count         XXX end-start+1
2942 */
2943struct resource_list_entry *
2944resource_list_add(struct resource_list *rl, int type, int rid,
2945    u_long start, u_long end, u_long count)
2946{
2947        struct resource_list_entry *rle;
2948
2949        rle = resource_list_find(rl, type, rid);
2950        if (!rle) {
2951                rle = malloc(sizeof(struct resource_list_entry), M_BUS,
2952                    M_NOWAIT);
2953                if (!rle)
2954                        panic("resource_list_add: can't record entry");
2955                STAILQ_INSERT_TAIL(rl, rle, link);
2956                rle->type = type;
2957                rle->rid = rid;
2958                rle->res = NULL;
2959        }
2960
2961        if (rle->res)
2962                panic("resource_list_add: resource entry is busy");
2963
2964        rle->start = start;
2965        rle->end = end;
2966        rle->count = count;
2967        return (rle);
2968}
2969
2970/**
2971 * @brief Find a resource entry by type and rid.
2972 *
2973 * @param rl            the resource list to search
2974 * @param type          the resource entry type (e.g. SYS_RES_MEMORY)
2975 * @param rid           the resource identifier
2976 *
2977 * @returns the resource entry pointer or NULL if there is no such
2978 * entry.
2979 */
2980struct resource_list_entry *
2981resource_list_find(struct resource_list *rl, int type, int rid)
2982{
2983        struct resource_list_entry *rle;
2984
2985        STAILQ_FOREACH(rle, rl, link) {
2986                if (rle->type == type && rle->rid == rid)
2987                        return (rle);
2988        }
2989        return (NULL);
2990}
2991
2992/**
2993 * @brief Delete a resource entry.
2994 *
2995 * @param rl            the resource list to edit
2996 * @param type          the resource entry type (e.g. SYS_RES_MEMORY)
2997 * @param rid           the resource identifier
2998 */
2999void
3000resource_list_delete(struct resource_list *rl, int type, int rid)
3001{
3002        struct resource_list_entry *rle = resource_list_find(rl, type, rid);
3003
3004        if (rle) {
3005                if (rle->res != NULL)
3006                        panic("resource_list_delete: resource has not been released");
3007                STAILQ_REMOVE(rl, rle, resource_list_entry, link);
3008                free(rle, M_BUS);
3009        }
3010}
3011
3012/**
3013 * @brief Helper function for implementing BUS_ALLOC_RESOURCE()
3014 *
3015 * Implement BUS_ALLOC_RESOURCE() by looking up a resource from the list
3016 * and passing the allocation up to the parent of @p bus. This assumes
3017 * that the first entry of @c device_get_ivars(child) is a struct
3018 * resource_list. This also handles 'passthrough' allocations where a
3019 * child is a remote descendant of bus by passing the allocation up to
3020 * the parent of bus.
3021 *
3022 * Typically, a bus driver would store a list of child resources
3023 * somewhere in the child device's ivars (see device_get_ivars()) and
3024 * its implementation of BUS_ALLOC_RESOURCE() would find that list and
3025 * then call resource_list_alloc() to perform the allocation.
3026 *
3027 * @param rl            the resource list to allocate from
3028 * @param bus           the parent device of @p child
3029 * @param child         the device which is requesting an allocation
3030 * @param type          the type of resource to allocate
3031 * @param rid           a pointer to the resource identifier
3032 * @param start         hint at the start of the resource range - pass
3033 *                      @c 0UL for any start address
3034 * @param end           hint at the end of the resource range - pass
3035 *                      @c ~0UL for any end address
3036 * @param count         hint at the size of range required - pass @c 1
3037 *                      for any size
3038 * @param flags         any extra flags to control the resource
3039 *                      allocation - see @c RF_XXX flags in
3040 *                      <sys/rman.h> for details
3041 *
3042 * @returns             the resource which was allocated or @c NULL if no
3043 *                      resource could be allocated
3044 */
3045struct resource *
3046resource_list_alloc(struct resource_list *rl, device_t bus, device_t child,
3047    int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
3048{
3049        struct resource_list_entry *rle = NULL;
3050        int passthrough = (device_get_parent(child) != bus);
3051        int isdefault = (start == 0UL && end == ~0UL);
3052
3053        if (passthrough) {
3054                return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
3055                    type, rid, start, end, count, flags));
3056        }
3057
3058        rle = resource_list_find(rl, type, *rid);
3059
3060        if (!rle)
3061                return (NULL);          /* no resource of that type/rid */
3062
3063        if (rle->res)
3064                panic("resource_list_alloc: resource entry is busy");
3065
3066        if (isdefault) {
3067                start = rle->start;
3068                count = ulmax(count, rle->count);
3069                end = ulmax(rle->end, start + count - 1);
3070        }
3071
3072        rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
3073            type, rid, start, end, count, flags);
3074
3075        /*
3076         * Record the new range.
3077         */
3078        if (rle->res) {
3079                rle->start = rman_get_start(rle->res);
3080                rle->end = rman_get_end(rle->res);
3081                rle->count = count;
3082        }
3083
3084        return (rle->res);
3085}
3086
3087/**
3088 * @brief Helper function for implementing BUS_RELEASE_RESOURCE()
3089 *
3090 * Implement BUS_RELEASE_RESOURCE() using a resource list. Normally
3091 * used with resource_list_alloc().
3092 *
3093 * @param rl            the resource list which was allocated from
3094 * @param bus           the parent device of @p child
3095 * @param child         the device which is requesting a release
3096 * @param type          the type of resource to allocate
3097 * @param rid           the resource identifier
3098 * @param res           the resource to release
3099 *
3100 * @retval 0            success
3101 * @retval non-zero     a standard unix error code indicating what
3102 *                      error condition prevented the operation
3103 */
3104int
3105resource_list_release(struct resource_list *rl, device_t bus, device_t child,
3106    int type, int rid, struct resource *res)
3107{
3108        struct resource_list_entry *rle = NULL;
3109        int passthrough = (device_get_parent(child) != bus);
3110        int error;
3111
3112        if (passthrough) {
3113                return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
3114                    type, rid, res));
3115        }
3116
3117        rle = resource_list_find(rl, type, rid);
3118
3119        if (!rle)
3120                panic("resource_list_release: can't find resource");
3121        if (!rle->res)
3122                panic("resource_list_release: resource entry is not busy");
3123
3124        error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
3125            type, rid, res);
3126        if (error)
3127                return (error);
3128
3129        rle->res = NULL;
3130        return (0);
3131}
3132
3133/**
3134 * @brief Print a description of resources in a resource list
3135 *
3136 * Print all resources of a specified type, for use in BUS_PRINT_CHILD().
3137 * The name is printed if at least one resource of the given type is available.
3138 * The format is used to print resource start and end.
3139 *
3140 * @param rl            the resource list to print
3141 * @param name          the name of @p type, e.g. @c "memory"
3142 * @param type          type type of resource entry to print
3143 * @param format        printf(9) format string to print resource
3144 *                      start and end values
3145 *
3146 * @returns             the number of characters printed
3147 */
3148int
3149resource_list_print_type(struct resource_list *rl, const char *name, int type,
3150    const char *format)
3151{
3152        struct resource_list_entry *rle;
3153        int printed, retval;
3154
3155        printed = 0;
3156        retval = 0;
3157        /* Yes, this is kinda cheating */
3158        STAILQ_FOREACH(rle, rl, link) {
3159                if (rle->type == type) {
3160                        if (printed == 0)
3161                                retval += printf(" %s ", name);
3162                        else
3163                                retval += printf(",");
3164                        printed++;
3165                        retval += printf(format, rle->start);
3166                        if (rle->count > 1) {
3167                                retval += printf("-");
3168                                retval += printf(format, rle->start +
3169                                                 rle->count - 1);
3170                        }
3171                }
3172        }
3173        return (retval);
3174}
3175
3176/**
3177 * @brief Releases all the resources in a list.
3178 *
3179 * @param rl            The resource list to purge.
3180 *
3181 * @returns             nothing
3182 */
3183void
3184resource_list_purge(struct resource_list *rl)
3185{
3186        struct resource_list_entry *rle;
3187
3188        while ((rle = STAILQ_FIRST(rl)) != NULL) {
3189                if (rle->res)
3190                        bus_release_resource(rman_get_device(rle->res),
3191                            rle->type, rle->rid, rle->res);
3192                STAILQ_REMOVE_HEAD(rl, link);
3193                free(rle, M_BUS);
3194        }
3195}
3196#endif /* __rtems__ */
3197
3198device_t
3199bus_generic_add_child(device_t dev, u_int order, const char *name, int unit)
3200{
3201
3202        return (device_add_child_ordered(dev, order, name, unit));
3203}
3204
3205/**
3206 * @brief Helper function for implementing DEVICE_PROBE()
3207 *
3208 * This function can be used to help implement the DEVICE_PROBE() for
3209 * a bus (i.e. a device which has other devices attached to it). It
3210 * calls the DEVICE_IDENTIFY() method of each driver in the device's
3211 * devclass.
3212 */
3213int
3214bus_generic_probe(device_t dev)
3215{
3216        devclass_t dc = dev->devclass;
3217        driverlink_t dl;
3218
3219        TAILQ_FOREACH(dl, &dc->drivers, link) {
3220                /*
3221                 * If this driver's pass is too high, then ignore it.
3222                 * For most drivers in the default pass, this will
3223                 * never be true.  For early-pass drivers they will
3224                 * only call the identify routines of eligible drivers
3225                 * when this routine is called.  Drivers for later
3226                 * passes should have their identify routines called
3227                 * on early-pass busses during BUS_NEW_PASS().
3228                 */
3229                if (dl->pass > bus_current_pass)
3230                                continue;
3231                DEVICE_IDENTIFY(dl->driver, dev);
3232        }
3233
3234        return (0);
3235}
3236
3237/**
3238 * @brief Helper function for implementing DEVICE_ATTACH()
3239 *
3240 * This function can be used to help implement the DEVICE_ATTACH() for
3241 * a bus. It calls device_probe_and_attach() for each of the device's
3242 * children.
3243 */
3244int
3245bus_generic_attach(device_t dev)
3246{
3247        device_t child;
3248
3249        TAILQ_FOREACH(child, &dev->children, link) {
3250                device_probe_and_attach(child);
3251        }
3252
3253        return (0);
3254}
3255
3256/**
3257 * @brief Helper function for implementing DEVICE_DETACH()
3258 *
3259 * This function can be used to help implement the DEVICE_DETACH() for
3260 * a bus. It calls device_detach() for each of the device's
3261 * children.
3262 */
3263int
3264bus_generic_detach(device_t dev)
3265{
3266        device_t child;
3267        int error;
3268
3269        if (dev->state != DS_ATTACHED)
3270                return (EBUSY);
3271
3272        TAILQ_FOREACH(child, &dev->children, link) {
3273                if ((error = device_detach(child)) != 0)
3274                        return (error);
3275        }
3276
3277        return (0);
3278}
3279
3280/**
3281 * @brief Helper function for implementing DEVICE_SHUTDOWN()
3282 *
3283 * This function can be used to help implement the DEVICE_SHUTDOWN()
3284 * for a bus. It calls device_shutdown() for each of the device's
3285 * children.
3286 */
3287int
3288bus_generic_shutdown(device_t dev)
3289{
3290        device_t child;
3291
3292        TAILQ_FOREACH(child, &dev->children, link) {
3293                device_shutdown(child);
3294        }
3295
3296        return (0);
3297}
3298
3299/**
3300 * @brief Helper function for implementing DEVICE_SUSPEND()
3301 *
3302 * This function can be used to help implement the DEVICE_SUSPEND()
3303 * for a bus. It calls DEVICE_SUSPEND() for each of the device's
3304 * children. If any call to DEVICE_SUSPEND() fails, the suspend
3305 * operation is aborted and any devices which were suspended are
3306 * resumed immediately by calling their DEVICE_RESUME() methods.
3307 */
3308int
3309bus_generic_suspend(device_t dev)
3310{
3311        int             error;
3312        device_t        child, child2;
3313
3314        TAILQ_FOREACH(child, &dev->children, link) {
3315                error = DEVICE_SUSPEND(child);
3316                if (error) {
3317                        for (child2 = TAILQ_FIRST(&dev->children);
3318                             child2 && child2 != child;
3319                             child2 = TAILQ_NEXT(child2, link))
3320                                DEVICE_RESUME(child2);
3321                        return (error);
3322                }
3323        }
3324        return (0);
3325}
3326
3327/**
3328 * @brief Helper function for implementing DEVICE_RESUME()
3329 *
3330 * This function can be used to help implement the DEVICE_RESUME() for
3331 * a bus. It calls DEVICE_RESUME() on each of the device's children.
3332 */
3333int
3334bus_generic_resume(device_t dev)
3335{
3336        device_t        child;
3337
3338        TAILQ_FOREACH(child, &dev->children, link) {
3339                DEVICE_RESUME(child);
3340                /* if resume fails, there's nothing we can usefully do... */
3341        }
3342        return (0);
3343}
3344
3345/**
3346 * @brief Helper function for implementing BUS_PRINT_CHILD().
3347 *
3348 * This function prints the first part of the ascii representation of
3349 * @p child, including its name, unit and description (if any - see
3350 * device_set_desc()).
3351 *
3352 * @returns the number of characters printed
3353 */
3354int
3355bus_print_child_header(device_t dev, device_t child)
3356{
3357        int     retval = 0;
3358
3359        if (device_get_desc(child)) {
3360                retval += device_printf(child, "<%s>", device_get_desc(child));
3361        } else {
3362                retval += printf("%s", device_get_nameunit(child));
3363        }
3364
3365        return (retval);
3366}
3367
3368/**
3369 * @brief Helper function for implementing BUS_PRINT_CHILD().
3370 *
3371 * This function prints the last part of the ascii representation of
3372 * @p child, which consists of the string @c " on " followed by the
3373 * name and unit of the @p dev.
3374 *
3375 * @returns the number of characters printed
3376 */
3377int
3378bus_print_child_footer(device_t dev, device_t child)
3379{
3380        return (printf(" on %s\n", device_get_nameunit(dev)));
3381}
3382
3383/**
3384 * @brief Helper function for implementing BUS_PRINT_CHILD().
3385 *
3386 * This function simply calls bus_print_child_header() followed by
3387 * bus_print_child_footer().
3388 *
3389 * @returns the number of characters printed
3390 */
3391int
3392bus_generic_print_child(device_t dev, device_t child)
3393{
3394        int     retval = 0;
3395
3396        retval += bus_print_child_header(dev, child);
3397        retval += bus_print_child_footer(dev, child);
3398
3399        return (retval);
3400}
3401
3402/**
3403 * @brief Stub function for implementing BUS_READ_IVAR().
3404 *
3405 * @returns ENOENT
3406 */
3407int
3408bus_generic_read_ivar(device_t dev, device_t child, int index,
3409    uintptr_t * result)
3410{
3411        return (ENOENT);
3412}
3413
3414/**
3415 * @brief Stub function for implementing BUS_WRITE_IVAR().
3416 *
3417 * @returns ENOENT
3418 */
3419int
3420bus_generic_write_ivar(device_t dev, device_t child, int index,
3421    uintptr_t value)
3422{
3423        return (ENOENT);
3424}
3425
3426/**
3427 * @brief Stub function for implementing BUS_GET_RESOURCE_LIST().
3428 *
3429 * @returns NULL
3430 */
3431struct resource_list *
3432bus_generic_get_resource_list(device_t dev, device_t child)
3433{
3434        return (NULL);
3435}
3436
3437/**
3438 * @brief Helper function for implementing BUS_DRIVER_ADDED().
3439 *
3440 * This implementation of BUS_DRIVER_ADDED() simply calls the driver's
3441 * DEVICE_IDENTIFY() method to allow it to add new children to the bus
3442 * and then calls device_probe_and_attach() for each unattached child.
3443 */
3444void
3445bus_generic_driver_added(device_t dev, driver_t *driver)
3446{
3447        device_t child;
3448
3449        DEVICE_IDENTIFY(driver, dev);
3450        TAILQ_FOREACH(child, &dev->children, link) {
3451                if (child->state == DS_NOTPRESENT ||
3452                    (child->flags & DF_REBID))
3453                        device_probe_and_attach(child);
3454        }
3455}
3456
3457/**
3458 * @brief Helper function for implementing BUS_NEW_PASS().
3459 *
3460 * This implementing of BUS_NEW_PASS() first calls the identify
3461 * routines for any drivers that probe at the current pass.  Then it
3462 * walks the list of devices for this bus.  If a device is already
3463 * attached, then it calls BUS_NEW_PASS() on that device.  If the
3464 * device is not already attached, it attempts to attach a driver to
3465 * it.
3466 */
3467void
3468bus_generic_new_pass(device_t dev)
3469{
3470        driverlink_t dl;
3471        devclass_t dc;
3472        device_t child;
3473
3474        dc = dev->devclass;
3475        TAILQ_FOREACH(dl, &dc->drivers, link) {
3476                if (dl->pass == bus_current_pass)
3477                        DEVICE_IDENTIFY(dl->driver, dev);
3478        }
3479        TAILQ_FOREACH(child, &dev->children, link) {
3480                if (child->state >= DS_ATTACHED)
3481                        BUS_NEW_PASS(child);
3482                else if (child->state == DS_NOTPRESENT)
3483                        device_probe_and_attach(child);
3484        }
3485}
3486
3487/**
3488 * @brief Helper function for implementing BUS_SETUP_INTR().
3489 *
3490 * This simple implementation of BUS_SETUP_INTR() simply calls the
3491 * BUS_SETUP_INTR() method of the parent of @p dev.
3492 */
3493int
3494bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
3495    int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
3496    void **cookiep)
3497{
3498        /* Propagate up the bus hierarchy until someone handles it. */
3499        if (dev->parent)
3500                return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
3501                    filter, intr, arg, cookiep));
3502        return (EINVAL);
3503}
3504
3505/**
3506 * @brief Helper function for implementing BUS_TEARDOWN_INTR().
3507 *
3508 * This simple implementation of BUS_TEARDOWN_INTR() simply calls the
3509 * BUS_TEARDOWN_INTR() method of the parent of @p dev.
3510 */
3511int
3512bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
3513    void *cookie)
3514{
3515        /* Propagate up the bus hierarchy until someone handles it. */
3516        if (dev->parent)
3517                return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
3518        return (EINVAL);
3519}
3520
3521#ifndef __rtems__
3522/**
3523 * @brief Helper function for implementing BUS_ALLOC_RESOURCE().
3524 *
3525 * This simple implementation of BUS_ALLOC_RESOURCE() simply calls the
3526 * BUS_ALLOC_RESOURCE() method of the parent of @p dev.
3527 */
3528struct resource *
3529bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
3530    u_long start, u_long end, u_long count, u_int flags)
3531{
3532        /* Propagate up the bus hierarchy until someone handles it. */
3533        if (dev->parent)
3534                return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid,
3535                    start, end, count, flags));
3536        return (NULL);
3537}
3538
3539/**
3540 * @brief Helper function for implementing BUS_RELEASE_RESOURCE().
3541 *
3542 * This simple implementation of BUS_RELEASE_RESOURCE() simply calls the
3543 * BUS_RELEASE_RESOURCE() method of the parent of @p dev.
3544 */
3545int
3546bus_generic_release_resource(device_t dev, device_t child, int type, int rid,
3547    struct resource *r)
3548{
3549        /* Propagate up the bus hierarchy until someone handles it. */
3550        if (dev->parent)
3551                return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid,
3552                    r));
3553        return (EINVAL);
3554}
3555
3556/**
3557 * @brief Helper function for implementing BUS_ACTIVATE_RESOURCE().
3558 *
3559 * This simple implementation of BUS_ACTIVATE_RESOURCE() simply calls the
3560 * BUS_ACTIVATE_RESOURCE() method of the parent of @p dev.
3561 */
3562int
3563bus_generic_activate_resource(device_t dev, device_t child, int type, int rid,
3564    struct resource *r)
3565{
3566        /* Propagate up the bus hierarchy until someone handles it. */
3567        if (dev->parent)
3568                return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid,
3569                    r));
3570        return (EINVAL);
3571}
3572
3573/**
3574 * @brief Helper function for implementing BUS_DEACTIVATE_RESOURCE().
3575 *
3576 * This simple implementation of BUS_DEACTIVATE_RESOURCE() simply calls the
3577 * BUS_DEACTIVATE_RESOURCE() method of the parent of @p dev.
3578 */
3579int
3580bus_generic_deactivate_resource(device_t dev, device_t child, int type,
3581    int rid, struct resource *r)
3582{
3583        /* Propagate up the bus hierarchy until someone handles it. */
3584        if (dev->parent)
3585                return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
3586                    r));
3587        return (EINVAL);
3588}
3589#endif /* __rtems__ */
3590
3591/**
3592 * @brief Helper function for implementing BUS_BIND_INTR().
3593 *
3594 * This simple implementation of BUS_BIND_INTR() simply calls the
3595 * BUS_BIND_INTR() method of the parent of @p dev.
3596 */
3597int
3598bus_generic_bind_intr(device_t dev, device_t child, struct resource *irq,
3599    int cpu)
3600{
3601
3602        /* Propagate up the bus hierarchy until someone handles it. */
3603        if (dev->parent)
3604                return (BUS_BIND_INTR(dev->parent, child, irq, cpu));
3605        return (EINVAL);
3606}
3607
3608/**
3609 * @brief Helper function for implementing BUS_CONFIG_INTR().
3610 *
3611 * This simple implementation of BUS_CONFIG_INTR() simply calls the
3612 * BUS_CONFIG_INTR() method of the parent of @p dev.
3613 */
3614int
3615bus_generic_config_intr(device_t dev, int irq, enum intr_trigger trig,
3616    enum intr_polarity pol)
3617{
3618
3619        /* Propagate up the bus hierarchy until someone handles it. */
3620        if (dev->parent)
3621                return (BUS_CONFIG_INTR(dev->parent, irq, trig, pol));
3622        return (EINVAL);
3623}
3624
3625/**
3626 * @brief Helper function for implementing BUS_DESCRIBE_INTR().
3627 *
3628 * This simple implementation of BUS_DESCRIBE_INTR() simply calls the
3629 * BUS_DESCRIBE_INTR() method of the parent of @p dev.
3630 */
3631int
3632bus_generic_describe_intr(device_t dev, device_t child, struct resource *irq,
3633    void *cookie, const char *descr)
3634{
3635
3636        /* Propagate up the bus hierarchy until someone handles it. */
3637        if (dev->parent)
3638                return (BUS_DESCRIBE_INTR(dev->parent, child, irq, cookie,
3639                    descr));
3640        return (EINVAL);
3641}
3642
3643/**
3644 * @brief Helper function for implementing BUS_GET_DMA_TAG().
3645 *
3646 * This simple implementation of BUS_GET_DMA_TAG() simply calls the
3647 * BUS_GET_DMA_TAG() method of the parent of @p dev.
3648 */
3649bus_dma_tag_t
3650bus_generic_get_dma_tag(device_t dev, device_t child)
3651{
3652
3653        /* Propagate up the bus hierarchy until someone handles it. */
3654        if (dev->parent != NULL)
3655                return (BUS_GET_DMA_TAG(dev->parent, child));
3656        return (NULL);
3657}
3658
3659#ifndef __rtems__
3660/**
3661 * @brief Helper function for implementing BUS_GET_RESOURCE().
3662 *
3663 * This implementation of BUS_GET_RESOURCE() uses the
3664 * resource_list_find() function to do most of the work. It calls
3665 * BUS_GET_RESOURCE_LIST() to find a suitable resource list to
3666 * search.
3667 */
3668int
3669bus_generic_rl_get_resource(device_t dev, device_t child, int type, int rid,
3670    u_long *startp, u_long *countp)
3671{
3672        struct resource_list *          rl = NULL;
3673        struct resource_list_entry *    rle = NULL;
3674
3675        rl = BUS_GET_RESOURCE_LIST(dev, child);
3676        if (!rl)
3677                return (EINVAL);
3678
3679        rle = resource_list_find(rl, type, rid);
3680        if (!rle)
3681                return (ENOENT);
3682
3683        if (startp)
3684                *startp = rle->start;
3685        if (countp)
3686                *countp = rle->count;
3687
3688        return (0);
3689}
3690
3691/**
3692 * @brief Helper function for implementing BUS_SET_RESOURCE().
3693 *
3694 * This implementation of BUS_SET_RESOURCE() uses the
3695 * resource_list_add() function to do most of the work. It calls
3696 * BUS_GET_RESOURCE_LIST() to find a suitable resource list to
3697 * edit.
3698 */
3699int
3700bus_generic_rl_set_resource(device_t dev, device_t child, int type, int rid,
3701    u_long start, u_long count)
3702{
3703        struct resource_list *          rl = NULL;
3704
3705        rl = BUS_GET_RESOURCE_LIST(dev, child);
3706        if (!rl)
3707                return (EINVAL);
3708
3709        resource_list_add(rl, type, rid, start, (start + count - 1), count);
3710
3711        return (0);
3712}
3713
3714/**
3715 * @brief Helper function for implementing BUS_DELETE_RESOURCE().
3716 *
3717 * This implementation of BUS_DELETE_RESOURCE() uses the
3718 * resource_list_delete() function to do most of the work. It calls
3719 * BUS_GET_RESOURCE_LIST() to find a suitable resource list to
3720 * edit.
3721 */
3722void
3723bus_generic_rl_delete_resource(device_t dev, device_t child, int type, int rid)
3724{
3725        struct resource_list *          rl = NULL;
3726
3727        rl = BUS_GET_RESOURCE_LIST(dev, child);
3728        if (!rl)
3729                return;
3730
3731        resource_list_delete(rl, type, rid);
3732
3733        return;
3734}
3735
3736/**
3737 * @brief Helper function for implementing BUS_RELEASE_RESOURCE().
3738 *
3739 * This implementation of BUS_RELEASE_RESOURCE() uses the
3740 * resource_list_release() function to do most of the work. It calls
3741 * BUS_GET_RESOURCE_LIST() to find a suitable resource list.
3742 */
3743int
3744bus_generic_rl_release_resource(device_t dev, device_t child, int type,
3745    int rid, struct resource *r)
3746{
3747        struct resource_list *          rl = NULL;
3748
3749        rl = BUS_GET_RESOURCE_LIST(dev, child);
3750        if (!rl)
3751                return (EINVAL);
3752
3753        return (resource_list_release(rl, dev, child, type, rid, r));
3754}
3755
3756/**
3757 * @brief Helper function for implementing BUS_ALLOC_RESOURCE().
3758 *
3759 * This implementation of BUS_ALLOC_RESOURCE() uses the
3760 * resource_list_alloc() function to do most of the work. It calls
3761 * BUS_GET_RESOURCE_LIST() to find a suitable resource list.
3762 */
3763struct resource *
3764bus_generic_rl_alloc_resource(device_t dev, device_t child, int type,
3765    int *rid, u_long start, u_long end, u_long count, u_int flags)
3766{
3767        struct resource_list *          rl = NULL;
3768
3769        rl = BUS_GET_RESOURCE_LIST(dev, child);
3770        if (!rl)
3771                return (NULL);
3772
3773        return (resource_list_alloc(rl, dev, child, type, rid,
3774            start, end, count, flags));
3775}
3776#endif /* __rtems__ */
3777
3778/**
3779 * @brief Helper function for implementing BUS_CHILD_PRESENT().
3780 *
3781 * This simple implementation of BUS_CHILD_PRESENT() simply calls the
3782 * BUS_CHILD_PRESENT() method of the parent of @p dev.
3783 */
3784int
3785bus_generic_child_present(device_t dev, device_t child)
3786{
3787        return (BUS_CHILD_PRESENT(device_get_parent(dev), dev));
3788}
3789
3790/*
3791 * Some convenience functions to make it easier for drivers to use the
3792 * resource-management functions.  All these really do is hide the
3793 * indirection through the parent's method table, making for slightly
3794 * less-wordy code.  In the future, it might make sense for this code
3795 * to maintain some sort of a list of resources allocated by each device.
3796 */
3797
3798int
3799bus_alloc_resources(device_t dev, struct resource_spec *rs,
3800    struct resource **res)
3801{
3802        int i;
3803
3804        for (i = 0; rs[i].type != -1; i++)
3805                res[i] = NULL;
3806        for (i = 0; rs[i].type != -1; i++) {
3807                res[i] = bus_alloc_resource_any(dev,
3808                    rs[i].type, &rs[i].rid, rs[i].flags);
3809                if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) {
3810                        bus_release_resources(dev, rs, res);
3811                        return (ENXIO);
3812                }
3813        }
3814        return (0);
3815}
3816
3817void
3818bus_release_resources(device_t dev, const struct resource_spec *rs,
3819    struct resource **res)
3820{
3821        int i;
3822
3823        for (i = 0; rs[i].type != -1; i++)
3824                if (res[i] != NULL) {
3825                        bus_release_resource(
3826                            dev, rs[i].type, rs[i].rid, res[i]);
3827                        res[i] = NULL;
3828                }
3829}
3830
3831/**
3832 * @brief Wrapper function for BUS_ALLOC_RESOURCE().
3833 *
3834 * This function simply calls the BUS_ALLOC_RESOURCE() method of the
3835 * parent of @p dev.
3836 */
3837struct resource *
3838bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end,
3839    u_long count, u_int flags)
3840{
3841        if (dev->parent == NULL)
3842                return (NULL);
3843        return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
3844            count, flags));
3845}
3846
3847/**
3848 * @brief Wrapper function for BUS_ACTIVATE_RESOURCE().
3849 *
3850 * This function simply calls the BUS_ACTIVATE_RESOURCE() method of the
3851 * parent of @p dev.
3852 */
3853int
3854bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
3855{
3856        if (dev->parent == NULL)
3857                return (EINVAL);
3858        return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
3859}
3860
3861/**
3862 * @brief Wrapper function for BUS_DEACTIVATE_RESOURCE().
3863 *
3864 * This function simply calls the BUS_DEACTIVATE_RESOURCE() method of the
3865 * parent of @p dev.
3866 */
3867int
3868bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
3869{
3870        if (dev->parent == NULL)
3871                return (EINVAL);
3872        return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
3873}
3874
3875/**
3876 * @brief Wrapper function for BUS_RELEASE_RESOURCE().
3877 *
3878 * This function simply calls the BUS_RELEASE_RESOURCE() method of the
3879 * parent of @p dev.
3880 */
3881int
3882bus_release_resource(device_t dev, int type, int rid, struct resource *r)
3883{
3884        if (dev->parent == NULL)
3885                return (EINVAL);
3886        return (BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r));
3887}
3888
3889/**
3890 * @brief Wrapper function for BUS_SETUP_INTR().
3891 *
3892 * This function simply calls the BUS_SETUP_INTR() method of the
3893 * parent of @p dev.
3894 */
3895int
3896bus_setup_intr(device_t dev, struct resource *r, int flags,
3897    driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep)
3898{
3899        int error;
3900
3901        if (dev->parent == NULL)
3902                return (EINVAL);
3903        error = BUS_SETUP_INTR(dev->parent, dev, r, flags, filter, handler,
3904            arg, cookiep);
3905        if (error != 0)
3906                return (error);
3907        if (handler != NULL && !(flags & INTR_MPSAFE))
3908                device_printf(dev, "[GIANT-LOCKED]\n");
3909        if (bootverbose && (flags & INTR_MPSAFE))
3910                device_printf(dev, "[MPSAFE]\n");
3911        if (filter != NULL) {
3912                if (handler == NULL)
3913                        device_printf(dev, "[FILTER]\n");
3914                else
3915                        device_printf(dev, "[FILTER+ITHREAD]\n");
3916        } else
3917                device_printf(dev, "[ITHREAD]\n");
3918        return (0);
3919}
3920
3921/**
3922 * @brief Wrapper function for BUS_TEARDOWN_INTR().
3923 *
3924 * This function simply calls the BUS_TEARDOWN_INTR() method of the
3925 * parent of @p dev.
3926 */
3927int
3928bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
3929{
3930        if (dev->parent == NULL)
3931                return (EINVAL);
3932        return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
3933}
3934
3935/**
3936 * @brief Wrapper function for BUS_BIND_INTR().
3937 *
3938 * This function simply calls the BUS_BIND_INTR() method of the
3939 * parent of @p dev.
3940 */
3941int
3942bus_bind_intr(device_t dev, struct resource *r, int cpu)
3943{
3944        if (dev->parent == NULL)
3945                return (EINVAL);
3946        return (BUS_BIND_INTR(dev->parent, dev, r, cpu));
3947}
3948
3949/**
3950 * @brief Wrapper function for BUS_DESCRIBE_INTR().
3951 *
3952 * This function first formats the requested description into a
3953 * temporary buffer and then calls the BUS_DESCRIBE_INTR() method of
3954 * the parent of @p dev.
3955 */
3956int
3957bus_describe_intr(device_t dev, struct resource *irq, void *cookie,
3958    const char *fmt, ...)
3959{
3960        va_list ap;
3961        char descr[MAXCOMLEN + 1];
3962
3963        if (dev->parent == NULL)
3964                return (EINVAL);
3965        va_start(ap, fmt);
3966        vsnprintf(descr, sizeof(descr), fmt, ap);
3967        va_end(ap);
3968        return (BUS_DESCRIBE_INTR(dev->parent, dev, irq, cookie, descr));
3969}
3970
3971/**
3972 * @brief Wrapper function for BUS_SET_RESOURCE().
3973 *
3974 * This function simply calls the BUS_SET_RESOURCE() method of the
3975 * parent of @p dev.
3976 */
3977int
3978bus_set_resource(device_t dev, int type, int rid,
3979    u_long start, u_long count)
3980{
3981        return (BUS_SET_RESOURCE(device_get_parent(dev), dev, type, rid,
3982            start, count));
3983}
3984
3985/**
3986 * @brief Wrapper function for BUS_GET_RESOURCE().
3987 *
3988 * This function simply calls the BUS_GET_RESOURCE() method of the
3989 * parent of @p dev.
3990 */
3991int
3992bus_get_resource(device_t dev, int type, int rid,
3993    u_long *startp, u_long *countp)
3994{
3995        return (BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
3996            startp, countp));
3997}
3998
3999/**
4000 * @brief Wrapper function for BUS_GET_RESOURCE().
4001 *
4002 * This function simply calls the BUS_GET_RESOURCE() method of the
4003 * parent of @p dev and returns the start value.
4004 */
4005u_long
4006bus_get_resource_start(device_t dev, int type, int rid)
4007{
4008        u_long start, count;
4009        int error;
4010
4011        error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
4012            &start, &count);
4013        if (error)
4014                return (0);
4015        return (start);
4016}
4017
4018/**
4019 * @brief Wrapper function for BUS_GET_RESOURCE().
4020 *
4021 * This function simply calls the BUS_GET_RESOURCE() method of the
4022 * parent of @p dev and returns the count value.
4023 */
4024u_long
4025bus_get_resource_count(device_t dev, int type, int rid)
4026{
4027        u_long start, count;
4028        int error;
4029
4030        error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
4031            &start, &count);
4032        if (error)
4033                return (0);
4034        return (count);
4035}
4036
4037/**
4038 * @brief Wrapper function for BUS_DELETE_RESOURCE().
4039 *
4040 * This function simply calls the BUS_DELETE_RESOURCE() method of the
4041 * parent of @p dev.
4042 */
4043void
4044bus_delete_resource(device_t dev, int type, int rid)
4045{
4046        BUS_DELETE_RESOURCE(device_get_parent(dev), dev, type, rid);
4047}
4048
4049/**
4050 * @brief Wrapper function for BUS_CHILD_PRESENT().
4051 *
4052 * This function simply calls the BUS_CHILD_PRESENT() method of the
4053 * parent of @p dev.
4054 */
4055int
4056bus_child_present(device_t child)
4057{
4058        return (BUS_CHILD_PRESENT(device_get_parent(child), child));
4059}
4060
4061/**
4062 * @brief Wrapper function for BUS_CHILD_PNPINFO_STR().
4063 *
4064 * This function simply calls the BUS_CHILD_PNPINFO_STR() method of the
4065 * parent of @p dev.
4066 */
4067int
4068bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen)
4069{
4070        device_t parent;
4071
4072        parent = device_get_parent(child);
4073        if (parent == NULL) {
4074                *buf = '\0';
4075                return (0);
4076        }
4077        return (BUS_CHILD_PNPINFO_STR(parent, child, buf, buflen));
4078}
4079
4080/**
4081 * @brief Wrapper function for BUS_CHILD_LOCATION_STR().
4082 *
4083 * This function simply calls the BUS_CHILD_LOCATION_STR() method of the
4084 * parent of @p dev.
4085 */
4086int
4087bus_child_location_str(device_t child, char *buf, size_t buflen)
4088{
4089        device_t parent;
4090
4091        parent = device_get_parent(child);
4092        if (parent == NULL) {
4093                *buf = '\0';
4094                return (0);
4095        }
4096        return (BUS_CHILD_LOCATION_STR(parent, child, buf, buflen));
4097}
4098
4099/**
4100 * @brief Wrapper function for BUS_GET_DMA_TAG().
4101 *
4102 * This function simply calls the BUS_GET_DMA_TAG() method of the
4103 * parent of @p dev.
4104 */
4105bus_dma_tag_t
4106bus_get_dma_tag(device_t dev)
4107{
4108        device_t parent;
4109
4110        parent = device_get_parent(dev);
4111        if (parent == NULL)
4112                return (NULL);
4113        return (BUS_GET_DMA_TAG(parent, dev));
4114}
4115
4116/* Resume all devices and then notify userland that we're up again. */
4117static int
4118root_resume(device_t dev)
4119{
4120        int error;
4121
4122        error = bus_generic_resume(dev);
4123        if (error == 0)
4124                devctl_notify("kern", "power", "resume", NULL);
4125        return (error);
4126}
4127
4128static int
4129root_print_child(device_t dev, device_t child)
4130{
4131        int     retval = 0;
4132
4133        retval += bus_print_child_header(dev, child);
4134        retval += printf("\n");
4135
4136        return (retval);
4137}
4138
4139static int
4140root_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
4141    driver_filter_t *filter, driver_intr_t *intr, void *arg, void **cookiep)
4142{
4143        /*
4144         * If an interrupt mapping gets to here something bad has happened.
4145         */
4146        panic("root_setup_intr");
4147}
4148
4149/*
4150 * If we get here, assume that the device is permanant and really is
4151 * present in the system.  Removable bus drivers are expected to intercept
4152 * this call long before it gets here.  We return -1 so that drivers that
4153 * really care can check vs -1 or some ERRNO returned higher in the food
4154 * chain.
4155 */
4156static int
4157root_child_present(device_t dev, device_t child)
4158{
4159        return (-1);
4160}
4161
4162static kobj_method_t root_methods[] = {
4163        /* Device interface */
4164        KOBJMETHOD(device_shutdown,     bus_generic_shutdown),
4165        KOBJMETHOD(device_suspend,      bus_generic_suspend),
4166        KOBJMETHOD(device_resume,       root_resume),
4167
4168        /* Bus interface */
4169        KOBJMETHOD(bus_print_child,     root_print_child),
4170        KOBJMETHOD(bus_read_ivar,       bus_generic_read_ivar),
4171        KOBJMETHOD(bus_write_ivar,      bus_generic_write_ivar),
4172        KOBJMETHOD(bus_setup_intr,      root_setup_intr),
4173        KOBJMETHOD(bus_child_present,   root_child_present),
4174
4175        KOBJMETHOD_END
4176};
4177
4178static driver_t root_driver = {
4179        "root",
4180        root_methods,
4181        1,                      /* no softc */
4182};
4183
4184device_t        root_bus;
4185devclass_t      root_devclass;
4186
4187static int
4188root_bus_module_handler(module_t mod, int what, void* arg)
4189{
4190        switch (what) {
4191        case MOD_LOAD:
4192                TAILQ_INIT(&bus_data_devices);
4193                kobj_class_compile((kobj_class_t) &root_driver);
4194                root_bus = make_device(NULL, "root", 0);
4195                root_bus->desc = "System root bus";
4196                kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
4197                root_bus->driver = &root_driver;
4198                root_bus->state = DS_ATTACHED;
4199                root_devclass = devclass_find_internal("root", NULL, FALSE);
4200                devinit();
4201                return (0);
4202
4203        case MOD_SHUTDOWN:
4204                device_shutdown(root_bus);
4205                return (0);
4206        default:
4207                return (EOPNOTSUPP);
4208        }
4209
4210        return (0);
4211}
4212
4213static moduledata_t root_bus_mod = {
4214        "rootbus",
4215        root_bus_module_handler,
4216        NULL
4217};
4218DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
4219
4220/**
4221 * @brief Automatically configure devices
4222 *
4223 * This function begins the autoconfiguration process by calling
4224 * device_probe_and_attach() for each child of the @c root0 device.
4225 */
4226void
4227root_bus_configure(void)
4228{
4229
4230        PDEBUG(("."));
4231
4232        /* Eventually this will be split up, but this is sufficient for now. */
4233        bus_set_pass(BUS_PASS_DEFAULT);
4234}
4235
4236/**
4237 * @brief Module handler for registering device drivers
4238 *
4239 * This module handler is used to automatically register device
4240 * drivers when modules are loaded. If @p what is MOD_LOAD, it calls
4241 * devclass_add_driver() for the driver described by the
4242 * driver_module_data structure pointed to by @p arg
4243 */
4244int
4245driver_module_handler(module_t mod, int what, void *arg)
4246{
4247        struct driver_module_data *dmd;
4248        devclass_t bus_devclass;
4249        kobj_class_t driver;
4250        int error, pass;
4251
4252        dmd = (struct driver_module_data *)arg;
4253        bus_devclass = devclass_find_internal(dmd->dmd_busname, NULL, TRUE);
4254        error = 0;
4255
4256        switch (what) {
4257        case MOD_LOAD:
4258                if (dmd->dmd_chainevh)
4259                        error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
4260
4261                pass = dmd->dmd_pass;
4262                driver = dmd->dmd_driver;
4263                PDEBUG(("Loading module: driver %s on bus %s (pass %d)",
4264                    DRIVERNAME(driver), dmd->dmd_busname, pass));
4265                error = devclass_add_driver(bus_devclass, driver, pass,
4266                    dmd->dmd_devclass);
4267                break;
4268
4269        case MOD_UNLOAD:
4270                PDEBUG(("Unloading module: driver %s from bus %s",
4271                    DRIVERNAME(dmd->dmd_driver),
4272                    dmd->dmd_busname));
4273                error = devclass_delete_driver(bus_devclass,
4274                    dmd->dmd_driver);
4275
4276                if (!error && dmd->dmd_chainevh)
4277                        error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
4278                break;
4279        case MOD_QUIESCE:
4280                PDEBUG(("Quiesce module: driver %s from bus %s",
4281                    DRIVERNAME(dmd->dmd_driver),
4282                    dmd->dmd_busname));
4283                error = devclass_quiesce_driver(bus_devclass,
4284                    dmd->dmd_driver);
4285
4286                if (!error && dmd->dmd_chainevh)
4287                        error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
4288                break;
4289        default:
4290                error = EOPNOTSUPP;
4291                break;
4292        }
4293
4294        return (error);
4295}
4296
4297#ifndef __rtems__
4298/**
4299 * @brief Enumerate all hinted devices for this bus.
4300 *
4301 * Walks through the hints for this bus and calls the bus_hinted_child
4302 * routine for each one it fines.  It searches first for the specific
4303 * bus that's being probed for hinted children (eg isa0), and then for
4304 * generic children (eg isa).
4305 *
4306 * @param       dev     bus device to enumerate
4307 */
4308void
4309bus_enumerate_hinted_children(device_t bus)
4310{
4311        int i;
4312        const char *dname, *busname;
4313        int dunit;
4314
4315        /*
4316         * enumerate all devices on the specific bus
4317         */
4318        busname = device_get_nameunit(bus);
4319        i = 0;
4320        while (resource_find_match(&i, &dname, &dunit, "at", busname) == 0)
4321                BUS_HINTED_CHILD(bus, dname, dunit);
4322
4323        /*
4324         * and all the generic ones.
4325         */
4326        busname = device_get_name(bus);
4327        i = 0;
4328        while (resource_find_match(&i, &dname, &dunit, "at", busname) == 0)
4329                BUS_HINTED_CHILD(bus, dname, dunit);
4330}
4331#endif /* __rtems__ */
4332
4333#ifdef BUS_DEBUG
4334
4335/* the _short versions avoid iteration by not calling anything that prints
4336 * more than oneliners. I love oneliners.
4337 */
4338
4339static void
4340print_device_short(device_t dev, int indent)
4341{
4342        if (!dev)
4343                return;
4344
4345        indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
4346            dev->unit, dev->desc,
4347            (dev->parent? "":"no "),
4348            (TAILQ_EMPTY(&dev->children)? "no ":""),
4349            (dev->flags&DF_ENABLED? "enabled,":"disabled,"),
4350            (dev->flags&DF_FIXEDCLASS? "fixed,":""),
4351            (dev->flags&DF_WILDCARD? "wildcard,":""),
4352            (dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
4353            (dev->flags&DF_REBID? "rebiddable,":""),
4354            (dev->ivars? "":"no "),
4355            (dev->softc? "":"no "),
4356            dev->busy));
4357}
4358
4359static void
4360print_device(device_t dev, int indent)
4361{
4362        if (!dev)
4363                return;
4364
4365        print_device_short(dev, indent);
4366
4367        indentprintf(("Parent:\n"));
4368        print_device_short(dev->parent, indent+1);
4369        indentprintf(("Driver:\n"));
4370        print_driver_short(dev->driver, indent+1);
4371        indentprintf(("Devclass:\n"));
4372        print_devclass_short(dev->devclass, indent+1);
4373}
4374
4375void
4376print_device_tree_short(device_t dev, int indent)
4377/* print the device and all its children (indented) */
4378{
4379        device_t child;
4380
4381        if (!dev)
4382                return;
4383
4384        print_device_short(dev, indent);
4385
4386        TAILQ_FOREACH(child, &dev->children, link) {
4387                print_device_tree_short(child, indent+1);
4388        }
4389}
4390
4391void
4392print_device_tree(device_t dev, int indent)
4393/* print the device and all its children (indented) */
4394{
4395        device_t child;
4396
4397        if (!dev)
4398                return;
4399
4400        print_device(dev, indent);
4401
4402        TAILQ_FOREACH(child, &dev->children, link) {
4403                print_device_tree(child, indent+1);
4404        }
4405}
4406
4407static void
4408print_driver_short(driver_t *driver, int indent)
4409{
4410        if (!driver)
4411                return;
4412
4413        indentprintf(("driver %s: softc size = %zd\n",
4414            driver->name, driver->size));
4415}
4416
4417static void
4418print_driver(driver_t *driver, int indent)
4419{
4420        if (!driver)
4421                return;
4422
4423        print_driver_short(driver, indent);
4424}
4425
4426
4427static void
4428print_driver_list(driver_list_t drivers, int indent)
4429{
4430        driverlink_t driver;
4431
4432        TAILQ_FOREACH(driver, &drivers, link) {
4433                print_driver(driver->driver, indent);
4434        }
4435}
4436
4437static void
4438print_devclass_short(devclass_t dc, int indent)
4439{
4440        if ( !dc )
4441                return;
4442
4443        indentprintf(("devclass %s: max units = %d\n", dc->name, dc->maxunit));
4444}
4445
4446static void
4447print_devclass(devclass_t dc, int indent)
4448{
4449        int i;
4450
4451        if ( !dc )
4452                return;
4453
4454        print_devclass_short(dc, indent);
4455        indentprintf(("Drivers:\n"));
4456        print_driver_list(dc->drivers, indent+1);
4457
4458        indentprintf(("Devices:\n"));
4459        for (i = 0; i < dc->maxunit; i++)
4460                if (dc->devices[i])
4461                        print_device(dc->devices[i], indent+1);
4462}
4463
4464void
4465print_devclass_list_short(void)
4466{
4467        devclass_t dc;
4468
4469        printf("Short listing of devclasses, drivers & devices:\n");
4470        TAILQ_FOREACH(dc, &devclasses, link) {
4471                print_devclass_short(dc, 0);
4472        }
4473}
4474
4475void
4476print_devclass_list(void)
4477{
4478        devclass_t dc;
4479
4480        printf("Full listing of devclasses, drivers & devices:\n");
4481        TAILQ_FOREACH(dc, &devclasses, link) {
4482                print_devclass(dc, 0);
4483        }
4484}
4485
4486#endif
4487
4488#ifndef __rtems__
4489/*
4490 * User-space access to the device tree.
4491 *
4492 * We implement a small set of nodes:
4493 *
4494 * hw.bus                       Single integer read method to obtain the
4495 *                              current generation count.
4496 * hw.bus.devices               Reads the entire device tree in flat space.
4497 * hw.bus.rman                  Resource manager interface
4498 *
4499 * We might like to add the ability to scan devclasses and/or drivers to
4500 * determine what else is currently loaded/available.
4501 */
4502
4503static int
4504sysctl_bus(SYSCTL_HANDLER_ARGS)
4505{
4506        struct u_businfo        ubus;
4507
4508        ubus.ub_version = BUS_USER_VERSION;
4509        ubus.ub_generation = bus_data_generation;
4510
4511        return (SYSCTL_OUT(req, &ubus, sizeof(ubus)));
4512}
4513SYSCTL_NODE(_hw_bus, OID_AUTO, info, CTLFLAG_RW, sysctl_bus,
4514    "bus-related data");
4515
4516static int
4517sysctl_devices(SYSCTL_HANDLER_ARGS)
4518{
4519        int                     *name = (int *)arg1;
4520        u_int                   namelen = arg2;
4521        int                     index;
4522        struct device           *dev;
4523        struct u_device         udev;   /* XXX this is a bit big */
4524        int                     error;
4525
4526        if (namelen != 2)
4527                return (EINVAL);
4528
4529        if (bus_data_generation_check(name[0]))
4530                return (EINVAL);
4531
4532        index = name[1];
4533
4534        /*
4535         * Scan the list of devices, looking for the requested index.
4536         */
4537        TAILQ_FOREACH(dev, &bus_data_devices, devlink) {
4538                if (index-- == 0)
4539                        break;
4540        }
4541        if (dev == NULL)
4542                return (ENOENT);
4543
4544        /*
4545         * Populate the return array.
4546         */
4547        bzero(&udev, sizeof(udev));
4548        udev.dv_handle = (uintptr_t)dev;
4549        udev.dv_parent = (uintptr_t)dev->parent;
4550        if (dev->nameunit != NULL)
4551                strlcpy(udev.dv_name, dev->nameunit, sizeof(udev.dv_name));
4552        if (dev->desc != NULL)
4553                strlcpy(udev.dv_desc, dev->desc, sizeof(udev.dv_desc));
4554        if (dev->driver != NULL && dev->driver->name != NULL)
4555                strlcpy(udev.dv_drivername, dev->driver->name,
4556                    sizeof(udev.dv_drivername));
4557        bus_child_pnpinfo_str(dev, udev.dv_pnpinfo, sizeof(udev.dv_pnpinfo));
4558        bus_child_location_str(dev, udev.dv_location, sizeof(udev.dv_location));
4559        udev.dv_devflags = dev->devflags;
4560        udev.dv_flags = dev->flags;
4561        udev.dv_state = dev->state;
4562        error = SYSCTL_OUT(req, &udev, sizeof(udev));
4563        return (error);
4564}
4565
4566SYSCTL_NODE(_hw_bus, OID_AUTO, devices, CTLFLAG_RD, sysctl_devices,
4567    "system device tree");
4568#endif /* __rtems__ */
4569
4570int
4571bus_data_generation_check(int generation)
4572{
4573        if (generation != bus_data_generation)
4574                return (1);
4575
4576        /* XXX generate optimised lists here? */
4577        return (0);
4578}
4579
4580void
4581bus_data_generation_update(void)
4582{
4583        bus_data_generation++;
4584}
4585
4586#ifndef __rtems__
4587int
4588bus_free_resource(device_t dev, int type, struct resource *r)
4589{
4590        if (r == NULL)
4591                return (0);
4592        return (bus_release_resource(dev, type, rman_get_rid(r), r));
4593}
4594#endif /* __rtems__ */
Note: See TracBrowser for help on using the repository browser.