1/* $FreeBSD: stable/11/stand/kshim/bsd_kernel.c 315221 2017-03-14 02:06:03Z pfg $ */
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
29struct usb_process usb_process[USB_PROC_MAX];
30
31static device_t usb_pci_root;
32
33/*------------------------------------------------------------------------*
34 * Implementation of mutex API
35 *------------------------------------------------------------------------*/
36
37struct mtx Giant;
38int (*bus_alloc_resource_any_cb)(struct resource *res, device_t dev,
39    int type, int *rid, unsigned int flags);
40int (*ofw_bus_status_ok_cb)(device_t dev);
41int (*ofw_bus_is_compatible_cb)(device_t dev, char *name);
42
43static void
44mtx_system_init(void *arg)
45{
46	mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
47}
48SYSINIT(mtx_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, mtx_system_init, NULL);
49
50int
51bus_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
71int
72bus_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
88int
89bus_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
103void
104bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
105{
106
107	free(map, XXX);
108}
109
110int
111bus_dma_tag_destroy(bus_dma_tag_t dmat)
112{
113
114	free(dmat, XXX);
115	return (0);
116}
117
118struct resource *
119bus_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
144int
145bus_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
163void
164bus_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
177int
178bus_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
189int
190bus_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
200int
201bus_release_resource(device_t dev, int type, int rid, struct resource *r)
202{
203	/* Resource releasing is not supported */
204	return (EINVAL);
205}
206
207int
208bus_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
219bus_space_tag_t
220rman_get_bustag(struct resource *r)
221{
222
223	return (r->r_bustag);
224}
225
226bus_space_handle_t
227rman_get_bushandle(struct resource *r)
228{
229
230	return (r->r_bushandle);
231}
232
233u_long
234rman_get_size(struct resource *r)
235{
236
237	return (r->__r_i->r_end - r->__r_i->r_start + 1);
238}
239
240int
241ofw_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
249int
250ofw_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
258void
259mtx_init(struct mtx *mtx, const char *name, const char *type, int opt)
260{
261	mtx->owned = 0;
262	mtx->parent = mtx;
263}
264
265void
266mtx_lock(struct mtx *mtx)
267{
268	mtx = mtx->parent;
269	mtx->owned++;
270}
271
272void
273mtx_unlock(struct mtx *mtx)
274{
275	mtx = mtx->parent;
276	mtx->owned--;
277}
278
279int
280mtx_owned(struct mtx *mtx)
281{
282	mtx = mtx->parent;
283	return (mtx->owned != 0);
284}
285
286void
287mtx_destroy(struct mtx *mtx)
288{
289	/* NOP */
290}
291
292/*------------------------------------------------------------------------*
293 * Implementation of shared/exclusive mutex API
294 *------------------------------------------------------------------------*/
295
296void
297sx_init_flags(struct sx *sx, const char *name, int flags)
298{
299	sx->owned = 0;
300}
301
302void
303sx_destroy(struct sx *sx)
304{
305	/* NOP */
306}
307
308void
309sx_xlock(struct sx *sx)
310{
311	sx->owned++;
312}
313
314void
315sx_xunlock(struct sx *sx)
316{
317	sx->owned--;
318}
319
320int
321sx_xlocked(struct sx *sx)
322{
323	return (sx->owned != 0);
324}
325
326/*------------------------------------------------------------------------*
327 * Implementaiton of condition variable API
328 *------------------------------------------------------------------------*/
329
330void
331cv_init(struct cv *cv, const char *desc)
332{
333	cv->sleeping = 0;
334}
335
336void
337cv_destroy(struct cv *cv)
338{
339	/* NOP */
340}
341
342void
343cv_wait(struct cv *cv, struct mtx *mtx)
344{
345	cv_timedwait(cv, mtx, -1);
346}
347
348int
349cv_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
388void
389cv_signal(struct cv *cv)
390{
391	cv->sleeping = 0;
392}
393
394void
395cv_broadcast(struct cv *cv)
396{
397	cv->sleeping = 0;
398}
399
400/*------------------------------------------------------------------------*
401 * Implementation of callout API
402 *------------------------------------------------------------------------*/
403
404static void callout_proc_msg(struct usb_proc_msg *);
405
406volatile int ticks = 0;
407
408static LIST_HEAD(, callout) head_callout = LIST_HEAD_INITIALIZER(&head_callout);
409
410static struct mtx mtx_callout;
411static struct usb_proc_msg callout_msg[2];
412
413static void
414callout_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}
421SYSINIT(callout_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, callout_system_init, NULL);
422
423static void
424callout_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
442void
443callout_process(int timeout)
444{
445	ticks += timeout;
446	usb_proc_msignal(usb_process + 2, &callout_msg[0], &callout_msg[1]);
447}
448
449static void
450callout_proc_msg(struct usb_proc_msg *pmsg)
451{
452	struct callout *c;
453	int delta;
454
455repeat:
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
472void
473callout_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
484void
485callout_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
499void
500callout_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
514void
515callout_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
525int
526callout_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
541static const char unknown_string[] = { "unknown" };
542
543static TAILQ_HEAD(, module_data) module_head =
544    TAILQ_HEAD_INITIALIZER(module_head);
545
546static uint8_t
547devclass_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
567int
568bus_generic_resume(device_t dev)
569{
570	return (0);
571}
572
573int
574bus_generic_shutdown(device_t dev)
575{
576	return (0);
577}
578
579int
580bus_generic_suspend(device_t dev)
581{
582	return (0);
583}
584
585int
586bus_generic_print_child(device_t dev, device_t child)
587{
588	return (0);
589}
590
591void
592bus_generic_driver_added(device_t dev, driver_t *driver)
593{
594	return;
595}
596
597device_t
598device_get_parent(device_t dev)
599{
600	return (dev ? dev->dev_parent : NULL);
601}
602
603void
604device_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
612void
613device_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
634void
635device_set_ivars(device_t dev, void *ivars)
636{
637	dev->dev_aux = ivars;
638}
639
640void   *
641device_get_ivars(device_t dev)
642{
643	return (dev ? dev->dev_aux : NULL);
644}
645
646int
647device_get_unit(device_t dev)
648{
649	return (dev ? dev->dev_unit : 0);
650}
651
652int
653bus_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
668const char *
669device_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
677static uint8_t
678devclass_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
694static const struct module_data *
695devclass_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
710static uint8_t
711devclass_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
738static void
739devclass_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
748static device_t
749make_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	}
782done:
783	return (dev);
784
785error:
786	if (dev) {
787		free(dev, M_DEVBUF);
788	}
789	return (NULL);
790}
791
792device_t
793device_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);
810done:
811	return (child);
812}
813
814int
815device_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
842done:
843	return (error);
844}
845
846int
847device_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
862void
863device_quiet(device_t dev)
864{
865	dev->dev_quiet = 1;
866}
867
868const char *
869device_get_desc(device_t dev)
870{
871	if (dev)
872		return &(dev->dev_desc[0]);
873	return (unknown_string);
874}
875
876static int
877default_method(void)
878{
879	/* do nothing */
880	DPRINTF("Default method called\n");
881	return (0);
882}
883
884void   *
885device_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
899const char *
900device_get_name(device_t dev)
901{
902	if (dev == NULL)
903		return (unknown_string);
904
905	return (dev->dev_module->driver->name);
906}
907
908static int
909device_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
928int
929device_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
987error:
988	return (ENODEV);
989}
990
991int
992device_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
1013void
1014device_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
1024void   *
1025device_get_softc(device_t dev)
1026{
1027	if (dev == NULL)
1028		return (NULL);
1029
1030	return (dev->dev_sc);
1031}
1032
1033int
1034device_is_attached(device_t dev)
1035{
1036	return (dev->dev_attached);
1037}
1038
1039void
1040device_set_desc(device_t dev, const char *desc)
1041{
1042	snprintf(dev->dev_desc, sizeof(dev->dev_desc), "%s", desc);
1043}
1044
1045void
1046device_set_desc_copy(device_t dev, const char *desc)
1047{
1048	device_set_desc(dev, desc);
1049}
1050
1051void   *
1052devclass_get_softc(devclass_t dc, int unit)
1053{
1054	return (device_get_softc(devclass_get_device(dc, unit)));
1055}
1056
1057int
1058devclass_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
1074device_t
1075devclass_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
1081devclass_t
1082devclass_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
1093void
1094module_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
1105static void
1106sysinit_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
1120static int usb_do_process(struct usb_process *);
1121static int usb_proc_level = -1;
1122static struct mtx usb_proc_mtx;
1123
1124void
1125usb_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
1146void
1147usb_init(void)
1148{
1149	sysinit_run(sysinit_data);
1150}
1151
1152void
1153usb_uninit(void)
1154{
1155	sysinit_run(sysuninit_data);
1156}
1157
1158static void
1159usb_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
1169static void
1170usb_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}
1180SYSINIT(usb_process_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, usb_process_init, NULL);
1181
1182static int
1183usb_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
1190repeat:
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
1211void   *
1212usb_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 *------------------------------------------------------------------------*/
1280uint8_t
1281usb_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 *------------------------------------------------------------------------*/
1293void
1294usb_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
1315static device_method_t pci_methods[] = {
1316	DEVMETHOD_END
1317};
1318
1319static driver_t pci_driver = {
1320	.name = "pci",
1321	.methods = pci_methods,
1322};
1323
1324static devclass_t pci_devclass;
1325
1326DRIVER_MODULE(pci, pci, pci_driver, pci_devclass, 0, 0);
1327
1328static 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
1334static device_t usb_pci_dev[USB_PCI_USB_MAX];
1335
1336static void
1337usb_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}
1355SYSINIT(usb_pci_mod_load, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_load, 0);
1356
1357static void
1358usb_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}
1371SYSUNINIT(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
1381static uint8_t usb_pool[USB_POOL_SIZE] __aligned(USB_POOL_ALIGN);
1382static uint32_t usb_pool_rem = USB_POOL_SIZE;
1383static uint32_t usb_pool_entries;
1384
1385struct malloc_hdr {
1386	TAILQ_ENTRY(malloc_hdr) entry;
1387	uint32_t size;
1388} __aligned(USB_POOL_ALIGN);
1389
1390static TAILQ_HEAD(, malloc_hdr) malloc_head =
1391	TAILQ_HEAD_INITIALIZER(malloc_head);
1392
1393void   *
1394usb_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
1430void
1431usb_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
1445char   *
1446usb_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