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