3 * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <bsd_global.h>
29 struct usb_process usb_process[USB_PROC_MAX];
31 static device_t usb_pci_root;
33 int (*bus_alloc_resource_any_cb)(struct resource *res, device_t dev,
34 int type, int *rid, unsigned int flags);
35 int (*ofw_bus_status_ok_cb)(device_t dev);
36 int (*ofw_bus_is_compatible_cb)(device_t dev, char *name);
38 /*------------------------------------------------------------------------*
39 * Implementation of busdma API
40 *------------------------------------------------------------------------*/
42 bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
43 bus_size_t boundary, bus_addr_t lowaddr,
44 bus_addr_t highaddr, bus_dma_filter_t *filter,
45 void *filterarg, bus_size_t maxsize, int nsegments,
46 bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
47 void *lockfuncarg, bus_dma_tag_t *dmat)
49 struct bus_dma_tag *ret;
51 ret = malloc(sizeof(struct bus_dma_tag), XXX, XXX);
54 ret->alignment = alignment;
55 ret->maxsize = maxsize;
63 bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
68 addr = malloc(dmat->maxsize + dmat->alignment, XXX, XXX);
73 addr = (void*)(((uintptr_t)addr + dmat->alignment - 1) & ~(dmat->alignment - 1));
80 bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
81 bus_size_t buflen, bus_dmamap_callback_t *callback,
82 void *callback_arg, int flags)
84 bus_dma_segment_t segs[1];
86 segs[0].ds_addr = (uintptr_t)buf;
87 segs[0].ds_len = buflen;
89 (*callback)(callback_arg, segs, 1, 0);
95 bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, int flags)
97 /* Assuming coherent memory */
98 __asm__ __volatile__("": : :"memory");
102 bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
109 bus_dma_tag_destroy(bus_dma_tag_t dmat)
116 /*------------------------------------------------------------------------*
117 * Implementation of resource management API
118 *------------------------------------------------------------------------*/
121 bus_alloc_resource_any(device_t dev, int type, int *rid, unsigned int flags)
123 struct resource *res;
126 res = malloc(sizeof(*res), XXX, XXX);
130 res->__r_i = malloc(sizeof(struct resource_i), XXX, XXX);
131 if (res->__r_i == NULL) {
136 if (bus_alloc_resource_any_cb != NULL)
137 ret = (*bus_alloc_resource_any_cb)(res, dev, type, rid, flags);
141 free(res->__r_i, XXX);
147 bus_alloc_resources(device_t dev, struct resource_spec *rs,
148 struct resource **res)
152 for (i = 0; rs[i].type != -1; i++)
154 for (i = 0; rs[i].type != -1; i++) {
155 res[i] = bus_alloc_resource_any(dev,
156 rs[i].type, &rs[i].rid, rs[i].flags);
157 if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) {
158 bus_release_resources(dev, rs, res);
166 bus_release_resources(device_t dev, const struct resource_spec *rs,
167 struct resource **res)
171 for (i = 0; rs[i].type != -1; i++)
172 if (res[i] != NULL) {
173 bus_release_resource(
174 dev, rs[i].type, rs[i].rid, res[i]);
180 bus_setup_intr(device_t dev, struct resource *r, int flags,
181 driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep)
184 dev->dev_irq_filter = filter;
185 dev->dev_irq_fn = handler;
186 dev->dev_irq_arg = arg;
192 bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
195 dev->dev_irq_filter = NULL;
196 dev->dev_irq_fn = NULL;
197 dev->dev_irq_arg = NULL;
203 bus_release_resource(device_t dev, int type, int rid, struct resource *r)
205 /* Resource releasing is not supported */
210 bus_generic_attach(device_t dev)
214 TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
215 device_probe_and_attach(child);
222 rman_get_bustag(struct resource *r)
225 return (r->r_bustag);
229 rman_get_bushandle(struct resource *r)
232 return (r->r_bushandle);
236 rman_get_size(struct resource *r)
239 return (r->__r_i->r_end - r->__r_i->r_start + 1);
243 ofw_bus_status_okay(device_t dev)
245 if (ofw_bus_status_ok_cb == NULL)
248 return ((*ofw_bus_status_ok_cb)(dev));
252 ofw_bus_is_compatible(device_t dev, char *name)
254 if (ofw_bus_is_compatible_cb == NULL)
257 return ((*ofw_bus_is_compatible_cb)(dev, name));
260 /*------------------------------------------------------------------------*
261 * Implementation of mutex API
262 *------------------------------------------------------------------------*/
267 mtx_system_init(void *arg)
269 mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
271 SYSINIT(mtx_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, mtx_system_init, NULL);
274 mtx_init(struct mtx *mtx, const char *name, const char *type, int opt)
281 mtx_lock(struct mtx *mtx)
288 mtx_unlock(struct mtx *mtx)
295 mtx_owned(struct mtx *mtx)
298 return (mtx->owned != 0);
302 mtx_destroy(struct mtx *mtx)
307 /*------------------------------------------------------------------------*
308 * Implementation of shared/exclusive mutex API
309 *------------------------------------------------------------------------*/
312 sx_init_flags(struct sx *sx, const char *name, int flags)
318 sx_destroy(struct sx *sx)
324 sx_xlock(struct sx *sx)
330 sx_xunlock(struct sx *sx)
336 sx_xlocked(struct sx *sx)
338 return (sx->owned != 0);
341 /*------------------------------------------------------------------------*
342 * Implementaiton of condition variable API
343 *------------------------------------------------------------------------*/
346 cv_init(struct cv *cv, const char *desc)
352 cv_destroy(struct cv *cv)
358 cv_wait(struct cv *cv, struct mtx *mtx)
360 cv_timedwait(cv, mtx, -1);
364 cv_timedwait(struct cv *cv, struct mtx *mtx, int timo)
371 return (EWOULDBLOCK); /* not allowed */
375 while (cv->sleeping) {
377 delta = ticks - start;
378 if (delta >= timo || delta < 0)
385 if (++time >= (1000000 / hz)) {
398 return (EWOULDBLOCK); /* not allowed */
404 cv_signal(struct cv *cv)
410 cv_broadcast(struct cv *cv)
415 /*------------------------------------------------------------------------*
416 * Implementation of callout API
417 *------------------------------------------------------------------------*/
419 static void callout_proc_msg(struct usb_proc_msg *);
421 volatile int ticks = 0;
423 static LIST_HEAD(, callout) head_callout = LIST_HEAD_INITIALIZER(&head_callout);
425 static struct mtx mtx_callout;
426 static struct usb_proc_msg callout_msg[2];
429 callout_system_init(void *arg)
431 mtx_init(&mtx_callout, "callout-mtx", NULL, MTX_DEF | MTX_RECURSE);
433 callout_msg[0].pm_callback = &callout_proc_msg;
434 callout_msg[1].pm_callback = &callout_proc_msg;
436 SYSINIT(callout_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, callout_system_init, NULL);
439 callout_callback(struct callout *c)
443 mtx_lock(&mtx_callout);
444 if (c->entry.le_prev != NULL) {
445 LIST_REMOVE(c, entry);
446 c->entry.le_prev = NULL;
448 mtx_unlock(&mtx_callout);
450 if (c->c_func != NULL)
451 (c->c_func) (c->c_arg);
453 if (!(c->flags & CALLOUT_RETURNUNLOCKED))
458 callout_process(int timeout)
461 usb_proc_msignal(usb_process + 2, &callout_msg[0], &callout_msg[1]);
465 callout_proc_msg(struct usb_proc_msg *pmsg)
471 mtx_lock(&mtx_callout);
473 LIST_FOREACH(c, &head_callout, entry) {
475 delta = c->timeout - ticks;
477 mtx_unlock(&mtx_callout);
484 mtx_unlock(&mtx_callout);
488 callout_init_mtx(struct callout *c, struct mtx *mtx, int flags)
490 memset(c, 0, sizeof(*c));
496 c->flags = (flags & CALLOUT_RETURNUNLOCKED);
500 callout_reset(struct callout *c, int to_ticks,
501 void (*func) (void *), void *arg)
507 c->timeout = ticks + to_ticks;
509 mtx_lock(&mtx_callout);
510 LIST_INSERT_HEAD(&head_callout, c, entry);
511 mtx_unlock(&mtx_callout);
515 callout_stop(struct callout *c)
517 mtx_lock(&mtx_callout);
519 if (c->entry.le_prev != NULL) {
520 LIST_REMOVE(c, entry);
521 c->entry.le_prev = NULL;
523 mtx_unlock(&mtx_callout);
530 callout_drain(struct callout *c)
533 return; /* not initialised */
541 callout_pending(struct callout *c)
545 mtx_lock(&mtx_callout);
546 retval = (c->entry.le_prev != NULL);
547 mtx_unlock(&mtx_callout);
552 /*------------------------------------------------------------------------*
553 * Implementation of device API
554 *------------------------------------------------------------------------*/
556 static const char unknown_string[] = { "unknown" };
558 static TAILQ_HEAD(, module_data) module_head =
559 TAILQ_HEAD_INITIALIZER(module_head);
562 devclass_equal(const char *a, const char *b)
583 bus_generic_resume(device_t dev)
589 bus_generic_shutdown(device_t dev)
595 bus_generic_suspend(device_t dev)
601 bus_generic_print_child(device_t dev, device_t child)
607 bus_generic_driver_added(device_t dev, driver_t *driver)
613 device_get_parent(device_t dev)
615 return (dev ? dev->dev_parent : NULL);
619 device_set_interrupt(device_t dev, driver_filter_t *filter,
620 driver_intr_t *fn, void *arg)
622 dev->dev_irq_filter = filter;
623 dev->dev_irq_fn = fn;
624 dev->dev_irq_arg = arg;
628 device_run_interrupts(device_t parent)
635 TAILQ_FOREACH(child, &parent->dev_children, dev_link) {
637 if (child->dev_irq_filter != NULL)
638 status = child->dev_irq_filter(child->dev_irq_arg);
640 status = FILTER_SCHEDULE_THREAD;
642 if (status == FILTER_SCHEDULE_THREAD) {
643 if (child->dev_irq_fn != NULL)
644 (child->dev_irq_fn) (child->dev_irq_arg);
650 device_set_ivars(device_t dev, void *ivars)
652 dev->dev_aux = ivars;
656 device_get_ivars(device_t dev)
658 return (dev ? dev->dev_aux : NULL);
662 device_get_unit(device_t dev)
664 return (dev ? dev->dev_unit : 0);
668 bus_generic_detach(device_t dev)
673 if (!dev->dev_attached)
676 TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
677 if ((error = device_detach(child)) != 0)
684 device_get_nameunit(device_t dev)
686 if (dev && dev->dev_nameunit[0])
687 return (dev->dev_nameunit);
689 return (unknown_string);
693 devclass_create(devclass_t *dc_pp)
698 if (dc_pp[0] == NULL) {
699 dc_pp[0] = malloc(sizeof(**(dc_pp)),
700 M_DEVBUF, M_WAITOK | M_ZERO);
702 if (dc_pp[0] == NULL) {
709 static const struct module_data *
710 devclass_find_create(const char *classname)
712 const struct module_data *mod;
714 TAILQ_FOREACH(mod, &module_head, entry) {
715 if (devclass_equal(mod->mod_name, classname)) {
716 if (devclass_create(mod->devclass_pp)) {
726 devclass_add_device(const struct module_data *mod, device_t dev)
732 pp_dev = mod->devclass_pp[0]->dev_list;
733 end = pp_dev + DEVCLASS_MAXUNIT;
736 while (pp_dev != end) {
737 if (*pp_dev == NULL) {
739 dev->dev_unit = unit;
740 dev->dev_module = mod;
741 snprintf(dev->dev_nameunit,
742 sizeof(dev->dev_nameunit),
743 "%s%d", device_get_name(dev), unit);
749 DPRINTF("Could not add device to devclass.\n");
754 devclass_delete_device(const struct module_data *mod, device_t dev)
759 mod->devclass_pp[0]->dev_list[dev->dev_unit] = NULL;
760 dev->dev_module = NULL;
764 make_device(device_t parent, const char *name)
767 const struct module_data *mod = NULL;
771 mod = devclass_find_create(name);
775 DPRINTF("%s:%d:%s: can't find device "
776 "class %s\n", __FILE__, __LINE__,
782 dev = malloc(sizeof(*dev),
783 M_DEVBUF, M_WAITOK | M_ZERO);
788 dev->dev_parent = parent;
789 TAILQ_INIT(&dev->dev_children);
792 dev->dev_fixed_class = 1;
793 if (devclass_add_device(mod, dev)) {
808 device_add_child(device_t dev, const char *name, int unit)
813 device_printf(dev, "Unit is not -1\n");
815 child = make_device(dev, name);
817 device_printf(dev, "Could not add child '%s'\n", name);
824 TAILQ_INSERT_TAIL(&dev->dev_children, child, dev_link);
830 device_delete_child(device_t dev, device_t child)
835 /* detach parent before deleting children, if any */
836 error = device_detach(child);
840 /* remove children second */
841 while ((grandchild = TAILQ_FIRST(&child->dev_children))) {
842 error = device_delete_child(child, grandchild);
844 device_printf(dev, "Error deleting child!\n");
849 devclass_delete_device(child->dev_module, child);
852 /* remove child from parent */
853 TAILQ_REMOVE(&dev->dev_children, child, dev_link);
855 free(child, M_DEVBUF);
862 device_delete_children(device_t dev)
867 while ((child = TAILQ_FIRST(&dev->dev_children))) {
868 error = device_delete_child(dev, child);
870 device_printf(dev, "Error deleting child!\n");
878 device_quiet(device_t dev)
884 device_get_desc(device_t dev)
887 return &(dev->dev_desc[0]);
888 return (unknown_string);
895 DPRINTF("Default method called\n");
900 device_get_method(device_t dev, const char *what)
902 const struct device_method *mtod;
904 mtod = dev->dev_module->driver->methods;
905 while (mtod->func != NULL) {
906 if (devclass_equal(mtod->desc, what)) {
911 return ((void *)&default_method);
915 device_get_name(device_t dev)
918 return (unknown_string);
920 return (dev->dev_module->driver->name);
924 device_allocate_softc(device_t dev)
926 const struct module_data *mod;
928 mod = dev->dev_module;
930 if ((dev->dev_softc_alloc == 0) &&
931 (mod->driver->size != 0)) {
932 dev->dev_sc = malloc(mod->driver->size,
933 M_DEVBUF, M_WAITOK | M_ZERO);
935 if (dev->dev_sc == NULL)
938 dev->dev_softc_alloc = 1;
944 device_probe_and_attach(device_t dev)
946 const struct module_data *mod;
947 const char *bus_name_parent;
949 bus_name_parent = device_get_name(device_get_parent(dev));
951 if (dev->dev_attached)
952 return (0); /* fail-safe */
954 if (dev->dev_fixed_class) {
956 mod = dev->dev_module;
958 if (DEVICE_PROBE(dev) <= 0) {
960 if (device_allocate_softc(dev) == 0) {
962 if (DEVICE_ATTACH(dev) == 0) {
964 dev->dev_attached = 1;
974 * Else find a module for our device, if any
977 TAILQ_FOREACH(mod, &module_head, entry) {
978 if (devclass_equal(mod->bus_name, bus_name_parent)) {
979 if (devclass_create(mod->devclass_pp)) {
982 if (devclass_add_device(mod, dev)) {
985 if (DEVICE_PROBE(dev) <= 0) {
987 if (device_allocate_softc(dev) == 0) {
989 if (DEVICE_ATTACH(dev) == 0) {
991 dev->dev_attached = 1;
996 /* else try next driver */
1007 device_detach(device_t dev)
1009 const struct module_data *mod = dev->dev_module;
1012 if (dev->dev_attached) {
1014 error = DEVICE_DETACH(dev);
1018 dev->dev_attached = 0;
1020 device_set_softc(dev, NULL);
1022 if (dev->dev_fixed_class == 0)
1023 devclass_delete_device(mod, dev);
1029 device_set_softc(device_t dev, void *softc)
1031 if (dev->dev_softc_alloc) {
1032 free(dev->dev_sc, M_DEVBUF);
1035 dev->dev_sc = softc;
1036 dev->dev_softc_alloc = 0;
1040 device_get_softc(device_t dev)
1045 return (dev->dev_sc);
1049 device_is_attached(device_t dev)
1051 return (dev->dev_attached);
1055 device_set_desc(device_t dev, const char *desc)
1057 snprintf(dev->dev_desc, sizeof(dev->dev_desc), "%s", desc);
1061 device_set_desc_copy(device_t dev, const char *desc)
1063 device_set_desc(dev, desc);
1067 devclass_get_softc(devclass_t dc, int unit)
1069 return (device_get_softc(devclass_get_device(dc, unit)));
1073 devclass_get_maxunit(devclass_t dc)
1078 max_unit = DEVCLASS_MAXUNIT;
1079 while (max_unit--) {
1080 if (dc->dev_list[max_unit]) {
1090 devclass_get_device(devclass_t dc, int unit)
1092 return (((unit < 0) || (unit >= DEVCLASS_MAXUNIT) || (dc == NULL)) ?
1093 NULL : dc->dev_list[unit]);
1097 devclass_find(const char *classname)
1099 const struct module_data *mod;
1101 TAILQ_FOREACH(mod, &module_head, entry) {
1102 if (devclass_equal(mod->driver->name, classname))
1103 return (mod->devclass_pp[0]);
1109 module_register(void *data)
1111 struct module_data *mdata = data;
1113 TAILQ_INSERT_TAIL(&module_head, mdata, entry);
1116 /*------------------------------------------------------------------------*
1118 *------------------------------------------------------------------------*/
1121 sysinit_run(const void **ppdata)
1123 const struct sysinit *psys;
1125 while ((psys = *ppdata) != NULL) {
1126 (psys->func) (psys->data);
1131 /*------------------------------------------------------------------------*
1133 *------------------------------------------------------------------------*/
1135 static int usb_do_process(struct usb_process *);
1136 static int usb_proc_level = -1;
1137 static struct mtx usb_proc_mtx;
1142 int old_level = usb_proc_level;
1143 int old_giant = Giant.owned;
1146 device_run_interrupts(usb_pci_root);
1152 while (++usb_proc_level < USB_PROC_MAX)
1153 worked |= usb_do_process(usb_process + usb_proc_level);
1155 usb_proc_level = old_level;
1156 Giant.owned = old_giant;
1164 sysinit_run(sysinit_data);
1170 sysinit_run(sysuninit_data);
1174 usb_process_init_sub(struct usb_process *up)
1176 TAILQ_INIT(&up->up_qhead);
1178 cv_init(&up->up_cv, "-");
1179 cv_init(&up->up_drain, "usbdrain");
1181 up->up_mtx = &usb_proc_mtx;
1185 usb_process_init(void *arg)
1189 mtx_init(&usb_proc_mtx, "usb-proc-mtx", NULL, MTX_DEF | MTX_RECURSE);
1191 for (x = 0; x != USB_PROC_MAX; x++)
1192 usb_process_init_sub(&usb_process[x]);
1195 SYSINIT(usb_process_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, usb_process_init, NULL);
1198 usb_do_process(struct usb_process *up)
1200 struct usb_proc_msg *pm;
1203 mtx_lock(&usb_proc_mtx);
1206 pm = TAILQ_FIRST(&up->up_qhead);
1212 (pm->pm_callback) (pm);
1214 if (pm == TAILQ_FIRST(&up->up_qhead)) {
1215 /* nothing changed */
1216 TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry);
1217 pm->pm_qentry.tqe_prev = NULL;
1221 mtx_unlock(&usb_proc_mtx);
1227 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
1229 struct usb_proc_msg *pm0 = _pm0;
1230 struct usb_proc_msg *pm1 = _pm1;
1231 struct usb_proc_msg *pm2;
1237 if (pm0->pm_qentry.tqe_prev) {
1240 if (pm1->pm_qentry.tqe_prev) {
1245 * No entries are queued. Queue "pm0" and use the existing
1249 } else if (t == 1) {
1250 /* Check if we need to increment the message number. */
1251 if (pm0->pm_num == up->up_msg_num) {
1255 } else if (t == 2) {
1256 /* Check if we need to increment the message number. */
1257 if (pm1->pm_num == up->up_msg_num) {
1261 } else if (t == 3) {
1263 * Both entries are queued. Re-queue the entry closest to
1266 d = (pm1->pm_num - pm0->pm_num);
1268 /* Check sign after subtraction */
1269 if (d & 0x80000000) {
1275 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry);
1277 pm2 = NULL; /* panic - should not happen */
1280 /* Put message last on queue */
1282 pm2->pm_num = up->up_msg_num;
1283 TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry);
1288 /*------------------------------------------------------------------------*
1292 * 0: USB process is running
1293 * Else: USB process is tearing down
1294 *------------------------------------------------------------------------*/
1296 usb_proc_is_gone(struct usb_process *up)
1301 /*------------------------------------------------------------------------*
1304 * This function will return when the USB process message pointed to
1305 * by "pm" is no longer on a queue. This function must be called
1306 * having "usb_proc_mtx" locked.
1307 *------------------------------------------------------------------------*/
1309 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
1311 struct usb_proc_msg *pm0 = _pm0;
1312 struct usb_proc_msg *pm1 = _pm1;
1314 /* Just remove the messages from the queue. */
1315 if (pm0->pm_qentry.tqe_prev) {
1316 TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry);
1317 pm0->pm_qentry.tqe_prev = NULL;
1319 if (pm1->pm_qentry.tqe_prev) {
1320 TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry);
1321 pm1->pm_qentry.tqe_prev = NULL;
1325 /*------------------------------------------------------------------------*
1327 *------------------------------------------------------------------------*/
1329 #ifdef USB_PCI_PROBE_LIST
1330 static device_method_t pci_methods[] = {
1334 static driver_t pci_driver = {
1336 .methods = pci_methods,
1339 static devclass_t pci_devclass;
1341 DRIVER_MODULE(pci, pci, pci_driver, pci_devclass, 0, 0);
1343 static const char *usb_pci_devices[] = {
1347 #define USB_PCI_USB_MAX (sizeof(usb_pci_devices) / sizeof(void *))
1349 static device_t usb_pci_dev[USB_PCI_USB_MAX];
1352 usb_pci_mod_load(void *arg)
1356 usb_pci_root = device_add_child(NULL, "pci", -1);
1357 if (usb_pci_root == NULL)
1360 for (x = 0; x != USB_PCI_USB_MAX; x++) {
1361 usb_pci_dev[x] = device_add_child(usb_pci_root, usb_pci_devices[x], -1);
1362 if (usb_pci_dev[x] == NULL)
1364 if (device_probe_and_attach(usb_pci_dev[x])) {
1365 device_printf(usb_pci_dev[x],
1366 "WARNING: Probe and attach failed!\n");
1370 SYSINIT(usb_pci_mod_load, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_load, 0);
1373 usb_pci_mod_unload(void *arg)
1377 for (x = 0; x != USB_PCI_USB_MAX; x++) {
1378 if (usb_pci_dev[x]) {
1379 device_detach(usb_pci_dev[x]);
1380 device_delete_child(usb_pci_root, usb_pci_dev[x]);
1384 device_delete_child(NULL, usb_pci_root);
1386 SYSUNINIT(usb_pci_mod_unload, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_unload, 0);
1389 /*------------------------------------------------------------------------*
1391 *------------------------------------------------------------------------*/
1394 #define USB_POOL_ALIGN 8
1396 static uint8_t usb_pool[USB_POOL_SIZE] __aligned(USB_POOL_ALIGN);
1397 static uint32_t usb_pool_rem = USB_POOL_SIZE;
1398 static uint32_t usb_pool_entries;
1401 TAILQ_ENTRY(malloc_hdr) entry;
1403 } __aligned(USB_POOL_ALIGN);
1405 static TAILQ_HEAD(, malloc_hdr) malloc_head =
1406 TAILQ_HEAD_INITIALIZER(malloc_head);
1409 usb_malloc(unsigned long size)
1411 struct malloc_hdr *hdr;
1413 size = (size + USB_POOL_ALIGN - 1) & ~(USB_POOL_ALIGN - 1);
1414 size += sizeof(struct malloc_hdr);
1416 TAILQ_FOREACH(hdr, &malloc_head, entry) {
1417 if (hdr->size == size)
1422 DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n",
1423 (int)usb_pool_entries, (int)usb_pool_rem, (int)size);
1425 TAILQ_REMOVE(&malloc_head, hdr, entry);
1426 memset(hdr + 1, 0, hdr->size - sizeof(*hdr));
1429 if (usb_pool_rem >= size) {
1430 hdr = (void *)(usb_pool + USB_POOL_SIZE - usb_pool_rem);
1433 usb_pool_rem -= size;
1436 DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n",
1437 (int)usb_pool_entries, (int)usb_pool_rem, (int)size);
1439 memset(hdr + 1, 0, hdr->size - sizeof(*hdr));
1448 struct malloc_hdr *hdr;
1456 TAILQ_INSERT_TAIL(&malloc_head, hdr, entry);
1461 usb_strdup(const char *str)
1466 len = 1 + strlen(str);
1468 tmp = malloc(len,XXX,XXX);
1472 memcpy(tmp, str, len);