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