xref: /freebsd/stand/kshim/bsd_kernel.c (revision 4f52dfbb8d6c4d446500c5b097e3806ec219fbd4)
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
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
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
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
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
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
111 bus_dma_tag_destroy(bus_dma_tag_t dmat)
112 {
113 
114 	free(dmat, XXX);
115 	return (0);
116 }
117 
118 struct resource *
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
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
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
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
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
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
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
220 rman_get_bustag(struct resource *r)
221 {
222 
223 	return (r->r_bustag);
224 }
225 
226 bus_space_handle_t
227 rman_get_bushandle(struct resource *r)
228 {
229 
230 	return (r->r_bushandle);
231 }
232 
233 u_long
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
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
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
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
266 mtx_lock(struct mtx *mtx)
267 {
268 	mtx = mtx->parent;
269 	mtx->owned++;
270 }
271 
272 void
273 mtx_unlock(struct mtx *mtx)
274 {
275 	mtx = mtx->parent;
276 	mtx->owned--;
277 }
278 
279 int
280 mtx_owned(struct mtx *mtx)
281 {
282 	mtx = mtx->parent;
283 	return (mtx->owned != 0);
284 }
285 
286 void
287 mtx_destroy(struct mtx *mtx)
288 {
289 	/* NOP */
290 }
291 
292 /*------------------------------------------------------------------------*
293  * Implementation of shared/exclusive mutex API
294  *------------------------------------------------------------------------*/
295 
296 void
297 sx_init_flags(struct sx *sx, const char *name, int flags)
298 {
299 	sx->owned = 0;
300 }
301 
302 void
303 sx_destroy(struct sx *sx)
304 {
305 	/* NOP */
306 }
307 
308 void
309 sx_xlock(struct sx *sx)
310 {
311 	sx->owned++;
312 }
313 
314 void
315 sx_xunlock(struct sx *sx)
316 {
317 	sx->owned--;
318 }
319 
320 int
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
331 cv_init(struct cv *cv, const char *desc)
332 {
333 	cv->sleeping = 0;
334 }
335 
336 void
337 cv_destroy(struct cv *cv)
338 {
339 	/* NOP */
340 }
341 
342 void
343 cv_wait(struct cv *cv, struct mtx *mtx)
344 {
345 	cv_timedwait(cv, mtx, -1);
346 }
347 
348 int
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
389 cv_signal(struct cv *cv)
390 {
391 	cv->sleeping = 0;
392 }
393 
394 void
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
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
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
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
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
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
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
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
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
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
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
568 bus_generic_resume(device_t dev)
569 {
570 	return (0);
571 }
572 
573 int
574 bus_generic_shutdown(device_t dev)
575 {
576 	return (0);
577 }
578 
579 int
580 bus_generic_suspend(device_t dev)
581 {
582 	return (0);
583 }
584 
585 int
586 bus_generic_print_child(device_t dev, device_t child)
587 {
588 	return (0);
589 }
590 
591 void
592 bus_generic_driver_added(device_t dev, driver_t *driver)
593 {
594 	return;
595 }
596 
597 device_t
598 device_get_parent(device_t dev)
599 {
600 	return (dev ? dev->dev_parent : NULL);
601 }
602 
603 void
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
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
635 device_set_ivars(device_t dev, void *ivars)
636 {
637 	dev->dev_aux = ivars;
638 }
639 
640 void   *
641 device_get_ivars(device_t dev)
642 {
643 	return (dev ? dev->dev_aux : NULL);
644 }
645 
646 int
647 device_get_unit(device_t dev)
648 {
649 	return (dev ? dev->dev_unit : 0);
650 }
651 
652 int
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 *
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
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 *
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
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
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
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
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
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
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
863 device_quiet(device_t dev)
864 {
865 	dev->dev_quiet = 1;
866 }
867 
868 const char *
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
877 default_method(void)
878 {
879 	/* do nothing */
880 	DPRINTF("Default method called\n");
881 	return (0);
882 }
883 
884 void   *
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 *
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
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
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
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
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   *
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
1034 device_is_attached(device_t dev)
1035 {
1036 	return (dev->dev_attached);
1037 }
1038 
1039 void
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
1046 device_set_desc_copy(device_t dev, const char *desc)
1047 {
1048 	device_set_desc(dev, desc);
1049 }
1050 
1051 void   *
1052 devclass_get_softc(devclass_t dc, int unit)
1053 {
1054 	return (device_get_softc(devclass_get_device(dc, unit)));
1055 }
1056 
1057 int
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
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
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
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
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
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
1147 usb_init(void)
1148 {
1149 	sysinit_run(sysinit_data);
1150 }
1151 
1152 void
1153 usb_uninit(void)
1154 {
1155 	sysinit_run(sysuninit_data);
1156 }
1157 
1158 static void
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
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
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   *
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
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
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
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
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   *
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
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   *
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