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