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