1 /* $FreeBSD$ */
2 /*-
3 * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
13 *
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
24 * SUCH DAMAGE.
25 */
26
27 #include <bsd_global.h>
28
29 struct usb_process usb_process[USB_PROC_MAX];
30
31 static device_t usb_pci_root;
32
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);
37
38 /*------------------------------------------------------------------------*
39 * Implementation of busdma API
40 *------------------------------------------------------------------------*/
41 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)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)
48 {
49 struct bus_dma_tag *ret;
50
51 ret = malloc(sizeof(struct bus_dma_tag), XXX, XXX);
52 if (*dmat == NULL)
53 return (ENOMEM);
54 ret->alignment = alignment;
55 ret->maxsize = maxsize;
56
57 *dmat = ret;
58
59 return (0);
60 }
61
62 int
bus_dmamem_alloc(bus_dma_tag_t dmat,void ** vaddr,int flags,bus_dmamap_t * mapp)63 bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
64 bus_dmamap_t *mapp)
65 {
66 void *addr;
67
68 addr = malloc(dmat->maxsize + dmat->alignment, XXX, XXX);
69 if (addr == NULL)
70 return (ENOMEM);
71
72 *mapp = addr;
73 addr = (void*)(((uintptr_t)addr + dmat->alignment - 1) & ~(dmat->alignment - 1));
74
75 *vaddr = addr;
76 return (0);
77 }
78
79 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)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)
83 {
84 bus_dma_segment_t segs[1];
85
86 segs[0].ds_addr = (uintptr_t)buf;
87 segs[0].ds_len = buflen;
88
89 (*callback)(callback_arg, segs, 1, 0);
90
91 return (0);
92 }
93
94 void
bus_dmamap_sync(bus_dma_tag_t dmat,bus_dmamap_t map,int flags)95 bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, int flags)
96 {
97 /* Assuming coherent memory */
98 __asm__ __volatile__("": : :"memory");
99 }
100
101 void
bus_dmamem_free(bus_dma_tag_t dmat,void * vaddr,bus_dmamap_t map)102 bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
103 {
104
105 free(map, XXX);
106 }
107
108 int
bus_dma_tag_destroy(bus_dma_tag_t dmat)109 bus_dma_tag_destroy(bus_dma_tag_t dmat)
110 {
111
112 free(dmat, XXX);
113 return (0);
114 }
115
116 /*------------------------------------------------------------------------*
117 * Implementation of resource management API
118 *------------------------------------------------------------------------*/
119
120 struct resource *
bus_alloc_resource_any(device_t dev,int type,int * rid,unsigned int flags)121 bus_alloc_resource_any(device_t dev, int type, int *rid, unsigned int flags)
122 {
123 struct resource *res;
124 int ret = EINVAL;
125
126 res = malloc(sizeof(*res), XXX, XXX);
127 if (res == NULL)
128 return (NULL);
129
130 res->__r_i = malloc(sizeof(struct resource_i), XXX, XXX);
131 if (res->__r_i == NULL) {
132 free(res, XXX);
133 return (NULL);
134 }
135
136 if (bus_alloc_resource_any_cb != NULL)
137 ret = (*bus_alloc_resource_any_cb)(res, dev, type, rid, flags);
138 if (ret == 0)
139 return (res);
140
141 free(res->__r_i, XXX);
142 free(res, XXX);
143 return (NULL);
144 }
145
146 int
bus_alloc_resources(device_t dev,struct resource_spec * rs,struct resource ** res)147 bus_alloc_resources(device_t dev, struct resource_spec *rs,
148 struct resource **res)
149 {
150 int i;
151
152 for (i = 0; rs[i].type != -1; i++)
153 res[i] = NULL;
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);
159 return (ENXIO);
160 }
161 }
162 return (0);
163 }
164
165 void
bus_release_resources(device_t dev,const struct resource_spec * rs,struct resource ** res)166 bus_release_resources(device_t dev, const struct resource_spec *rs,
167 struct resource **res)
168 {
169 int i;
170
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]);
175 res[i] = NULL;
176 }
177 }
178
179 int
bus_setup_intr(device_t dev,struct resource * r,int flags,driver_filter_t filter,driver_intr_t handler,void * arg,void ** cookiep)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)
182 {
183
184 dev->dev_irq_filter = filter;
185 dev->dev_irq_fn = handler;
186 dev->dev_irq_arg = arg;
187
188 return (0);
189 }
190
191 int
bus_teardown_intr(device_t dev,struct resource * r,void * cookie)192 bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
193 {
194
195 dev->dev_irq_filter = NULL;
196 dev->dev_irq_fn = NULL;
197 dev->dev_irq_arg = NULL;
198
199 return (0);
200 }
201
202 int
bus_release_resource(device_t dev,int type,int rid,struct resource * r)203 bus_release_resource(device_t dev, int type, int rid, struct resource *r)
204 {
205 /* Resource releasing is not supported */
206 return (EINVAL);
207 }
208
209 int
bus_generic_attach(device_t dev)210 bus_generic_attach(device_t dev)
211 {
212 device_t child;
213
214 TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
215 device_probe_and_attach(child);
216 }
217
218 return (0);
219 }
220
221 bus_space_tag_t
rman_get_bustag(struct resource * r)222 rman_get_bustag(struct resource *r)
223 {
224
225 return (r->r_bustag);
226 }
227
228 bus_space_handle_t
rman_get_bushandle(struct resource * r)229 rman_get_bushandle(struct resource *r)
230 {
231
232 return (r->r_bushandle);
233 }
234
235 u_long
rman_get_size(struct resource * r)236 rman_get_size(struct resource *r)
237 {
238
239 return (r->__r_i->r_end - r->__r_i->r_start + 1);
240 }
241
242 int
ofw_bus_status_okay(device_t dev)243 ofw_bus_status_okay(device_t dev)
244 {
245 if (ofw_bus_status_ok_cb == NULL)
246 return (0);
247
248 return ((*ofw_bus_status_ok_cb)(dev));
249 }
250
251 int
ofw_bus_is_compatible(device_t dev,char * name)252 ofw_bus_is_compatible(device_t dev, char *name)
253 {
254 if (ofw_bus_is_compatible_cb == NULL)
255 return (0);
256
257 return ((*ofw_bus_is_compatible_cb)(dev, name));
258 }
259
260 /*------------------------------------------------------------------------*
261 * Implementation of mutex API
262 *------------------------------------------------------------------------*/
263
264 struct mtx Giant;
265
266 static void
mtx_system_init(void * arg)267 mtx_system_init(void *arg)
268 {
269 mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
270 }
271 SYSINIT(mtx_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, mtx_system_init, NULL);
272
273 void
mtx_init(struct mtx * mtx,const char * name,const char * type,int opt)274 mtx_init(struct mtx *mtx, const char *name, const char *type, int opt)
275 {
276 mtx->owned = 0;
277 mtx->parent = mtx;
278 }
279
280 void
mtx_lock(struct mtx * mtx)281 mtx_lock(struct mtx *mtx)
282 {
283 mtx = mtx->parent;
284 mtx->owned++;
285 }
286
287 void
mtx_unlock(struct mtx * mtx)288 mtx_unlock(struct mtx *mtx)
289 {
290 mtx = mtx->parent;
291 mtx->owned--;
292 }
293
294 int
mtx_owned(struct mtx * mtx)295 mtx_owned(struct mtx *mtx)
296 {
297 mtx = mtx->parent;
298 return (mtx->owned != 0);
299 }
300
301 void
mtx_destroy(struct mtx * mtx)302 mtx_destroy(struct mtx *mtx)
303 {
304 /* NOP */
305 }
306
307 /*------------------------------------------------------------------------*
308 * Implementation of shared/exclusive mutex API
309 *------------------------------------------------------------------------*/
310
311 void
sx_init_flags(struct sx * sx,const char * name,int flags)312 sx_init_flags(struct sx *sx, const char *name, int flags)
313 {
314 sx->owned = 0;
315 }
316
317 void
sx_destroy(struct sx * sx)318 sx_destroy(struct sx *sx)
319 {
320 /* NOP */
321 }
322
323 void
sx_xlock(struct sx * sx)324 sx_xlock(struct sx *sx)
325 {
326 sx->owned++;
327 }
328
329 void
sx_xunlock(struct sx * sx)330 sx_xunlock(struct sx *sx)
331 {
332 sx->owned--;
333 }
334
335 int
sx_xlocked(struct sx * sx)336 sx_xlocked(struct sx *sx)
337 {
338 return (sx->owned != 0);
339 }
340
341 /*------------------------------------------------------------------------*
342 * Implementaiton of condition variable API
343 *------------------------------------------------------------------------*/
344
345 void
cv_init(struct cv * cv,const char * desc)346 cv_init(struct cv *cv, const char *desc)
347 {
348 cv->sleeping = 0;
349 }
350
351 void
cv_destroy(struct cv * cv)352 cv_destroy(struct cv *cv)
353 {
354 /* NOP */
355 }
356
357 void
cv_wait(struct cv * cv,struct mtx * mtx)358 cv_wait(struct cv *cv, struct mtx *mtx)
359 {
360 cv_timedwait(cv, mtx, -1);
361 }
362
363 int
cv_timedwait(struct cv * cv,struct mtx * mtx,int timo)364 cv_timedwait(struct cv *cv, struct mtx *mtx, int timo)
365 {
366 int start = ticks;
367 int delta;
368 int time = 0;
369
370 if (cv->sleeping)
371 return (EWOULDBLOCK); /* not allowed */
372
373 cv->sleeping = 1;
374
375 while (cv->sleeping) {
376 if (timo >= 0) {
377 delta = ticks - start;
378 if (delta >= timo || delta < 0)
379 break;
380 }
381 mtx_unlock(mtx);
382
383 usb_idle();
384
385 if (++time >= (1000000 / hz)) {
386 time = 0;
387 callout_process(1);
388 }
389
390 /* Sleep for 1 us */
391 delay(1);
392
393 mtx_lock(mtx);
394 }
395
396 if (cv->sleeping) {
397 cv->sleeping = 0;
398 return (EWOULDBLOCK); /* not allowed */
399 }
400 return (0);
401 }
402
403 void
cv_signal(struct cv * cv)404 cv_signal(struct cv *cv)
405 {
406 cv->sleeping = 0;
407 }
408
409 void
cv_broadcast(struct cv * cv)410 cv_broadcast(struct cv *cv)
411 {
412 cv->sleeping = 0;
413 }
414
415 /*------------------------------------------------------------------------*
416 * Implementation of callout API
417 *------------------------------------------------------------------------*/
418
419 static void callout_proc_msg(struct usb_proc_msg *);
420
421 volatile int ticks = 0;
422
423 static LIST_HEAD(, callout) head_callout = LIST_HEAD_INITIALIZER(&head_callout);
424
425 static struct mtx mtx_callout;
426 static struct usb_proc_msg callout_msg[2];
427
428 static void
callout_system_init(void * arg)429 callout_system_init(void *arg)
430 {
431 mtx_init(&mtx_callout, "callout-mtx", NULL, MTX_DEF | MTX_RECURSE);
432
433 callout_msg[0].pm_callback = &callout_proc_msg;
434 callout_msg[1].pm_callback = &callout_proc_msg;
435 }
436 SYSINIT(callout_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, callout_system_init, NULL);
437
438 static void
callout_callback(struct callout * c)439 callout_callback(struct callout *c)
440 {
441 mtx_lock(c->mtx);
442
443 mtx_lock(&mtx_callout);
444 if (c->entry.le_prev != NULL) {
445 LIST_REMOVE(c, entry);
446 c->entry.le_prev = NULL;
447 }
448 mtx_unlock(&mtx_callout);
449
450 if (c->c_func != NULL)
451 (c->c_func) (c->c_arg);
452
453 if (!(c->flags & CALLOUT_RETURNUNLOCKED))
454 mtx_unlock(c->mtx);
455 }
456
457 void
callout_process(int timeout)458 callout_process(int timeout)
459 {
460 ticks += timeout;
461 usb_proc_msignal(usb_process + 2, &callout_msg[0], &callout_msg[1]);
462 }
463
464 static void
callout_proc_msg(struct usb_proc_msg * pmsg)465 callout_proc_msg(struct usb_proc_msg *pmsg)
466 {
467 struct callout *c;
468 int delta;
469
470 repeat:
471 mtx_lock(&mtx_callout);
472
473 LIST_FOREACH(c, &head_callout, entry) {
474
475 delta = c->timeout - ticks;
476 if (delta < 0) {
477 mtx_unlock(&mtx_callout);
478
479 callout_callback(c);
480
481 goto repeat;
482 }
483 }
484 mtx_unlock(&mtx_callout);
485 }
486
487 void
callout_init_mtx(struct callout * c,struct mtx * mtx,int flags)488 callout_init_mtx(struct callout *c, struct mtx *mtx, int flags)
489 {
490 memset(c, 0, sizeof(*c));
491
492 if (mtx == NULL)
493 mtx = &Giant;
494
495 c->mtx = mtx;
496 c->flags = (flags & CALLOUT_RETURNUNLOCKED);
497 }
498
499 void
callout_reset(struct callout * c,int to_ticks,void (* func)(void *),void * arg)500 callout_reset(struct callout *c, int to_ticks,
501 void (*func) (void *), void *arg)
502 {
503 callout_stop(c);
504
505 c->c_func = func;
506 c->c_arg = arg;
507 c->timeout = ticks + to_ticks;
508
509 mtx_lock(&mtx_callout);
510 LIST_INSERT_HEAD(&head_callout, c, entry);
511 mtx_unlock(&mtx_callout);
512 }
513
514 void
callout_stop(struct callout * c)515 callout_stop(struct callout *c)
516 {
517 mtx_lock(&mtx_callout);
518
519 if (c->entry.le_prev != NULL) {
520 LIST_REMOVE(c, entry);
521 c->entry.le_prev = NULL;
522 }
523 mtx_unlock(&mtx_callout);
524
525 c->c_func = NULL;
526 c->c_arg = NULL;
527 }
528
529 void
callout_drain(struct callout * c)530 callout_drain(struct callout *c)
531 {
532 if (c->mtx == NULL)
533 return; /* not initialised */
534
535 mtx_lock(c->mtx);
536 callout_stop(c);
537 mtx_unlock(c->mtx);
538 }
539
540 int
callout_pending(struct callout * c)541 callout_pending(struct callout *c)
542 {
543 int retval;
544
545 mtx_lock(&mtx_callout);
546 retval = (c->entry.le_prev != NULL);
547 mtx_unlock(&mtx_callout);
548
549 return (retval);
550 }
551
552 /*------------------------------------------------------------------------*
553 * Implementation of device API
554 *------------------------------------------------------------------------*/
555
556 static const char unknown_string[] = { "unknown" };
557
558 static TAILQ_HEAD(, module_data) module_head =
559 TAILQ_HEAD_INITIALIZER(module_head);
560
561 static uint8_t
devclass_equal(const char * a,const char * b)562 devclass_equal(const char *a, const char *b)
563 {
564 char ta, tb;
565
566 if (a == b)
567 return (1);
568
569 while (1) {
570 ta = *a;
571 tb = *b;
572 if (ta != tb)
573 return (0);
574 if (ta == 0)
575 break;
576 a++;
577 b++;
578 }
579 return (1);
580 }
581
582 int
bus_generic_resume(device_t dev)583 bus_generic_resume(device_t dev)
584 {
585 return (0);
586 }
587
588 int
bus_generic_shutdown(device_t dev)589 bus_generic_shutdown(device_t dev)
590 {
591 return (0);
592 }
593
594 int
bus_generic_suspend(device_t dev)595 bus_generic_suspend(device_t dev)
596 {
597 return (0);
598 }
599
600 int
bus_generic_print_child(device_t dev,device_t child)601 bus_generic_print_child(device_t dev, device_t child)
602 {
603 return (0);
604 }
605
606 void
bus_generic_driver_added(device_t dev,driver_t * driver)607 bus_generic_driver_added(device_t dev, driver_t *driver)
608 {
609 return;
610 }
611
612 device_t
device_get_parent(device_t dev)613 device_get_parent(device_t dev)
614 {
615 return (dev ? dev->dev_parent : NULL);
616 }
617
618 void
device_set_interrupt(device_t dev,driver_filter_t * filter,driver_intr_t * fn,void * arg)619 device_set_interrupt(device_t dev, driver_filter_t *filter,
620 driver_intr_t *fn, void *arg)
621 {
622 dev->dev_irq_filter = filter;
623 dev->dev_irq_fn = fn;
624 dev->dev_irq_arg = arg;
625 }
626
627 void
device_run_interrupts(device_t parent)628 device_run_interrupts(device_t parent)
629 {
630 device_t child;
631
632 if (parent == NULL)
633 return;
634
635 TAILQ_FOREACH(child, &parent->dev_children, dev_link) {
636 int status;
637 if (child->dev_irq_filter != NULL)
638 status = child->dev_irq_filter(child->dev_irq_arg);
639 else
640 status = FILTER_SCHEDULE_THREAD;
641
642 if (status == FILTER_SCHEDULE_THREAD) {
643 if (child->dev_irq_fn != NULL)
644 (child->dev_irq_fn) (child->dev_irq_arg);
645 }
646 }
647 }
648
649 void
device_set_ivars(device_t dev,void * ivars)650 device_set_ivars(device_t dev, void *ivars)
651 {
652 dev->dev_aux = ivars;
653 }
654
655 void *
device_get_ivars(device_t dev)656 device_get_ivars(device_t dev)
657 {
658 return (dev ? dev->dev_aux : NULL);
659 }
660
661 int
device_get_unit(device_t dev)662 device_get_unit(device_t dev)
663 {
664 return (dev ? dev->dev_unit : 0);
665 }
666
667 int
bus_generic_detach(device_t dev)668 bus_generic_detach(device_t dev)
669 {
670 device_t child;
671 int error;
672
673 if (!dev->dev_attached)
674 return (EBUSY);
675
676 TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
677 if ((error = device_detach(child)) != 0)
678 return (error);
679 }
680 return (0);
681 }
682
683 const char *
device_get_nameunit(device_t dev)684 device_get_nameunit(device_t dev)
685 {
686 if (dev && dev->dev_nameunit[0])
687 return (dev->dev_nameunit);
688
689 return (unknown_string);
690 }
691
692 static uint8_t
devclass_create(devclass_t * dc_pp)693 devclass_create(devclass_t *dc_pp)
694 {
695 if (dc_pp == NULL) {
696 return (1);
697 }
698 if (dc_pp[0] == NULL) {
699 dc_pp[0] = malloc(sizeof(**(dc_pp)),
700 M_DEVBUF, M_WAITOK | M_ZERO);
701
702 if (dc_pp[0] == NULL) {
703 return (1);
704 }
705 }
706 return (0);
707 }
708
709 static const struct module_data *
devclass_find_create(const char * classname)710 devclass_find_create(const char *classname)
711 {
712 const struct module_data *mod;
713
714 TAILQ_FOREACH(mod, &module_head, entry) {
715 if (devclass_equal(mod->mod_name, classname)) {
716 if (devclass_create(mod->devclass_pp)) {
717 continue;
718 }
719 return (mod);
720 }
721 }
722 return (NULL);
723 }
724
725 static uint8_t
devclass_add_device(const struct module_data * mod,device_t dev)726 devclass_add_device(const struct module_data *mod, device_t dev)
727 {
728 device_t *pp_dev;
729 device_t *end;
730 uint8_t unit;
731
732 pp_dev = mod->devclass_pp[0]->dev_list;
733 end = pp_dev + DEVCLASS_MAXUNIT;
734 unit = 0;
735
736 while (pp_dev != end) {
737 if (*pp_dev == NULL) {
738 *pp_dev = dev;
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);
744 return (0);
745 }
746 pp_dev++;
747 unit++;
748 }
749 DPRINTF("Could not add device to devclass.\n");
750 return (1);
751 }
752
753 static void
devclass_delete_device(const struct module_data * mod,device_t dev)754 devclass_delete_device(const struct module_data *mod, device_t dev)
755 {
756 if (mod == NULL) {
757 return;
758 }
759 mod->devclass_pp[0]->dev_list[dev->dev_unit] = NULL;
760 dev->dev_module = NULL;
761 }
762
763 static device_t
make_device(device_t parent,const char * name)764 make_device(device_t parent, const char *name)
765 {
766 device_t dev = NULL;
767 const struct module_data *mod = NULL;
768
769 if (name) {
770
771 mod = devclass_find_create(name);
772
773 if (!mod) {
774
775 DPRINTF("%s:%d:%s: can't find device "
776 "class %s\n", __FILE__, __LINE__,
777 __FUNCTION__, name);
778
779 goto done;
780 }
781 }
782 dev = malloc(sizeof(*dev),
783 M_DEVBUF, M_WAITOK | M_ZERO);
784
785 if (dev == NULL)
786 goto done;
787
788 dev->dev_parent = parent;
789 TAILQ_INIT(&dev->dev_children);
790
791 if (name) {
792 dev->dev_fixed_class = 1;
793 if (devclass_add_device(mod, dev)) {
794 goto error;
795 }
796 }
797 done:
798 return (dev);
799
800 error:
801 if (dev) {
802 free(dev, M_DEVBUF);
803 }
804 return (NULL);
805 }
806
807 device_t
device_add_child(device_t dev,const char * name,int unit)808 device_add_child(device_t dev, const char *name, int unit)
809 {
810 device_t child;
811
812 if (unit != -1) {
813 device_printf(dev, "Unit is not -1\n");
814 }
815 child = make_device(dev, name);
816 if (child == NULL) {
817 device_printf(dev, "Could not add child '%s'\n", name);
818 goto done;
819 }
820 if (dev == NULL) {
821 /* no parent */
822 goto done;
823 }
824 TAILQ_INSERT_TAIL(&dev->dev_children, child, dev_link);
825 done:
826 return (child);
827 }
828
829 int
device_delete_child(device_t dev,device_t child)830 device_delete_child(device_t dev, device_t child)
831 {
832 int error = 0;
833 device_t grandchild;
834
835 /* detach parent before deleting children, if any */
836 error = device_detach(child);
837 if (error)
838 goto done;
839
840 /* remove children second */
841 while ((grandchild = TAILQ_FIRST(&child->dev_children))) {
842 error = device_delete_child(child, grandchild);
843 if (error) {
844 device_printf(dev, "Error deleting child!\n");
845 goto done;
846 }
847 }
848
849 devclass_delete_device(child->dev_module, child);
850
851 if (dev != NULL) {
852 /* remove child from parent */
853 TAILQ_REMOVE(&dev->dev_children, child, dev_link);
854 }
855 free(child, M_DEVBUF);
856
857 done:
858 return (error);
859 }
860
861 int
device_delete_children(device_t dev)862 device_delete_children(device_t dev)
863 {
864 device_t child;
865 int error = 0;
866
867 while ((child = TAILQ_FIRST(&dev->dev_children))) {
868 error = device_delete_child(dev, child);
869 if (error) {
870 device_printf(dev, "Error deleting child!\n");
871 break;
872 }
873 }
874 return (error);
875 }
876
877 void
device_quiet(device_t dev)878 device_quiet(device_t dev)
879 {
880 dev->dev_quiet = 1;
881 }
882
883 const char *
device_get_desc(device_t dev)884 device_get_desc(device_t dev)
885 {
886 if (dev)
887 return &(dev->dev_desc[0]);
888 return (unknown_string);
889 }
890
891 static int
default_method(void)892 default_method(void)
893 {
894 /* do nothing */
895 DPRINTF("Default method called\n");
896 return (0);
897 }
898
899 void *
device_get_method(device_t dev,const char * what)900 device_get_method(device_t dev, const char *what)
901 {
902 const struct device_method *mtod;
903
904 mtod = dev->dev_module->driver->methods;
905 while (mtod->func != NULL) {
906 if (devclass_equal(mtod->desc, what)) {
907 return (mtod->func);
908 }
909 mtod++;
910 }
911 return ((void *)&default_method);
912 }
913
914 const char *
device_get_name(device_t dev)915 device_get_name(device_t dev)
916 {
917 if (dev == NULL)
918 return (unknown_string);
919
920 return (dev->dev_module->driver->name);
921 }
922
923 static int
device_allocate_softc(device_t dev)924 device_allocate_softc(device_t dev)
925 {
926 const struct module_data *mod;
927
928 mod = dev->dev_module;
929
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);
934
935 if (dev->dev_sc == NULL)
936 return (ENOMEM);
937
938 dev->dev_softc_alloc = 1;
939 }
940 return (0);
941 }
942
943 int
device_probe_and_attach(device_t dev)944 device_probe_and_attach(device_t dev)
945 {
946 const struct module_data *mod;
947 const char *bus_name_parent;
948
949 bus_name_parent = device_get_name(device_get_parent(dev));
950
951 if (dev->dev_attached)
952 return (0); /* fail-safe */
953
954 if (dev->dev_fixed_class) {
955
956 mod = dev->dev_module;
957
958 if (DEVICE_PROBE(dev) <= 0) {
959
960 if (device_allocate_softc(dev) == 0) {
961
962 if (DEVICE_ATTACH(dev) == 0) {
963 /* success */
964 dev->dev_attached = 1;
965 return (0);
966 }
967 }
968 }
969 device_detach(dev);
970
971 goto error;
972 }
973 /*
974 * Else find a module for our device, if any
975 */
976
977 TAILQ_FOREACH(mod, &module_head, entry) {
978 if (devclass_equal(mod->bus_name, bus_name_parent)) {
979 if (devclass_create(mod->devclass_pp)) {
980 continue;
981 }
982 if (devclass_add_device(mod, dev)) {
983 continue;
984 }
985 if (DEVICE_PROBE(dev) <= 0) {
986
987 if (device_allocate_softc(dev) == 0) {
988
989 if (DEVICE_ATTACH(dev) == 0) {
990 /* success */
991 dev->dev_attached = 1;
992 return (0);
993 }
994 }
995 }
996 /* else try next driver */
997
998 device_detach(dev);
999 }
1000 }
1001
1002 error:
1003 return (ENODEV);
1004 }
1005
1006 int
device_detach(device_t dev)1007 device_detach(device_t dev)
1008 {
1009 const struct module_data *mod = dev->dev_module;
1010 int error;
1011
1012 if (dev->dev_attached) {
1013
1014 error = DEVICE_DETACH(dev);
1015 if (error) {
1016 return error;
1017 }
1018 dev->dev_attached = 0;
1019 }
1020 device_set_softc(dev, NULL);
1021
1022 if (dev->dev_fixed_class == 0)
1023 devclass_delete_device(mod, dev);
1024
1025 return (0);
1026 }
1027
1028 void
device_set_softc(device_t dev,void * softc)1029 device_set_softc(device_t dev, void *softc)
1030 {
1031 if (dev->dev_softc_alloc) {
1032 free(dev->dev_sc, M_DEVBUF);
1033 dev->dev_sc = NULL;
1034 }
1035 dev->dev_sc = softc;
1036 dev->dev_softc_alloc = 0;
1037 }
1038
1039 void *
device_get_softc(device_t dev)1040 device_get_softc(device_t dev)
1041 {
1042 if (dev == NULL)
1043 return (NULL);
1044
1045 return (dev->dev_sc);
1046 }
1047
1048 int
device_is_attached(device_t dev)1049 device_is_attached(device_t dev)
1050 {
1051 return (dev->dev_attached);
1052 }
1053
1054 void
device_set_desc(device_t dev,const char * desc)1055 device_set_desc(device_t dev, const char *desc)
1056 {
1057 snprintf(dev->dev_desc, sizeof(dev->dev_desc), "%s", desc);
1058 }
1059
1060 void
device_set_desc_copy(device_t dev,const char * desc)1061 device_set_desc_copy(device_t dev, const char *desc)
1062 {
1063 device_set_desc(dev, desc);
1064 }
1065
1066 void *
devclass_get_softc(devclass_t dc,int unit)1067 devclass_get_softc(devclass_t dc, int unit)
1068 {
1069 return (device_get_softc(devclass_get_device(dc, unit)));
1070 }
1071
1072 int
devclass_get_maxunit(devclass_t dc)1073 devclass_get_maxunit(devclass_t dc)
1074 {
1075 int max_unit = 0;
1076
1077 if (dc) {
1078 max_unit = DEVCLASS_MAXUNIT;
1079 while (max_unit--) {
1080 if (dc->dev_list[max_unit]) {
1081 break;
1082 }
1083 }
1084 max_unit++;
1085 }
1086 return (max_unit);
1087 }
1088
1089 device_t
devclass_get_device(devclass_t dc,int unit)1090 devclass_get_device(devclass_t dc, int unit)
1091 {
1092 return (((unit < 0) || (unit >= DEVCLASS_MAXUNIT) || (dc == NULL)) ?
1093 NULL : dc->dev_list[unit]);
1094 }
1095
1096 devclass_t
devclass_find(const char * classname)1097 devclass_find(const char *classname)
1098 {
1099 const struct module_data *mod;
1100
1101 TAILQ_FOREACH(mod, &module_head, entry) {
1102 if (devclass_equal(mod->driver->name, classname))
1103 return (mod->devclass_pp[0]);
1104 }
1105 return (NULL);
1106 }
1107
1108 void
module_register(void * data)1109 module_register(void *data)
1110 {
1111 struct module_data *mdata = data;
1112
1113 TAILQ_INSERT_TAIL(&module_head, mdata, entry);
1114 }
1115
1116 /*------------------------------------------------------------------------*
1117 * System startup
1118 *------------------------------------------------------------------------*/
1119
1120 static void
sysinit_run(const void ** ppdata)1121 sysinit_run(const void **ppdata)
1122 {
1123 const struct sysinit *psys;
1124
1125 while ((psys = *ppdata) != NULL) {
1126 (psys->func) (psys->data);
1127 ppdata++;
1128 }
1129 }
1130
1131 /*------------------------------------------------------------------------*
1132 * USB process API
1133 *------------------------------------------------------------------------*/
1134
1135 static int usb_do_process(struct usb_process *);
1136 static int usb_proc_level = -1;
1137 static struct mtx usb_proc_mtx;
1138
1139 void
usb_idle(void)1140 usb_idle(void)
1141 {
1142 int old_level = usb_proc_level;
1143 int old_giant = Giant.owned;
1144 int worked;
1145
1146 device_run_interrupts(usb_pci_root);
1147
1148 do {
1149 worked = 0;
1150 Giant.owned = 0;
1151
1152 while (++usb_proc_level < USB_PROC_MAX)
1153 worked |= usb_do_process(usb_process + usb_proc_level);
1154
1155 usb_proc_level = old_level;
1156 Giant.owned = old_giant;
1157
1158 } while (worked);
1159 }
1160
1161 void
usb_init(void)1162 usb_init(void)
1163 {
1164 sysinit_run(sysinit_data);
1165 }
1166
1167 void
usb_uninit(void)1168 usb_uninit(void)
1169 {
1170 sysinit_run(sysuninit_data);
1171 }
1172
1173 static void
usb_process_init_sub(struct usb_process * up)1174 usb_process_init_sub(struct usb_process *up)
1175 {
1176 TAILQ_INIT(&up->up_qhead);
1177
1178 cv_init(&up->up_cv, "-");
1179 cv_init(&up->up_drain, "usbdrain");
1180
1181 up->up_mtx = &usb_proc_mtx;
1182 }
1183
1184 static void
usb_process_init(void * arg)1185 usb_process_init(void *arg)
1186 {
1187 uint8_t x;
1188
1189 mtx_init(&usb_proc_mtx, "usb-proc-mtx", NULL, MTX_DEF | MTX_RECURSE);
1190
1191 for (x = 0; x != USB_PROC_MAX; x++)
1192 usb_process_init_sub(&usb_process[x]);
1193
1194 }
1195 SYSINIT(usb_process_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, usb_process_init, NULL);
1196
1197 static int
usb_do_process(struct usb_process * up)1198 usb_do_process(struct usb_process *up)
1199 {
1200 struct usb_proc_msg *pm;
1201 int worked = 0;
1202
1203 mtx_lock(&usb_proc_mtx);
1204
1205 repeat:
1206 pm = TAILQ_FIRST(&up->up_qhead);
1207
1208 if (pm != NULL) {
1209
1210 worked = 1;
1211
1212 (pm->pm_callback) (pm);
1213
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;
1218 }
1219 goto repeat;
1220 }
1221 mtx_unlock(&usb_proc_mtx);
1222
1223 return (worked);
1224 }
1225
1226 void *
usb_proc_msignal(struct usb_process * up,void * _pm0,void * _pm1)1227 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
1228 {
1229 struct usb_proc_msg *pm0 = _pm0;
1230 struct usb_proc_msg *pm1 = _pm1;
1231 struct usb_proc_msg *pm2;
1232 usb_size_t d;
1233 uint8_t t;
1234
1235 t = 0;
1236
1237 if (pm0->pm_qentry.tqe_prev) {
1238 t |= 1;
1239 }
1240 if (pm1->pm_qentry.tqe_prev) {
1241 t |= 2;
1242 }
1243 if (t == 0) {
1244 /*
1245 * No entries are queued. Queue "pm0" and use the existing
1246 * message number.
1247 */
1248 pm2 = pm0;
1249 } else if (t == 1) {
1250 /* Check if we need to increment the message number. */
1251 if (pm0->pm_num == up->up_msg_num) {
1252 up->up_msg_num++;
1253 }
1254 pm2 = pm1;
1255 } else if (t == 2) {
1256 /* Check if we need to increment the message number. */
1257 if (pm1->pm_num == up->up_msg_num) {
1258 up->up_msg_num++;
1259 }
1260 pm2 = pm0;
1261 } else if (t == 3) {
1262 /*
1263 * Both entries are queued. Re-queue the entry closest to
1264 * the end.
1265 */
1266 d = (pm1->pm_num - pm0->pm_num);
1267
1268 /* Check sign after subtraction */
1269 if (d & 0x80000000) {
1270 pm2 = pm0;
1271 } else {
1272 pm2 = pm1;
1273 }
1274
1275 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry);
1276 } else {
1277 pm2 = NULL; /* panic - should not happen */
1278 }
1279
1280 /* Put message last on queue */
1281
1282 pm2->pm_num = up->up_msg_num;
1283 TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry);
1284
1285 return (pm2);
1286 }
1287
1288 /*------------------------------------------------------------------------*
1289 * usb_proc_is_gone
1290 *
1291 * Return values:
1292 * 0: USB process is running
1293 * Else: USB process is tearing down
1294 *------------------------------------------------------------------------*/
1295 uint8_t
usb_proc_is_gone(struct usb_process * up)1296 usb_proc_is_gone(struct usb_process *up)
1297 {
1298 return (0);
1299 }
1300
1301 /*------------------------------------------------------------------------*
1302 * usb_proc_mwait
1303 *
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 *------------------------------------------------------------------------*/
1308 void
usb_proc_mwait(struct usb_process * up,void * _pm0,void * _pm1)1309 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
1310 {
1311 struct usb_proc_msg *pm0 = _pm0;
1312 struct usb_proc_msg *pm1 = _pm1;
1313
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;
1318 }
1319 if (pm1->pm_qentry.tqe_prev) {
1320 TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry);
1321 pm1->pm_qentry.tqe_prev = NULL;
1322 }
1323 }
1324
1325 /*------------------------------------------------------------------------*
1326 * SYSTEM attach
1327 *------------------------------------------------------------------------*/
1328
1329 #ifdef USB_PCI_PROBE_LIST
1330 static device_method_t pci_methods[] = {
1331 DEVMETHOD_END
1332 };
1333
1334 static driver_t pci_driver = {
1335 .name = "pci",
1336 .methods = pci_methods,
1337 };
1338
1339 static devclass_t pci_devclass;
1340
1341 DRIVER_MODULE(pci, pci, pci_driver, pci_devclass, 0, 0);
1342
1343 static const char *usb_pci_devices[] = {
1344 USB_PCI_PROBE_LIST
1345 };
1346
1347 #define USB_PCI_USB_MAX (sizeof(usb_pci_devices) / sizeof(void *))
1348
1349 static device_t usb_pci_dev[USB_PCI_USB_MAX];
1350
1351 static void
usb_pci_mod_load(void * arg)1352 usb_pci_mod_load(void *arg)
1353 {
1354 uint32_t x;
1355
1356 usb_pci_root = device_add_child(NULL, "pci", -1);
1357 if (usb_pci_root == NULL)
1358 return;
1359
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)
1363 continue;
1364 if (device_probe_and_attach(usb_pci_dev[x])) {
1365 device_printf(usb_pci_dev[x],
1366 "WARNING: Probe and attach failed!\n");
1367 }
1368 }
1369 }
1370 SYSINIT(usb_pci_mod_load, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_load, 0);
1371
1372 static void
usb_pci_mod_unload(void * arg)1373 usb_pci_mod_unload(void *arg)
1374 {
1375 uint32_t x;
1376
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]);
1381 }
1382 }
1383 if (usb_pci_root)
1384 device_delete_child(NULL, usb_pci_root);
1385 }
1386 SYSUNINIT(usb_pci_mod_unload, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_unload, 0);
1387 #endif
1388
1389 /*------------------------------------------------------------------------*
1390 * MALLOC API
1391 *------------------------------------------------------------------------*/
1392
1393 #ifndef HAVE_MALLOC
1394 #define USB_POOL_ALIGN 8
1395
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;
1399
1400 struct malloc_hdr {
1401 TAILQ_ENTRY(malloc_hdr) entry;
1402 uint32_t size;
1403 } __aligned(USB_POOL_ALIGN);
1404
1405 static TAILQ_HEAD(, malloc_hdr) malloc_head =
1406 TAILQ_HEAD_INITIALIZER(malloc_head);
1407
1408 void *
usb_malloc(unsigned long size)1409 usb_malloc(unsigned long size)
1410 {
1411 struct malloc_hdr *hdr;
1412
1413 size = (size + USB_POOL_ALIGN - 1) & ~(USB_POOL_ALIGN - 1);
1414 size += sizeof(struct malloc_hdr);
1415
1416 TAILQ_FOREACH(hdr, &malloc_head, entry) {
1417 if (hdr->size == size)
1418 break;
1419 }
1420
1421 if (hdr) {
1422 DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n",
1423 (int)usb_pool_entries, (int)usb_pool_rem, (int)size);
1424
1425 TAILQ_REMOVE(&malloc_head, hdr, entry);
1426 memset(hdr + 1, 0, hdr->size - sizeof(*hdr));
1427 return (hdr + 1);
1428 }
1429 if (usb_pool_rem >= size) {
1430 hdr = (void *)(usb_pool + USB_POOL_SIZE - usb_pool_rem);
1431 hdr->size = size;
1432
1433 usb_pool_rem -= size;
1434 usb_pool_entries++;
1435
1436 DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n",
1437 (int)usb_pool_entries, (int)usb_pool_rem, (int)size);
1438
1439 memset(hdr + 1, 0, hdr->size - sizeof(*hdr));
1440 return (hdr + 1);
1441 }
1442 return (NULL);
1443 }
1444
1445 void
usb_free(void * arg)1446 usb_free(void *arg)
1447 {
1448 struct malloc_hdr *hdr;
1449
1450 if (arg == NULL)
1451 return;
1452
1453 hdr = arg;
1454 hdr--;
1455
1456 TAILQ_INSERT_TAIL(&malloc_head, hdr, entry);
1457 }
1458 #endif
1459
1460 char *
usb_strdup(const char * str)1461 usb_strdup(const char *str)
1462 {
1463 char *tmp;
1464 int len;
1465
1466 len = 1 + strlen(str);
1467
1468 tmp = malloc(len,XXX,XXX);
1469 if (tmp == NULL)
1470 return (NULL);
1471
1472 memcpy(tmp, str, len);
1473 return (tmp);
1474 }
1475