aboutsummaryrefslogtreecommitdiff
path: root/sys/boot/kshim/bsd_kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/kshim/bsd_kernel.c')
-rw-r--r--sys/boot/kshim/bsd_kernel.c1459
1 files changed, 0 insertions, 1459 deletions
diff --git a/sys/boot/kshim/bsd_kernel.c b/sys/boot/kshim/bsd_kernel.c
deleted file mode 100644
index 75eccb1d6725..000000000000
--- a/sys/boot/kshim/bsd_kernel.c
+++ /dev/null
@@ -1,1459 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <bsd_global.h>
-
-struct usb_process usb_process[USB_PROC_MAX];
-
-static device_t usb_pci_root;
-
-/*------------------------------------------------------------------------*
- * Implementation of mutex API
- *------------------------------------------------------------------------*/
-
-struct mtx Giant;
-int (*bus_alloc_resource_any_cb)(struct resource *res, device_t dev,
- int type, int *rid, unsigned int flags);
-int (*ofw_bus_status_ok_cb)(device_t dev);
-int (*ofw_bus_is_compatible_cb)(device_t dev, char *name);
-
-static void
-mtx_system_init(void *arg)
-{
- mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
-}
-SYSINIT(mtx_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, mtx_system_init, NULL);
-
-int
-bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
- bus_size_t boundary, bus_addr_t lowaddr,
- bus_addr_t highaddr, bus_dma_filter_t *filter,
- void *filterarg, bus_size_t maxsize, int nsegments,
- bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
- void *lockfuncarg, bus_dma_tag_t *dmat)
-{
- struct bus_dma_tag *ret;
-
- ret = malloc(sizeof(struct bus_dma_tag), XXX, XXX);
- if (*dmat == NULL)
- return (ENOMEM);
- ret->alignment = alignment;
- ret->maxsize = maxsize;
-
- *dmat = ret;
-
- return (0);
-}
-
-int
-bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
- bus_dmamap_t *mapp)
-{
- void *addr;
-
- addr = malloc(dmat->maxsize + dmat->alignment, XXX, XXX);
- if (addr == NULL)
- return (ENOMEM);
-
- *mapp = addr;
- addr = (void*)(((uintptr_t)addr + dmat->alignment - 1) & ~(dmat->alignment - 1));
-
- *vaddr = addr;
- return (0);
-}
-
-int
-bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
- bus_size_t buflen, bus_dmamap_callback_t *callback,
- void *callback_arg, int flags)
-{
- bus_dma_segment_t segs[1];
-
- segs[0].ds_addr = (uintptr_t)buf;
- segs[0].ds_len = buflen;
-
- (*callback)(callback_arg, segs, 1, 0);
-
- return (0);
-}
-
-void
-bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
-{
-
- free(map, XXX);
-}
-
-int
-bus_dma_tag_destroy(bus_dma_tag_t dmat)
-{
-
- free(dmat, XXX);
- return (0);
-}
-
-struct resource *
-bus_alloc_resource_any(device_t dev, int type, int *rid, unsigned int flags)
-{
- struct resource *res;
- int ret = EINVAL;
-
- res = malloc(sizeof(*res), XXX, XXX);
- if (res == NULL)
- return (NULL);
-
- res->__r_i = malloc(sizeof(struct resource_i), XXX, XXX);
- if (res->__r_i == NULL) {
- free(res, XXX);
- return (NULL);
- }
-
- if (bus_alloc_resource_any_cb != NULL)
- ret = (*bus_alloc_resource_any_cb)(res, dev, type, rid, flags);
- if (ret == 0)
- return (res);
-
- free(res->__r_i, XXX);
- free(res, XXX);
- return (NULL);
-}
-
-int
-bus_alloc_resources(device_t dev, struct resource_spec *rs,
- struct resource **res)
-{
- int i;
-
- for (i = 0; rs[i].type != -1; i++)
- res[i] = NULL;
- for (i = 0; rs[i].type != -1; i++) {
- res[i] = bus_alloc_resource_any(dev,
- rs[i].type, &rs[i].rid, rs[i].flags);
- if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) {
- bus_release_resources(dev, rs, res);
- return (ENXIO);
- }
- }
- return (0);
-}
-
-void
-bus_release_resources(device_t dev, const struct resource_spec *rs,
- struct resource **res)
-{
- int i;
-
- for (i = 0; rs[i].type != -1; i++)
- if (res[i] != NULL) {
- bus_release_resource(
- dev, rs[i].type, rs[i].rid, res[i]);
- res[i] = NULL;
- }
-}
-
-int
-bus_setup_intr(device_t dev, struct resource *r, int flags,
- driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep)
-{
-
- dev->dev_irq_filter = filter;
- dev->dev_irq_fn = handler;
- dev->dev_irq_arg = arg;
-
- return (0);
-}
-
-int
-bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
-{
-
- dev->dev_irq_filter = NULL;
- dev->dev_irq_fn = NULL;
- dev->dev_irq_arg = NULL;
-
- return (0);
-}
-
-int
-bus_release_resource(device_t dev, int type, int rid, struct resource *r)
-{
- /* Resource releasing is not supported */
- return (EINVAL);
-}
-
-int
-bus_generic_attach(device_t dev)
-{
- device_t child;
-
- TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
- device_probe_and_attach(child);
- }
-
- return (0);
-}
-
-bus_space_tag_t
-rman_get_bustag(struct resource *r)
-{
-
- return (r->r_bustag);
-}
-
-bus_space_handle_t
-rman_get_bushandle(struct resource *r)
-{
-
- return (r->r_bushandle);
-}
-
-u_long
-rman_get_size(struct resource *r)
-{
-
- return (r->__r_i->r_end - r->__r_i->r_start + 1);
-}
-
-int
-ofw_bus_status_okay(device_t dev)
-{
- if (ofw_bus_status_ok_cb == NULL)
- return (0);
-
- return ((*ofw_bus_status_ok_cb)(dev));
-}
-
-int
-ofw_bus_is_compatible(device_t dev, char *name)
-{
- if (ofw_bus_is_compatible_cb == NULL)
- return (0);
-
- return ((*ofw_bus_is_compatible_cb)(dev, name));
-}
-
-void
-mtx_init(struct mtx *mtx, const char *name, const char *type, int opt)
-{
- mtx->owned = 0;
- mtx->parent = mtx;
-}
-
-void
-mtx_lock(struct mtx *mtx)
-{
- mtx = mtx->parent;
- mtx->owned++;
-}
-
-void
-mtx_unlock(struct mtx *mtx)
-{
- mtx = mtx->parent;
- mtx->owned--;
-}
-
-int
-mtx_owned(struct mtx *mtx)
-{
- mtx = mtx->parent;
- return (mtx->owned != 0);
-}
-
-void
-mtx_destroy(struct mtx *mtx)
-{
- /* NOP */
-}
-
-/*------------------------------------------------------------------------*
- * Implementation of shared/exclusive mutex API
- *------------------------------------------------------------------------*/
-
-void
-sx_init_flags(struct sx *sx, const char *name, int flags)
-{
- sx->owned = 0;
-}
-
-void
-sx_destroy(struct sx *sx)
-{
- /* NOP */
-}
-
-void
-sx_xlock(struct sx *sx)
-{
- sx->owned++;
-}
-
-void
-sx_xunlock(struct sx *sx)
-{
- sx->owned--;
-}
-
-int
-sx_xlocked(struct sx *sx)
-{
- return (sx->owned != 0);
-}
-
-/*------------------------------------------------------------------------*
- * Implementaiton of condition variable API
- *------------------------------------------------------------------------*/
-
-void
-cv_init(struct cv *cv, const char *desc)
-{
- cv->sleeping = 0;
-}
-
-void
-cv_destroy(struct cv *cv)
-{
- /* NOP */
-}
-
-void
-cv_wait(struct cv *cv, struct mtx *mtx)
-{
- cv_timedwait(cv, mtx, -1);
-}
-
-int
-cv_timedwait(struct cv *cv, struct mtx *mtx, int timo)
-{
- int start = ticks;
- int delta;
- int time = 0;
-
- if (cv->sleeping)
- return (EWOULDBLOCK); /* not allowed */
-
- cv->sleeping = 1;
-
- while (cv->sleeping) {
- if (timo >= 0) {
- delta = ticks - start;
- if (delta >= timo || delta < 0)
- break;
- }
- mtx_unlock(mtx);
-
- usb_idle();
-
- if (++time >= (1000000 / hz)) {
- time = 0;
- callout_process(1);
- }
-
- /* Sleep for 1 us */
- delay(1);
-
- mtx_lock(mtx);
- }
-
- if (cv->sleeping) {
- cv->sleeping = 0;
- return (EWOULDBLOCK); /* not allowed */
- }
- return (0);
-}
-
-void
-cv_signal(struct cv *cv)
-{
- cv->sleeping = 0;
-}
-
-void
-cv_broadcast(struct cv *cv)
-{
- cv->sleeping = 0;
-}
-
-/*------------------------------------------------------------------------*
- * Implementation of callout API
- *------------------------------------------------------------------------*/
-
-static void callout_proc_msg(struct usb_proc_msg *);
-
-volatile int ticks = 0;
-
-static LIST_HEAD(, callout) head_callout = LIST_HEAD_INITIALIZER(&head_callout);
-
-static struct mtx mtx_callout;
-static struct usb_proc_msg callout_msg[2];
-
-static void
-callout_system_init(void *arg)
-{
- mtx_init(&mtx_callout, "callout-mtx", NULL, MTX_DEF | MTX_RECURSE);
-
- callout_msg[0].pm_callback = &callout_proc_msg;
- callout_msg[1].pm_callback = &callout_proc_msg;
-}
-SYSINIT(callout_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, callout_system_init, NULL);
-
-static void
-callout_callback(struct callout *c)
-{
- mtx_lock(c->mtx);
-
- mtx_lock(&mtx_callout);
- if (c->entry.le_prev != NULL) {
- LIST_REMOVE(c, entry);
- c->entry.le_prev = NULL;
- }
- mtx_unlock(&mtx_callout);
-
- if (c->c_func != NULL)
- (c->c_func) (c->c_arg);
-
- if (!(c->flags & CALLOUT_RETURNUNLOCKED))
- mtx_unlock(c->mtx);
-}
-
-void
-callout_process(int timeout)
-{
- ticks += timeout;
- usb_proc_msignal(usb_process + 2, &callout_msg[0], &callout_msg[1]);
-}
-
-static void
-callout_proc_msg(struct usb_proc_msg *pmsg)
-{
- struct callout *c;
- int delta;
-
-repeat:
- mtx_lock(&mtx_callout);
-
- LIST_FOREACH(c, &head_callout, entry) {
-
- delta = c->timeout - ticks;
- if (delta < 0) {
- mtx_unlock(&mtx_callout);
-
- callout_callback(c);
-
- goto repeat;
- }
- }
- mtx_unlock(&mtx_callout);
-}
-
-void
-callout_init_mtx(struct callout *c, struct mtx *mtx, int flags)
-{
- memset(c, 0, sizeof(*c));
-
- if (mtx == NULL)
- mtx = &Giant;
-
- c->mtx = mtx;
- c->flags = (flags & CALLOUT_RETURNUNLOCKED);
-}
-
-void
-callout_reset(struct callout *c, int to_ticks,
- void (*func) (void *), void *arg)
-{
- callout_stop(c);
-
- c->c_func = func;
- c->c_arg = arg;
- c->timeout = ticks + to_ticks;
-
- mtx_lock(&mtx_callout);
- LIST_INSERT_HEAD(&head_callout, c, entry);
- mtx_unlock(&mtx_callout);
-}
-
-void
-callout_stop(struct callout *c)
-{
- mtx_lock(&mtx_callout);
-
- if (c->entry.le_prev != NULL) {
- LIST_REMOVE(c, entry);
- c->entry.le_prev = NULL;
- }
- mtx_unlock(&mtx_callout);
-
- c->c_func = NULL;
- c->c_arg = NULL;
-}
-
-void
-callout_drain(struct callout *c)
-{
- if (c->mtx == NULL)
- return; /* not initialised */
-
- mtx_lock(c->mtx);
- callout_stop(c);
- mtx_unlock(c->mtx);
-}
-
-int
-callout_pending(struct callout *c)
-{
- int retval;
-
- mtx_lock(&mtx_callout);
- retval = (c->entry.le_prev != NULL);
- mtx_unlock(&mtx_callout);
-
- return (retval);
-}
-
-/*------------------------------------------------------------------------*
- * Implementation of device API
- *------------------------------------------------------------------------*/
-
-static const char unknown_string[] = { "unknown" };
-
-static TAILQ_HEAD(, module_data) module_head =
- TAILQ_HEAD_INITIALIZER(module_head);
-
-static uint8_t
-devclass_equal(const char *a, const char *b)
-{
- char ta, tb;
-
- if (a == b)
- return (1);
-
- while (1) {
- ta = *a;
- tb = *b;
- if (ta != tb)
- return (0);
- if (ta == 0)
- break;
- a++;
- b++;
- }
- return (1);
-}
-
-int
-bus_generic_resume(device_t dev)
-{
- return (0);
-}
-
-int
-bus_generic_shutdown(device_t dev)
-{
- return (0);
-}
-
-int
-bus_generic_suspend(device_t dev)
-{
- return (0);
-}
-
-int
-bus_generic_print_child(device_t dev, device_t child)
-{
- return (0);
-}
-
-void
-bus_generic_driver_added(device_t dev, driver_t *driver)
-{
- return;
-}
-
-device_t
-device_get_parent(device_t dev)
-{
- return (dev ? dev->dev_parent : NULL);
-}
-
-void
-device_set_interrupt(device_t dev, driver_filter_t *filter,
- driver_intr_t *fn, void *arg)
-{
- dev->dev_irq_filter = filter;
- dev->dev_irq_fn = fn;
- dev->dev_irq_arg = arg;
-}
-
-void
-device_run_interrupts(device_t parent)
-{
- device_t child;
-
- if (parent == NULL)
- return;
-
- TAILQ_FOREACH(child, &parent->dev_children, dev_link) {
- int status;
- if (child->dev_irq_filter != NULL)
- status = child->dev_irq_filter(child->dev_irq_arg);
- else
- status = FILTER_SCHEDULE_THREAD;
-
- if (status == FILTER_SCHEDULE_THREAD) {
- if (child->dev_irq_fn != NULL)
- (child->dev_irq_fn) (child->dev_irq_arg);
- }
- }
-}
-
-void
-device_set_ivars(device_t dev, void *ivars)
-{
- dev->dev_aux = ivars;
-}
-
-void *
-device_get_ivars(device_t dev)
-{
- return (dev ? dev->dev_aux : NULL);
-}
-
-int
-device_get_unit(device_t dev)
-{
- return (dev ? dev->dev_unit : 0);
-}
-
-int
-bus_generic_detach(device_t dev)
-{
- device_t child;
- int error;
-
- if (!dev->dev_attached)
- return (EBUSY);
-
- TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
- if ((error = device_detach(child)) != 0)
- return (error);
- }
- return (0);
-}
-
-const char *
-device_get_nameunit(device_t dev)
-{
- if (dev && dev->dev_nameunit[0])
- return (dev->dev_nameunit);
-
- return (unknown_string);
-}
-
-static uint8_t
-devclass_create(devclass_t *dc_pp)
-{
- if (dc_pp == NULL) {
- return (1);
- }
- if (dc_pp[0] == NULL) {
- dc_pp[0] = malloc(sizeof(**(dc_pp)),
- M_DEVBUF, M_WAITOK | M_ZERO);
-
- if (dc_pp[0] == NULL) {
- return (1);
- }
- }
- return (0);
-}
-
-static const struct module_data *
-devclass_find_create(const char *classname)
-{
- const struct module_data *mod;
-
- TAILQ_FOREACH(mod, &module_head, entry) {
- if (devclass_equal(mod->mod_name, classname)) {
- if (devclass_create(mod->devclass_pp)) {
- continue;
- }
- return (mod);
- }
- }
- return (NULL);
-}
-
-static uint8_t
-devclass_add_device(const struct module_data *mod, device_t dev)
-{
- device_t *pp_dev;
- device_t *end;
- uint8_t unit;
-
- pp_dev = mod->devclass_pp[0]->dev_list;
- end = pp_dev + DEVCLASS_MAXUNIT;
- unit = 0;
-
- while (pp_dev != end) {
- if (*pp_dev == NULL) {
- *pp_dev = dev;
- dev->dev_unit = unit;
- dev->dev_module = mod;
- snprintf(dev->dev_nameunit,
- sizeof(dev->dev_nameunit),
- "%s%d", device_get_name(dev), unit);
- return (0);
- }
- pp_dev++;
- unit++;
- }
- DPRINTF("Could not add device to devclass.\n");
- return (1);
-}
-
-static void
-devclass_delete_device(const struct module_data *mod, device_t dev)
-{
- if (mod == NULL) {
- return;
- }
- mod->devclass_pp[0]->dev_list[dev->dev_unit] = NULL;
- dev->dev_module = NULL;
-}
-
-static device_t
-make_device(device_t parent, const char *name)
-{
- device_t dev = NULL;
- const struct module_data *mod = NULL;
-
- if (name) {
-
- mod = devclass_find_create(name);
-
- if (!mod) {
-
- DPRINTF("%s:%d:%s: can't find device "
- "class %s\n", __FILE__, __LINE__,
- __FUNCTION__, name);
-
- goto done;
- }
- }
- dev = malloc(sizeof(*dev),
- M_DEVBUF, M_WAITOK | M_ZERO);
-
- if (dev == NULL)
- goto done;
-
- dev->dev_parent = parent;
- TAILQ_INIT(&dev->dev_children);
-
- if (name) {
- dev->dev_fixed_class = 1;
- if (devclass_add_device(mod, dev)) {
- goto error;
- }
- }
-done:
- return (dev);
-
-error:
- if (dev) {
- free(dev, M_DEVBUF);
- }
- return (NULL);
-}
-
-device_t
-device_add_child(device_t dev, const char *name, int unit)
-{
- device_t child;
-
- if (unit != -1) {
- device_printf(dev, "Unit is not -1\n");
- }
- child = make_device(dev, name);
- if (child == NULL) {
- device_printf(dev, "Could not add child '%s'\n", name);
- goto done;
- }
- if (dev == NULL) {
- /* no parent */
- goto done;
- }
- TAILQ_INSERT_TAIL(&dev->dev_children, child, dev_link);
-done:
- return (child);
-}
-
-int
-device_delete_child(device_t dev, device_t child)
-{
- int error = 0;
- device_t grandchild;
-
- /* detach parent before deleting children, if any */
- error = device_detach(child);
- if (error)
- goto done;
-
- /* remove children second */
- while ((grandchild = TAILQ_FIRST(&child->dev_children))) {
- error = device_delete_child(child, grandchild);
- if (error) {
- device_printf(dev, "Error deleting child!\n");
- goto done;
- }
- }
-
- devclass_delete_device(child->dev_module, child);
-
- if (dev != NULL) {
- /* remove child from parent */
- TAILQ_REMOVE(&dev->dev_children, child, dev_link);
- }
- free(child, M_DEVBUF);
-
-done:
- return (error);
-}
-
-int
-device_delete_children(device_t dev)
-{
- device_t child;
- int error = 0;
-
- while ((child = TAILQ_FIRST(&dev->dev_children))) {
- error = device_delete_child(dev, child);
- if (error) {
- device_printf(dev, "Error deleting child!\n");
- break;
- }
- }
- return (error);
-}
-
-void
-device_quiet(device_t dev)
-{
- dev->dev_quiet = 1;
-}
-
-const char *
-device_get_desc(device_t dev)
-{
- if (dev)
- return &(dev->dev_desc[0]);
- return (unknown_string);
-}
-
-static int
-default_method(void)
-{
- /* do nothing */
- DPRINTF("Default method called\n");
- return (0);
-}
-
-void *
-device_get_method(device_t dev, const char *what)
-{
- const struct device_method *mtod;
-
- mtod = dev->dev_module->driver->methods;
- while (mtod->func != NULL) {
- if (devclass_equal(mtod->desc, what)) {
- return (mtod->func);
- }
- mtod++;
- }
- return ((void *)&default_method);
-}
-
-const char *
-device_get_name(device_t dev)
-{
- if (dev == NULL)
- return (unknown_string);
-
- return (dev->dev_module->driver->name);
-}
-
-static int
-device_allocate_softc(device_t dev)
-{
- const struct module_data *mod;
-
- mod = dev->dev_module;
-
- if ((dev->dev_softc_alloc == 0) &&
- (mod->driver->size != 0)) {
- dev->dev_sc = malloc(mod->driver->size,
- M_DEVBUF, M_WAITOK | M_ZERO);
-
- if (dev->dev_sc == NULL)
- return (ENOMEM);
-
- dev->dev_softc_alloc = 1;
- }
- return (0);
-}
-
-int
-device_probe_and_attach(device_t dev)
-{
- const struct module_data *mod;
- const char *bus_name_parent;
-
- bus_name_parent = device_get_name(device_get_parent(dev));
-
- if (dev->dev_attached)
- return (0); /* fail-safe */
-
- if (dev->dev_fixed_class) {
-
- mod = dev->dev_module;
-
- if (DEVICE_PROBE(dev) <= 0) {
-
- if (device_allocate_softc(dev) == 0) {
-
- if (DEVICE_ATTACH(dev) == 0) {
- /* success */
- dev->dev_attached = 1;
- return (0);
- }
- }
- }
- device_detach(dev);
-
- goto error;
- }
- /*
- * Else find a module for our device, if any
- */
-
- TAILQ_FOREACH(mod, &module_head, entry) {
- if (devclass_equal(mod->bus_name, bus_name_parent)) {
- if (devclass_create(mod->devclass_pp)) {
- continue;
- }
- if (devclass_add_device(mod, dev)) {
- continue;
- }
- if (DEVICE_PROBE(dev) <= 0) {
-
- if (device_allocate_softc(dev) == 0) {
-
- if (DEVICE_ATTACH(dev) == 0) {
- /* success */
- dev->dev_attached = 1;
- return (0);
- }
- }
- }
- /* else try next driver */
-
- device_detach(dev);
- }
- }
-
-error:
- return (ENODEV);
-}
-
-int
-device_detach(device_t dev)
-{
- const struct module_data *mod = dev->dev_module;
- int error;
-
- if (dev->dev_attached) {
-
- error = DEVICE_DETACH(dev);
- if (error) {
- return error;
- }
- dev->dev_attached = 0;
- }
- device_set_softc(dev, NULL);
-
- if (dev->dev_fixed_class == 0)
- devclass_delete_device(mod, dev);
-
- return (0);
-}
-
-void
-device_set_softc(device_t dev, void *softc)
-{
- if (dev->dev_softc_alloc) {
- free(dev->dev_sc, M_DEVBUF);
- dev->dev_sc = NULL;
- }
- dev->dev_sc = softc;
- dev->dev_softc_alloc = 0;
-}
-
-void *
-device_get_softc(device_t dev)
-{
- if (dev == NULL)
- return (NULL);
-
- return (dev->dev_sc);
-}
-
-int
-device_is_attached(device_t dev)
-{
- return (dev->dev_attached);
-}
-
-void
-device_set_desc(device_t dev, const char *desc)
-{
- snprintf(dev->dev_desc, sizeof(dev->dev_desc), "%s", desc);
-}
-
-void
-device_set_desc_copy(device_t dev, const char *desc)
-{
- device_set_desc(dev, desc);
-}
-
-void *
-devclass_get_softc(devclass_t dc, int unit)
-{
- return (device_get_softc(devclass_get_device(dc, unit)));
-}
-
-int
-devclass_get_maxunit(devclass_t dc)
-{
- int max_unit = 0;
-
- if (dc) {
- max_unit = DEVCLASS_MAXUNIT;
- while (max_unit--) {
- if (dc->dev_list[max_unit]) {
- break;
- }
- }
- max_unit++;
- }
- return (max_unit);
-}
-
-device_t
-devclass_get_device(devclass_t dc, int unit)
-{
- return (((unit < 0) || (unit >= DEVCLASS_MAXUNIT) || (dc == NULL)) ?
- NULL : dc->dev_list[unit]);
-}
-
-devclass_t
-devclass_find(const char *classname)
-{
- const struct module_data *mod;
-
- TAILQ_FOREACH(mod, &module_head, entry) {
- if (devclass_equal(mod->driver->name, classname))
- return (mod->devclass_pp[0]);
- }
- return (NULL);
-}
-
-void
-module_register(void *data)
-{
- struct module_data *mdata = data;
-
- TAILQ_INSERT_TAIL(&module_head, mdata, entry);
-}
-
-/*------------------------------------------------------------------------*
- * System startup
- *------------------------------------------------------------------------*/
-
-static void
-sysinit_run(const void **ppdata)
-{
- const struct sysinit *psys;
-
- while ((psys = *ppdata) != NULL) {
- (psys->func) (psys->data);
- ppdata++;
- }
-}
-
-/*------------------------------------------------------------------------*
- * USB process API
- *------------------------------------------------------------------------*/
-
-static int usb_do_process(struct usb_process *);
-static int usb_proc_level = -1;
-static struct mtx usb_proc_mtx;
-
-void
-usb_idle(void)
-{
- int old_level = usb_proc_level;
- int old_giant = Giant.owned;
- int worked;
-
- device_run_interrupts(usb_pci_root);
-
- do {
- worked = 0;
- Giant.owned = 0;
-
- while (++usb_proc_level < USB_PROC_MAX)
- worked |= usb_do_process(usb_process + usb_proc_level);
-
- usb_proc_level = old_level;
- Giant.owned = old_giant;
-
- } while (worked);
-}
-
-void
-usb_init(void)
-{
- sysinit_run(sysinit_data);
-}
-
-void
-usb_uninit(void)
-{
- sysinit_run(sysuninit_data);
-}
-
-static void
-usb_process_init_sub(struct usb_process *up)
-{
- TAILQ_INIT(&up->up_qhead);
-
- cv_init(&up->up_cv, "-");
- cv_init(&up->up_drain, "usbdrain");
-
- up->up_mtx = &usb_proc_mtx;
-}
-
-static void
-usb_process_init(void *arg)
-{
- uint8_t x;
-
- mtx_init(&usb_proc_mtx, "usb-proc-mtx", NULL, MTX_DEF | MTX_RECURSE);
-
- for (x = 0; x != USB_PROC_MAX; x++)
- usb_process_init_sub(&usb_process[x]);
-
-}
-SYSINIT(usb_process_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, usb_process_init, NULL);
-
-static int
-usb_do_process(struct usb_process *up)
-{
- struct usb_proc_msg *pm;
- int worked = 0;
-
- mtx_lock(&usb_proc_mtx);
-
-repeat:
- pm = TAILQ_FIRST(&up->up_qhead);
-
- if (pm != NULL) {
-
- worked = 1;
-
- (pm->pm_callback) (pm);
-
- if (pm == TAILQ_FIRST(&up->up_qhead)) {
- /* nothing changed */
- TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry);
- pm->pm_qentry.tqe_prev = NULL;
- }
- goto repeat;
- }
- mtx_unlock(&usb_proc_mtx);
-
- return (worked);
-}
-
-void *
-usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
-{
- struct usb_proc_msg *pm0 = _pm0;
- struct usb_proc_msg *pm1 = _pm1;
- struct usb_proc_msg *pm2;
- usb_size_t d;
- uint8_t t;
-
- t = 0;
-
- if (pm0->pm_qentry.tqe_prev) {
- t |= 1;
- }
- if (pm1->pm_qentry.tqe_prev) {
- t |= 2;
- }
- if (t == 0) {
- /*
- * No entries are queued. Queue "pm0" and use the existing
- * message number.
- */
- pm2 = pm0;
- } else if (t == 1) {
- /* Check if we need to increment the message number. */
- if (pm0->pm_num == up->up_msg_num) {
- up->up_msg_num++;
- }
- pm2 = pm1;
- } else if (t == 2) {
- /* Check if we need to increment the message number. */
- if (pm1->pm_num == up->up_msg_num) {
- up->up_msg_num++;
- }
- pm2 = pm0;
- } else if (t == 3) {
- /*
- * Both entries are queued. Re-queue the entry closest to
- * the end.
- */
- d = (pm1->pm_num - pm0->pm_num);
-
- /* Check sign after subtraction */
- if (d & 0x80000000) {
- pm2 = pm0;
- } else {
- pm2 = pm1;
- }
-
- TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry);
- } else {
- pm2 = NULL; /* panic - should not happen */
- }
-
- /* Put message last on queue */
-
- pm2->pm_num = up->up_msg_num;
- TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry);
-
- return (pm2);
-}
-
-/*------------------------------------------------------------------------*
- * usb_proc_is_gone
- *
- * Return values:
- * 0: USB process is running
- * Else: USB process is tearing down
- *------------------------------------------------------------------------*/
-uint8_t
-usb_proc_is_gone(struct usb_process *up)
-{
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb_proc_mwait
- *
- * This function will return when the USB process message pointed to
- * by "pm" is no longer on a queue. This function must be called
- * having "usb_proc_mtx" locked.
- *------------------------------------------------------------------------*/
-void
-usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
-{
- struct usb_proc_msg *pm0 = _pm0;
- struct usb_proc_msg *pm1 = _pm1;
-
- /* Just remove the messages from the queue. */
- if (pm0->pm_qentry.tqe_prev) {
- TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry);
- pm0->pm_qentry.tqe_prev = NULL;
- }
- if (pm1->pm_qentry.tqe_prev) {
- TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry);
- pm1->pm_qentry.tqe_prev = NULL;
- }
-}
-
-/*------------------------------------------------------------------------*
- * SYSTEM attach
- *------------------------------------------------------------------------*/
-
-#ifdef USB_PCI_PROBE_LIST
-static device_method_t pci_methods[] = {
- DEVMETHOD_END
-};
-
-static driver_t pci_driver = {
- .name = "pci",
- .methods = pci_methods,
-};
-
-static devclass_t pci_devclass;
-
-DRIVER_MODULE(pci, pci, pci_driver, pci_devclass, 0, 0);
-
-static const char *usb_pci_devices[] = {
- USB_PCI_PROBE_LIST
-};
-
-#define USB_PCI_USB_MAX (sizeof(usb_pci_devices) / sizeof(void *))
-
-static device_t usb_pci_dev[USB_PCI_USB_MAX];
-
-static void
-usb_pci_mod_load(void *arg)
-{
- uint32_t x;
-
- usb_pci_root = device_add_child(NULL, "pci", -1);
- if (usb_pci_root == NULL)
- return;
-
- for (x = 0; x != USB_PCI_USB_MAX; x++) {
- usb_pci_dev[x] = device_add_child(usb_pci_root, usb_pci_devices[x], -1);
- if (usb_pci_dev[x] == NULL)
- continue;
- if (device_probe_and_attach(usb_pci_dev[x])) {
- device_printf(usb_pci_dev[x],
- "WARNING: Probe and attach failed!\n");
- }
- }
-}
-SYSINIT(usb_pci_mod_load, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_load, 0);
-
-static void
-usb_pci_mod_unload(void *arg)
-{
- uint32_t x;
-
- for (x = 0; x != USB_PCI_USB_MAX; x++) {
- if (usb_pci_dev[x]) {
- device_detach(usb_pci_dev[x]);
- device_delete_child(usb_pci_root, usb_pci_dev[x]);
- }
- }
- if (usb_pci_root)
- device_delete_child(NULL, usb_pci_root);
-}
-SYSUNINIT(usb_pci_mod_unload, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_unload, 0);
-#endif
-
-/*------------------------------------------------------------------------*
- * MALLOC API
- *------------------------------------------------------------------------*/
-
-#ifndef HAVE_MALLOC
-#define USB_POOL_ALIGN 8
-
-static uint8_t usb_pool[USB_POOL_SIZE] __aligned(USB_POOL_ALIGN);
-static uint32_t usb_pool_rem = USB_POOL_SIZE;
-static uint32_t usb_pool_entries;
-
-struct malloc_hdr {
- TAILQ_ENTRY(malloc_hdr) entry;
- uint32_t size;
-} __aligned(USB_POOL_ALIGN);
-
-static TAILQ_HEAD(, malloc_hdr) malloc_head =
- TAILQ_HEAD_INITIALIZER(malloc_head);
-
-void *
-usb_malloc(unsigned long size)
-{
- struct malloc_hdr *hdr;
-
- size = (size + USB_POOL_ALIGN - 1) & ~(USB_POOL_ALIGN - 1);
- size += sizeof(struct malloc_hdr);
-
- TAILQ_FOREACH(hdr, &malloc_head, entry) {
- if (hdr->size == size)
- break;
- }
-
- if (hdr) {
- DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n",
- (int)usb_pool_entries, (int)usb_pool_rem, (int)size);
-
- TAILQ_REMOVE(&malloc_head, hdr, entry);
- memset(hdr + 1, 0, hdr->size - sizeof(*hdr));
- return (hdr + 1);
- }
- if (usb_pool_rem >= size) {
- hdr = (void *)(usb_pool + USB_POOL_SIZE - usb_pool_rem);
- hdr->size = size;
-
- usb_pool_rem -= size;
- usb_pool_entries++;
-
- DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n",
- (int)usb_pool_entries, (int)usb_pool_rem, (int)size);
-
- memset(hdr + 1, 0, hdr->size - sizeof(*hdr));
- return (hdr + 1);
- }
- return (NULL);
-}
-
-void
-usb_free(void *arg)
-{
- struct malloc_hdr *hdr;
-
- if (arg == NULL)
- return;
-
- hdr = arg;
- hdr--;
-
- TAILQ_INSERT_TAIL(&malloc_head, hdr, entry);
-}
-#endif
-
-char *
-usb_strdup(const char *str)
-{
- char *tmp;
- int len;
-
- len = 1 + strlen(str);
-
- tmp = malloc(len,XXX,XXX);
- if (tmp == NULL)
- return (NULL);
-
- memcpy(tmp, str, len);
- return (tmp);
-}