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 /*------------------------------------------------------------------------*
34 * Implementation of mutex API
35 *------------------------------------------------------------------------*/
40 mtx_system_init(void *arg)
42 mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
44 SYSINIT(mtx_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, mtx_system_init, NULL);
47 mtx_init(struct mtx *mtx, const char *name, const char *type, int opt)
54 mtx_lock(struct mtx *mtx)
61 mtx_unlock(struct mtx *mtx)
68 mtx_owned(struct mtx *mtx)
71 return (mtx->owned != 0);
75 mtx_destroy(struct mtx *mtx)
80 /*------------------------------------------------------------------------*
81 * Implementation of shared/exclusive mutex API
82 *------------------------------------------------------------------------*/
85 sx_init_flags(struct sx *sx, const char *name, int flags)
91 sx_destroy(struct sx *sx)
97 sx_xlock(struct sx *sx)
103 sx_xunlock(struct sx *sx)
109 sx_xlocked(struct sx *sx)
111 return (sx->owned != 0);
114 /*------------------------------------------------------------------------*
115 * Implementaiton of condition variable API
116 *------------------------------------------------------------------------*/
119 cv_init(struct cv *cv, const char *desc)
125 cv_destroy(struct cv *cv)
131 cv_wait(struct cv *cv, struct mtx *mtx)
133 cv_timedwait(cv, mtx, -1);
137 cv_timedwait(struct cv *cv, struct mtx *mtx, int timo)
143 return (EWOULDBLOCK); /* not allowed */
147 while (cv->sleeping) {
149 delta = ticks - start;
150 if (delta >= timo || delta < 0)
162 return (EWOULDBLOCK); /* not allowed */
168 cv_signal(struct cv *cv)
174 cv_broadcast(struct cv *cv)
179 /*------------------------------------------------------------------------*
180 * Implementation of callout API
181 *------------------------------------------------------------------------*/
183 static void callout_proc_msg(struct usb_proc_msg *);
185 volatile int ticks = 0;
187 static LIST_HEAD(, callout) head_callout = LIST_HEAD_INITIALIZER(&head_callout);
189 static struct mtx mtx_callout;
190 static struct usb_proc_msg callout_msg[2];
193 callout_system_init(void *arg)
195 mtx_init(&mtx_callout, "callout-mtx", NULL, MTX_DEF | MTX_RECURSE);
197 callout_msg[0].pm_callback = &callout_proc_msg;
198 callout_msg[1].pm_callback = &callout_proc_msg;
200 SYSINIT(callout_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, callout_system_init, NULL);
203 callout_callback(struct callout *c)
207 mtx_lock(&mtx_callout);
208 if (c->entry.le_prev != NULL) {
209 LIST_REMOVE(c, entry);
210 c->entry.le_prev = NULL;
212 mtx_unlock(&mtx_callout);
217 if (!(c->flags & CALLOUT_RETURNUNLOCKED))
222 callout_process(int timeout)
225 usb_proc_msignal(usb_process + 2, &callout_msg[0], &callout_msg[1]);
229 callout_proc_msg(struct usb_proc_msg *pmsg)
235 mtx_lock(&mtx_callout);
237 LIST_FOREACH(c, &head_callout, entry) {
239 delta = c->timeout - ticks;
241 mtx_unlock(&mtx_callout);
248 mtx_unlock(&mtx_callout);
252 callout_init_mtx(struct callout *c, struct mtx *mtx, int flags)
254 memset(c, 0, sizeof(*c));
260 c->flags = (flags & CALLOUT_RETURNUNLOCKED);
264 callout_reset(struct callout *c, int to_ticks,
265 void (*func) (void *), void *arg)
271 c->timeout = ticks + to_ticks;
273 mtx_lock(&mtx_callout);
274 LIST_INSERT_HEAD(&head_callout, c, entry);
275 mtx_unlock(&mtx_callout);
279 callout_stop(struct callout *c)
281 mtx_lock(&mtx_callout);
283 if (c->entry.le_prev != NULL) {
284 LIST_REMOVE(c, entry);
285 c->entry.le_prev = NULL;
287 mtx_unlock(&mtx_callout);
294 callout_drain(struct callout *c)
297 return; /* not initialised */
305 callout_pending(struct callout *c)
309 mtx_lock(&mtx_callout);
310 retval = (c->entry.le_prev != NULL);
311 mtx_unlock(&mtx_callout);
316 /*------------------------------------------------------------------------*
317 * Implementation of device API
318 *------------------------------------------------------------------------*/
320 static const char unknown_string[] = { "unknown" };
322 static TAILQ_HEAD(, module_data) module_head =
323 TAILQ_HEAD_INITIALIZER(module_head);
326 devclass_equal(const char *a, const char *b)
347 bus_generic_resume(device_t dev)
353 bus_generic_shutdown(device_t dev)
359 bus_generic_suspend(device_t dev)
365 bus_generic_print_child(device_t dev, device_t child)
371 bus_generic_driver_added(device_t dev, driver_t *driver)
377 device_get_parent(device_t dev)
379 return (dev ? dev->dev_parent : NULL);
383 device_set_interrupt(device_t dev, driver_filter_t *filter,
384 driver_intr_t *fn, void *arg)
386 dev->dev_irq_filter = filter;
387 dev->dev_irq_fn = fn;
388 dev->dev_irq_arg = arg;
392 device_run_interrupts(device_t parent)
399 TAILQ_FOREACH(child, &parent->dev_children, dev_link) {
401 if (child->dev_irq_filter != NULL)
402 status = child->dev_irq_filter(child->dev_irq_arg);
404 status = FILTER_SCHEDULE_THREAD;
406 if (status == FILTER_SCHEDULE_THREAD) {
407 if (child->dev_irq_fn != NULL)
408 (child->dev_irq_fn) (child->dev_irq_arg);
414 device_set_ivars(device_t dev, void *ivars)
416 dev->dev_aux = ivars;
420 device_get_ivars(device_t dev)
422 return (dev ? dev->dev_aux : NULL);
426 device_get_unit(device_t dev)
428 return (dev ? dev->dev_unit : 0);
432 bus_generic_detach(device_t dev)
437 if (!dev->dev_attached)
440 TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
441 if ((error = device_detach(child)) != 0)
448 device_get_nameunit(device_t dev)
450 if (dev && dev->dev_nameunit[0])
451 return (dev->dev_nameunit);
453 return (unknown_string);
457 devclass_create(devclass_t *dc_pp)
462 if (dc_pp[0] == NULL) {
463 dc_pp[0] = malloc(sizeof(**(dc_pp)),
464 M_DEVBUF, M_WAITOK | M_ZERO);
466 if (dc_pp[0] == NULL) {
473 static const struct module_data *
474 devclass_find_create(const char *classname)
476 const struct module_data *mod;
478 TAILQ_FOREACH(mod, &module_head, entry) {
479 if (devclass_equal(mod->mod_name, classname)) {
480 if (devclass_create(mod->devclass_pp)) {
490 devclass_add_device(const struct module_data *mod, device_t dev)
496 pp_dev = mod->devclass_pp[0]->dev_list;
497 end = pp_dev + DEVCLASS_MAXUNIT;
500 while (pp_dev != end) {
501 if (*pp_dev == NULL) {
503 dev->dev_unit = unit;
504 dev->dev_module = mod;
505 snprintf(dev->dev_nameunit,
506 sizeof(dev->dev_nameunit),
507 "%s%d", device_get_name(dev), unit);
513 DPRINTF("Could not add device to devclass.\n");
518 devclass_delete_device(const struct module_data *mod, device_t dev)
523 mod->devclass_pp[0]->dev_list[dev->dev_unit] = NULL;
524 dev->dev_module = NULL;
528 make_device(device_t parent, const char *name)
531 const struct module_data *mod = NULL;
535 mod = devclass_find_create(name);
539 DPRINTF("%s:%d:%s: can't find device "
540 "class %s\n", __FILE__, __LINE__,
546 dev = malloc(sizeof(*dev),
547 M_DEVBUF, M_WAITOK | M_ZERO);
552 dev->dev_parent = parent;
553 TAILQ_INIT(&dev->dev_children);
556 dev->dev_fixed_class = 1;
557 if (devclass_add_device(mod, dev)) {
572 device_add_child(device_t dev, const char *name, int unit)
577 device_printf(dev, "Unit is not -1\n");
579 child = make_device(dev, name);
581 device_printf(dev, "Could not add child '%s'\n", name);
588 TAILQ_INSERT_TAIL(&dev->dev_children, child, dev_link);
594 device_delete_child(device_t dev, device_t child)
599 /* remove children first */
601 while ((grandchild = TAILQ_FIRST(&child->dev_children))) {
602 error = device_delete_child(child, grandchild);
604 device_printf(dev, "Error deleting child!\n");
609 error = device_detach(child);
614 devclass_delete_device(child->dev_module, child);
617 /* remove child from parent */
618 TAILQ_REMOVE(&dev->dev_children, child, dev_link);
620 free(child, M_DEVBUF);
627 device_delete_children(device_t dev)
632 while ((child = TAILQ_FIRST(&dev->dev_children))) {
633 error = device_delete_child(dev, child);
635 device_printf(dev, "Error deleting child!\n");
643 device_quiet(device_t dev)
649 device_get_desc(device_t dev)
652 return &(dev->dev_desc[0]);
653 return (unknown_string);
660 DPRINTF("Default method called\n");
665 device_get_method(device_t dev, const char *what)
667 const struct device_method *mtod;
669 mtod = dev->dev_module->driver->methods;
670 while (mtod->func != NULL) {
671 if (devclass_equal(mtod->desc, what)) {
676 return ((void *)&default_method);
680 device_get_name(device_t dev)
683 return (unknown_string);
685 return (dev->dev_module->driver->name);
689 device_allocate_softc(device_t dev)
691 const struct module_data *mod;
693 mod = dev->dev_module;
695 if ((dev->dev_softc_alloc == 0) &&
696 (mod->driver->size != 0)) {
697 dev->dev_sc = malloc(mod->driver->size,
698 M_DEVBUF, M_WAITOK | M_ZERO);
700 if (dev->dev_sc == NULL)
703 dev->dev_softc_alloc = 1;
709 device_probe_and_attach(device_t dev)
711 const struct module_data *mod;
712 const char *bus_name_parent;
714 bus_name_parent = device_get_name(device_get_parent(dev));
716 if (dev->dev_attached)
717 return (0); /* fail-safe */
719 if (dev->dev_fixed_class) {
721 mod = dev->dev_module;
723 if (DEVICE_PROBE(dev) <= 0) {
725 if (device_allocate_softc(dev) == 0) {
727 if (DEVICE_ATTACH(dev) == 0) {
729 dev->dev_attached = 1;
739 * Else find a module for our device, if any
742 TAILQ_FOREACH(mod, &module_head, entry) {
743 if (devclass_equal(mod->bus_name, bus_name_parent)) {
744 if (devclass_create(mod->devclass_pp)) {
747 if (devclass_add_device(mod, dev)) {
750 if (DEVICE_PROBE(dev) <= 0) {
752 if (device_allocate_softc(dev) == 0) {
754 if (DEVICE_ATTACH(dev) == 0) {
756 dev->dev_attached = 1;
761 /* else try next driver */
772 device_detach(device_t dev)
774 const struct module_data *mod = dev->dev_module;
777 if (dev->dev_attached) {
779 error = DEVICE_DETACH(dev);
783 dev->dev_attached = 0;
785 device_set_softc(dev, NULL);
787 if (dev->dev_fixed_class == 0)
788 devclass_delete_device(mod, dev);
794 device_set_softc(device_t dev, void *softc)
796 if (dev->dev_softc_alloc) {
797 free(dev->dev_sc, M_DEVBUF);
801 dev->dev_softc_alloc = 0;
805 device_get_softc(device_t dev)
810 return (dev->dev_sc);
814 device_is_attached(device_t dev)
816 return (dev->dev_attached);
820 device_set_desc(device_t dev, const char *desc)
822 snprintf(dev->dev_desc, sizeof(dev->dev_desc), "%s", desc);
826 device_set_desc_copy(device_t dev, const char *desc)
828 device_set_desc(dev, desc);
832 devclass_get_softc(devclass_t dc, int unit)
834 return (device_get_softc(devclass_get_device(dc, unit)));
838 devclass_get_maxunit(devclass_t dc)
843 max_unit = DEVCLASS_MAXUNIT;
845 if (dc->dev_list[max_unit]) {
855 devclass_get_device(devclass_t dc, int unit)
857 return (((unit < 0) || (unit >= DEVCLASS_MAXUNIT) || (dc == NULL)) ?
858 NULL : dc->dev_list[unit]);
862 devclass_find(const char *classname)
864 const struct module_data *mod;
866 TAILQ_FOREACH(mod, &module_head, entry) {
867 if (devclass_equal(mod->mod_name, classname))
868 return (mod->devclass_pp[0]);
874 module_register(void *data)
876 struct module_data *mdata = data;
878 TAILQ_INSERT_TAIL(&module_head, mdata, entry);
881 /*------------------------------------------------------------------------*
883 *------------------------------------------------------------------------*/
886 sysinit_run(const void **ppdata)
888 const struct sysinit *psys;
890 while ((psys = *ppdata) != NULL) {
891 (psys->func) (psys->data);
896 /*------------------------------------------------------------------------*
898 *------------------------------------------------------------------------*/
900 static int usb_do_process(struct usb_process *);
901 static int usb_proc_level = -1;
902 static struct mtx usb_proc_mtx;
907 int old_level = usb_proc_level;
908 int old_giant = Giant.owned;
911 device_run_interrupts(usb_pci_root);
917 while (++usb_proc_level < USB_PROC_MAX)
918 worked |= usb_do_process(usb_process + usb_proc_level);
920 usb_proc_level = old_level;
921 Giant.owned = old_giant;
929 sysinit_run(sysinit_data);
935 sysinit_run(sysuninit_data);
939 usb_process_init_sub(struct usb_process *up)
941 TAILQ_INIT(&up->up_qhead);
943 cv_init(&up->up_cv, "-");
944 cv_init(&up->up_drain, "usbdrain");
946 up->up_mtx = &usb_proc_mtx;
950 usb_process_init(void *arg)
954 mtx_init(&usb_proc_mtx, "usb-proc-mtx", NULL, MTX_DEF | MTX_RECURSE);
956 for (x = 0; x != USB_PROC_MAX; x++)
957 usb_process_init_sub(&usb_process[x]);
960 SYSINIT(usb_process_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, usb_process_init, NULL);
963 usb_do_process(struct usb_process *up)
965 struct usb_proc_msg *pm;
968 mtx_lock(&usb_proc_mtx);
971 pm = TAILQ_FIRST(&up->up_qhead);
977 (pm->pm_callback) (pm);
979 if (pm == TAILQ_FIRST(&up->up_qhead)) {
980 /* nothing changed */
981 TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry);
982 pm->pm_qentry.tqe_prev = NULL;
986 mtx_unlock(&usb_proc_mtx);
992 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
994 struct usb_proc_msg *pm0 = _pm0;
995 struct usb_proc_msg *pm1 = _pm1;
996 struct usb_proc_msg *pm2;
1002 if (pm0->pm_qentry.tqe_prev) {
1005 if (pm1->pm_qentry.tqe_prev) {
1010 * No entries are queued. Queue "pm0" and use the existing
1014 } else if (t == 1) {
1015 /* Check if we need to increment the message number. */
1016 if (pm0->pm_num == up->up_msg_num) {
1020 } else if (t == 2) {
1021 /* Check if we need to increment the message number. */
1022 if (pm1->pm_num == up->up_msg_num) {
1026 } else if (t == 3) {
1028 * Both entries are queued. Re-queue the entry closest to
1031 d = (pm1->pm_num - pm0->pm_num);
1033 /* Check sign after subtraction */
1034 if (d & 0x80000000) {
1040 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry);
1042 pm2 = NULL; /* panic - should not happen */
1045 /* Put message last on queue */
1047 pm2->pm_num = up->up_msg_num;
1048 TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry);
1053 /*------------------------------------------------------------------------*
1057 * 0: USB process is running
1058 * Else: USB process is tearing down
1059 *------------------------------------------------------------------------*/
1061 usb_proc_is_gone(struct usb_process *up)
1066 /*------------------------------------------------------------------------*
1069 * This function will return when the USB process message pointed to
1070 * by "pm" is no longer on a queue. This function must be called
1071 * having "usb_proc_mtx" locked.
1072 *------------------------------------------------------------------------*/
1074 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
1076 struct usb_proc_msg *pm0 = _pm0;
1077 struct usb_proc_msg *pm1 = _pm1;
1079 /* Just remove the messages from the queue. */
1080 if (pm0->pm_qentry.tqe_prev) {
1081 TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry);
1082 pm0->pm_qentry.tqe_prev = NULL;
1084 if (pm1->pm_qentry.tqe_prev) {
1085 TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry);
1086 pm1->pm_qentry.tqe_prev = NULL;
1090 /*------------------------------------------------------------------------*
1092 *------------------------------------------------------------------------*/
1094 #ifdef USB_PCI_PROBE_LIST
1095 static device_method_t pci_methods[] = {
1099 static driver_t pci_driver = {
1101 .methods = pci_methods,
1104 static devclass_t pci_devclass;
1106 DRIVER_MODULE(pci, pci, pci_driver, pci_devclass, 0, 0);
1108 static const char *usb_pci_devices[] = {
1112 #define USB_PCI_USB_MAX (sizeof(usb_pci_devices) / sizeof(void *))
1114 static device_t usb_pci_dev[USB_PCI_USB_MAX];
1117 usb_pci_mod_load(void *arg)
1121 usb_pci_root = device_add_child(NULL, "pci", -1);
1122 if (usb_pci_root == NULL)
1125 for (x = 0; x != USB_PCI_USB_MAX; x++) {
1126 usb_pci_dev[x] = device_add_child(usb_pci_root, usb_pci_devices[x], -1);
1127 if (usb_pci_dev[x] == NULL)
1129 if (device_probe_and_attach(usb_pci_dev[x])) {
1130 device_printf(usb_pci_dev[x],
1131 "WARNING: Probe and attach failed!\n");
1135 SYSINIT(usb_pci_mod_load, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_load, 0);
1138 usb_pci_mod_unload(void *arg)
1142 for (x = 0; x != USB_PCI_USB_MAX; x++) {
1143 if (usb_pci_dev[x]) {
1144 device_detach(usb_pci_dev[x]);
1145 device_delete_child(usb_pci_root, usb_pci_dev[x]);
1149 device_delete_child(NULL, usb_pci_root);
1151 SYSUNINIT(usb_pci_mod_unload, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_unload, 0);
1154 /*------------------------------------------------------------------------*
1156 *------------------------------------------------------------------------*/
1159 #define USB_POOL_ALIGN 8
1161 static uint8_t usb_pool[USB_POOL_SIZE] __aligned(USB_POOL_ALIGN);
1162 static uint32_t usb_pool_rem = USB_POOL_SIZE;
1163 static uint32_t usb_pool_entries;
1166 TAILQ_ENTRY(malloc_hdr) entry;
1168 } __aligned(USB_POOL_ALIGN);
1170 static TAILQ_HEAD(, malloc_hdr) malloc_head =
1171 TAILQ_HEAD_INITIALIZER(malloc_head);
1174 usb_malloc(unsigned long size)
1176 struct malloc_hdr *hdr;
1178 size = (size + USB_POOL_ALIGN - 1) & ~(USB_POOL_ALIGN - 1);
1179 size += sizeof(struct malloc_hdr);
1181 TAILQ_FOREACH(hdr, &malloc_head, entry) {
1182 if (hdr->size == size)
1187 DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n",
1188 (int)usb_pool_entries, (int)usb_pool_rem, (int)size);
1190 TAILQ_REMOVE(&malloc_head, hdr, entry);
1191 memset(hdr + 1, 0, hdr->size - sizeof(*hdr));
1194 if (usb_pool_rem >= size) {
1195 hdr = (void *)(usb_pool + USB_POOL_SIZE - usb_pool_rem);
1198 usb_pool_rem -= size;
1201 DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n",
1202 (int)usb_pool_entries, (int)usb_pool_rem, (int)size);
1204 memset(hdr + 1, 0, hdr->size - sizeof(*hdr));
1213 struct malloc_hdr *hdr;
1221 TAILQ_INSERT_TAIL(&malloc_head, hdr, entry);
1226 usb_strdup(const char *str)
1231 len = 1 + strlen(str);
1233 tmp = malloc(len,XXX,XXX);
1237 memcpy(tmp, str, len);