svn commit: r246145 - in head/sys/boot/usb: . tools

Hans Petter Selasky hselasky at FreeBSD.org
Thu Jan 31 11:00:59 UTC 2013


Author: hselasky
Date: Thu Jan 31 11:00:57 2013
New Revision: 246145
URL: http://svnweb.freebsd.org/changeset/base/246145

Log:
  Initial version of libusbboot, a fully stand-alone, single threaded and
  functional compilation of the FreeBSD USB stack for use with boot loaders
  and such.
  
  Discussed with:		Hiroki Sato, hrs @ EuroBSDCon

Added:
  head/sys/boot/usb/
  head/sys/boot/usb/Makefile   (contents, props changed)
  head/sys/boot/usb/Makefile.test   (contents, props changed)
  head/sys/boot/usb/bsd_busspace.c   (contents, props changed)
  head/sys/boot/usb/bsd_global.h   (contents, props changed)
  head/sys/boot/usb/bsd_kernel.c   (contents, props changed)
  head/sys/boot/usb/bsd_kernel.h   (contents, props changed)
  head/sys/boot/usb/bsd_usbloader_test.c   (contents, props changed)
  head/sys/boot/usb/tools/
  head/sys/boot/usb/tools/sysinit.c   (contents, props changed)
  head/sys/boot/usb/tools/sysinit.h   (contents, props changed)
  head/sys/boot/usb/usb_busdma_loader.c   (contents, props changed)

Added: head/sys/boot/usb/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/usb/Makefile	Thu Jan 31 11:00:57 2013	(r246145)
@@ -0,0 +1,150 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+T=${.CURDIR}/tools
+S=${.CURDIR}/../..
+
+.PATH: \
+	${.CURDIR} \
+	${S}/dev/usb \
+	${S}/dev/usb/controller \
+	${S}/dev/usb/serial \
+	${S}/dev/usb/storage \
+	${S}/dev/usb/template
+
+LIB=		usbboot
+INTERNALLIB=
+OBJCOPY?=	objcopy
+SYSCC?=		cc
+
+CFLAGS+=	-DBOOTPROG=\"usbloader\"
+CFLAGS+=	-DUSB_GLOBAL_INCLUDE_FILE="\"bsd_global.h\""
+CFLAGS+=	-ffunction-sections -fdata-sections
+CFLAGS+=	-ffreestanding
+CFLAGS+=	-Wformat -Wall
+CFLAGS+=	-I ${S}
+CFLAGS+=	-I ${T}
+CFLAGS+=	-I ${.CURDIR}
+CFLAGS+=	-g
+
+.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
+CFLAGS+=	-march=i386
+CFLAGS+=	-mpreferred-stack-boundary=2
+.endif
+.if ${MACHINE_CPUARCH} == "amd64"
+CFLAGS+=	-m32
+.endif
+
+#
+# Single threaded BSD kernel
+#
+SRCS+=	bsd_kernel.c
+
+#
+# BUSSPACE implementation
+#
+SRCS+=	bsd_busspace.c
+
+#
+# BUSDMA implementation
+#
+SRCS+=	usb_busdma_loader.c
+
+#
+# USB controller drivers
+#
+SRCS+=	at91dci.c
+SRCS+=	atmegadci.c
+SRCS+=	avr32dci.c
+SRCS+=	dwc_otg.c
+SRCS+=	ehci.c
+SRCS+=	musb_otg.c
+SRCS+=	ohci.c
+SRCS+=	uhci.c
+SRCS+=	uss820dci.c
+SRCS+=	xhci.c
+SRCS+=	usb_controller.c
+
+CFLAGS += -DUSB_PROBE_LIST="\"xhci\", \"ehci\", \"uhci\", \"ohci\""
+
+#
+# USB core and templates
+#
+SRCS+=	usb_core.c
+SRCS+=	usb_debug.c
+SRCS+=	usb_device.c
+SRCS+=	usb_dynamic.c
+SRCS+=	usb_error.c
+SRCS+=	usb_handle_request.c
+SRCS+=	usb_hid.c
+SRCS+=	usb_hub.c
+SRCS+=	usb_lookup.c
+SRCS+=	usb_msctest.c
+SRCS+=	usb_parse.c
+SRCS+=	usb_request.c
+SRCS+=	usb_transfer.c
+SRCS+=	usb_util.c
+SRCS+=	usb_template.c
+SRCS+=	usb_template_cdce.c
+SRCS+=	usb_template_msc.c
+SRCS+=	usb_template_mtp.c
+SRCS+=	usb_template_modem.c
+SRCS+=	usb_template_mouse.c
+SRCS+=	usb_template_kbd.c
+SRCS+=	usb_template_audio.c
+SRCS+=	sysinit_data.c
+SRCS+=	sysuninit_data.c
+
+CLEANFILES+= sysinit
+CLEANFILES+= sysinit.bin
+CLEANFILES+= sysinit_data.c
+CLEANFILES+= sysuninit_data.c
+
+CLEANFILES+= ${SRCS:C/\.c/.osys/g}
+
+.include <bsd.lib.mk>
+
+#
+# SYSINIT() and SYSUNINIT() handling
+#
+sysinit: ${T}/sysinit.c
+	${SYSCC} -Wall -o ${.TARGET} ${.ALLSRC}
+
+sysinit_data.c: sysinit.bin sysinit
+	${.OBJDIR}/sysinit -i sysinit.bin -o ${.TARGET} -k sysinit -s sysinit_data
+
+sysuninit_data.c: sysinit.bin sysinit
+	${.OBJDIR}/sysinit -i sysinit.bin -o ${.TARGET} -R -k sysuninit -s sysuninit_data
+
+.for F in ${OBJS}
+${F}sys: ${F}
+	${OBJCOPY} -j ".debug.sysinit" -O binary ${F} ${.TARGET}
+	[ -f ${.TARGET} ] || touch ${.TARGET}
+.endfor
+
+sysinit.bin: ${OBJS:C/\.o/.osys/g:C/sysinit_data.osys//g:C/sysuninit_data.osys//g}
+	cat ${.ALLSRC} > sysinit.bin

Added: head/sys/boot/usb/Makefile.test
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/usb/Makefile.test	Thu Jan 31 11:00:57 2013	(r246145)
@@ -0,0 +1,61 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+#
+# USB test application
+#
+
+.PATH: ${.CURDIR}
+
+PROG=	usbloader
+MAN=
+SRCS= 
+
+CFLAGS+= -Wall
+CFLAGS+= -g
+
+.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
+CFLAGS+=	-march=i386
+CFLAGS+=	-mpreferred-stack-boundary=2
+.endif
+.if ${MACHINE_CPUARCH} == "amd64"
+CFLAGS+=	-m32
+.endif
+
+LDFLAGS+= -Wl,--gc-sections
+
+SRCS+=	bsd_usbloader_test.c
+
+LDADD+=	libusbboot.a
+DPADD+= libusbboot.a
+
+all: libusbboot.a
+
+.include <bsd.prog.mk>
+
+libusbboot.a:
+	make -f Makefile

Added: head/sys/boot/usb/bsd_busspace.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/usb/bsd_busspace.c	Thu Jan 31 11:00:57 2013	(r246145)
@@ -0,0 +1,207 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <bsd_kernel.h>
+
+struct burst {
+	uint32_t dw0;
+	uint32_t dw1;
+	uint32_t dw2;
+	uint32_t dw3;
+	uint32_t dw4;
+	uint32_t dw5;
+	uint32_t dw6;
+	uint32_t dw7;
+};
+
+void
+bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t *datap, bus_size_t count)
+{
+	while (count--) {
+		*datap++ = bus_space_read_1(t, h, offset);
+	}
+}
+
+void
+bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint16_t *datap, bus_size_t count)
+{
+	while (count--) {
+		*datap++ = bus_space_read_2(t, h, offset);
+	}
+}
+
+void
+bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t *datap, bus_size_t count)
+{
+	h += offset;
+
+	while (count--) {
+		*datap++ = *((volatile uint32_t *)h);
+	}
+}
+
+void
+bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t *datap, bus_size_t count)
+{
+	while (count--) {
+		uint8_t temp = *datap++;
+
+		bus_space_write_1(t, h, offset, temp);
+	}
+}
+
+void
+bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint16_t *datap, bus_size_t count)
+{
+	while (count--) {
+		uint16_t temp = *datap++;
+
+		bus_space_write_2(t, h, offset, temp);
+	}
+}
+
+void
+bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t *datap, bus_size_t count)
+{
+	h += offset;
+
+	while (count--) {
+		*((volatile uint32_t *)h) = *datap++;
+	}
+}
+
+void
+bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t data)
+{
+	*((volatile uint8_t *)(h + offset)) = data;
+}
+
+void
+bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint16_t data)
+{
+	*((volatile uint16_t *)(h + offset)) = data;
+}
+
+void
+bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t data)
+{
+	*((volatile uint32_t *)(h + offset)) = data;
+}
+
+uint8_t
+bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
+{
+	return (*((volatile uint8_t *)(h + offset)));
+}
+
+uint16_t
+bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
+{
+	return (*((volatile uint16_t *)(h + offset)));
+}
+
+uint32_t
+bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
+{
+	return (*((volatile uint32_t *)(h + offset)));
+}
+
+void
+bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t *datap, bus_size_t count)
+{
+	h += offset;
+
+	while (count--) {
+		*datap++ = *((volatile uint8_t *)h);
+		h += 1;
+	}
+}
+
+void
+bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t *datap, bus_size_t count)
+{
+	h += offset;
+
+	while (count--) {
+		*((volatile uint8_t *)h) = *datap++;
+		h += 1;
+	}
+}
+
+void
+bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t *datap, bus_size_t count)
+{
+	enum { BURST = sizeof(struct burst) / 4 };
+
+	h += offset;
+
+	while (count >= BURST) {
+		*(struct burst *)datap = *((/* volatile */ struct burst *)h);
+
+		h += BURST * 4;
+		datap += BURST;
+		count -= BURST;
+	}
+
+	while (count--) {
+		*datap++ = *((volatile uint32_t *)h);
+		h += 4;
+	}
+}
+
+void
+bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t *datap, bus_size_t count)
+{
+	enum { BURST = sizeof(struct burst) / 4 };
+
+	h += offset;
+
+	while (count >= BURST) {
+		*((/* volatile */ struct burst *)h) = *(struct burst *)datap;
+
+		h += BURST * 4;
+		datap += BURST;
+		count -= BURST;
+	}
+
+	while (count--) {
+		*((volatile uint32_t *)h) = *datap++;
+		h += 4;
+	}
+}

Added: head/sys/boot/usb/bsd_global.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/usb/bsd_global.h	Thu Jan 31 11:00:57 2013	(r246145)
@@ -0,0 +1,63 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BSD_GLOBAL_H_
+#define	_BSD_GLOBAL_H_
+
+#include <bsd_kernel.h>
+
+#define	USB_DEBUG_VAR usb_debug
+#include <dev/usb/usb_freebsd_loader.h>
+#include <dev/usb/usb_endian.h>
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_debug.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_dynamic.h>
+#include <dev/usb/usb_device.h>
+#include <dev/usb/usb_hub.h>
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usb_cdc.h>
+#include <dev/usb/usb_dev.h>
+#include <dev/usb/usb_mbuf.h>
+#include <dev/usb/usb_msctest.h>
+#include <dev/usb/usb_pci.h>
+#include <dev/usb/usb_pf.h>
+#include <dev/usb/usb_request.h>
+#include <dev/usb/usb_util.h>
+#include <dev/usb/usb_transfer.h>
+#include <dev/usb/usb_compat_linux.h>
+#include <dev/usb/usbhid.h>
+#include <dev/usb/usb_ioctl.h>
+#include <dev/usb/usb_generic.h>
+#include <dev/usb/quirk/usb_quirk.h>
+#include <dev/usb/template/usb_template.h>
+
+#endif					/* _BSD_GLOBAL_H_ */

Added: head/sys/boot/usb/bsd_kernel.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/usb/bsd_kernel.c	Thu Jan 31 11:00:57 2013	(r246145)
@@ -0,0 +1,1269 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <bsd_global.h>
+
+static struct usb_process usb_process[USB_PROC_MAX];
+static device_t usb_pci_root;
+
+/*------------------------------------------------------------------------*
+ * Implementation of mutex API
+ *------------------------------------------------------------------------*/
+
+struct mtx Giant;
+
+static void
+mtx_system_init(void *arg)
+{
+	mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
+}
+SYSINIT(mtx_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, mtx_system_init, NULL);
+
+void
+mtx_init(struct mtx *mtx, const char *name, const char *type, int opt)
+{
+	mtx->owned = 0;
+	mtx->parent = mtx;
+}
+
+void
+mtx_lock(struct mtx *mtx)
+{
+	mtx = mtx->parent;
+	mtx->owned++;
+}
+
+void
+mtx_unlock(struct mtx *mtx)
+{
+	mtx = mtx->parent;
+	mtx->owned--;
+}
+
+int
+mtx_owned(struct mtx *mtx)
+{
+	mtx = mtx->parent;
+	return (mtx->owned != 0);
+}
+
+void
+mtx_destroy(struct mtx *mtx)
+{
+	/* NOP */
+}
+
+/*------------------------------------------------------------------------*
+ * Implementation of shared/exclusive mutex API
+ *------------------------------------------------------------------------*/
+
+void
+sx_init_flags(struct sx *sx, const char *name, int flags)
+{
+	sx->owned = 0;
+}
+
+void
+sx_destroy(struct sx *sx)
+{
+	/* NOP */
+}
+
+void
+sx_xlock(struct sx *sx)
+{
+	sx->owned++;
+}
+
+void
+sx_xunlock(struct sx *sx)
+{
+	sx->owned--;
+}
+
+int
+sx_xlocked(struct sx *sx)
+{
+	return (sx->owned != 0);
+}
+
+/*------------------------------------------------------------------------*
+ * Implementaiton of condition variable API
+ *------------------------------------------------------------------------*/
+
+void
+cv_init(struct cv *cv, const char *desc)
+{
+	cv->sleeping = 0;
+}
+
+void
+cv_destroy(struct cv *cv)
+{
+	/* NOP */
+}
+
+void
+cv_wait(struct cv *cv, struct mtx *mtx)
+{
+	cv_timedwait(cv, mtx, -1);
+}
+
+int
+cv_timedwait(struct cv *cv, struct mtx *mtx, int timo)
+{
+	int start = ticks;
+	int delta;
+
+	if (cv->sleeping)
+		return (EWOULDBLOCK);	/* not allowed */
+
+	cv->sleeping = 1;
+
+	while (cv->sleeping) {
+		if (timo >= 0) {
+			delta = ticks - start;
+			if (delta >= timo || delta < 0)
+				break;
+		}
+		mtx_unlock(mtx);
+
+		usb_idle();
+
+		mtx_lock(mtx);
+	}
+
+	if (cv->sleeping) {
+		cv->sleeping = 0;
+		return (EWOULDBLOCK);	/* not allowed */
+	}
+	return (0);
+}
+
+void
+cv_signal(struct cv *cv)
+{
+	cv->sleeping = 0;
+}
+
+void
+cv_broadcast(struct cv *cv)
+{
+	cv->sleeping = 0;
+}
+
+/*------------------------------------------------------------------------*
+ * Implementation of callout API
+ *------------------------------------------------------------------------*/
+
+static void callout_proc_msg(struct usb_proc_msg *);
+
+volatile int ticks = 0;
+
+static LIST_HEAD(, callout) head_callout = LIST_HEAD_INITIALIZER(&head_callout);
+
+static struct mtx mtx_callout;
+static struct usb_proc_msg callout_msg[2];
+
+static void
+callout_system_init(void *arg)
+{
+	mtx_init(&mtx_callout, "callout-mtx", NULL, MTX_DEF | MTX_RECURSE);
+
+	callout_msg[0].pm_callback = &callout_proc_msg;
+	callout_msg[1].pm_callback = &callout_proc_msg;
+}
+SYSINIT(callout_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, callout_system_init, NULL);
+
+static void
+callout_callback(struct callout *c)
+{
+	mtx_lock(c->mtx);
+
+	mtx_lock(&mtx_callout);
+	if (c->entry.le_prev != NULL) {
+		LIST_REMOVE(c, entry);
+		c->entry.le_prev = NULL;
+	}
+	mtx_unlock(&mtx_callout);
+
+	if (c->func)
+		(c->func) (c->arg);
+
+	if (!(c->flags & CALLOUT_RETURNUNLOCKED))
+		mtx_unlock(c->mtx);
+}
+
+void
+callout_process(int timeout)
+{
+	ticks += timeout;
+	usb_proc_msignal(usb_process + 2, &callout_msg[0], &callout_msg[1]);
+}
+
+static void
+callout_proc_msg(struct usb_proc_msg *pmsg)
+{
+	struct callout *c;
+	int delta;
+
+repeat:
+	mtx_lock(&mtx_callout);
+
+	LIST_FOREACH(c, &head_callout, entry) {
+
+		delta = c->timeout - ticks;
+		if (delta < 0) {
+			mtx_unlock(&mtx_callout);
+
+			callout_callback(c);
+
+			goto repeat;
+		}
+	}
+	mtx_unlock(&mtx_callout);
+}
+
+void
+callout_init_mtx(struct callout *c, struct mtx *mtx, int flags)
+{
+	memset(c, 0, sizeof(*c));
+
+	if (mtx == NULL)
+		mtx = &Giant;
+
+	c->mtx = mtx;
+	c->flags = (flags & CALLOUT_RETURNUNLOCKED);
+}
+
+void
+callout_reset(struct callout *c, int to_ticks,
+    void (*func) (void *), void *arg)
+{
+	callout_stop(c);
+
+	c->func = func;
+	c->arg = arg;
+	c->timeout = ticks + to_ticks;
+
+	mtx_lock(&mtx_callout);
+	LIST_INSERT_HEAD(&head_callout, c, entry);
+	mtx_unlock(&mtx_callout);
+}
+
+void
+callout_stop(struct callout *c)
+{
+	mtx_lock(&mtx_callout);
+
+	if (c->entry.le_prev != NULL) {
+		LIST_REMOVE(c, entry);
+		c->entry.le_prev = NULL;
+	}
+	mtx_unlock(&mtx_callout);
+
+	c->func = NULL;
+	c->arg = NULL;
+}
+
+void
+callout_drain(struct callout *c)
+{
+	if (c->mtx == NULL)
+		return;			/* not initialised */
+
+	mtx_lock(c->mtx);
+	callout_stop(c);
+	mtx_unlock(c->mtx);
+}
+
+int
+callout_pending(struct callout *c)
+{
+	int retval;
+
+	mtx_lock(&mtx_callout);
+	retval = (c->entry.le_prev != NULL);
+	mtx_unlock(&mtx_callout);
+
+	return (retval);
+}
+
+/*------------------------------------------------------------------------*
+ * Implementation of device API
+ *------------------------------------------------------------------------*/
+
+static const char unknown_string[] = { "unknown" };
+
+static TAILQ_HEAD(, module_data) module_head =
+    TAILQ_HEAD_INITIALIZER(module_head);
+
+static uint8_t
+devclass_equal(const char *a, const char *b)
+{
+	char ta, tb;
+
+	if (a == b)
+		return (1);
+
+	while (1) {
+		ta = *a;
+		tb = *b;
+		if (ta != tb)
+			return (0);
+		if (ta == 0)
+			break;
+		a++;
+		b++;
+	}
+	return (1);
+}
+
+int
+bus_generic_resume(device_t dev)
+{
+	return (0);
+}
+
+int
+bus_generic_shutdown(device_t dev)
+{
+	return (0);
+}
+
+int
+bus_generic_suspend(device_t dev)
+{
+	return (0);
+}
+
+int
+bus_generic_print_child(device_t dev, device_t child)
+{
+	return (0);
+}
+
+void
+bus_generic_driver_added(device_t dev, driver_t *driver)
+{
+	return;
+}
+
+device_t
+device_get_parent(device_t dev)
+{
+	return (dev ? dev->dev_parent : NULL);
+}
+
+void
+device_set_interrupt(device_t dev, intr_fn_t *fn, void *arg)
+{
+	dev->dev_irq_fn = fn;
+	dev->dev_irq_arg = arg;
+}
+
+void
+device_run_interrupts(device_t parent)
+{
+	device_t child;
+
+	if (parent == NULL)
+		return;
+
+	TAILQ_FOREACH(child, &parent->dev_children, dev_link) {
+		if (child->dev_irq_fn != NULL)
+			(child->dev_irq_fn) (child->dev_irq_arg);
+	}
+}
+
+void
+device_set_ivars(device_t dev, void *ivars)
+{
+	dev->dev_aux = ivars;
+}
+
+void   *
+device_get_ivars(device_t dev)
+{
+	return (dev ? dev->dev_aux : NULL);
+}
+
+int
+device_get_unit(device_t dev)
+{
+	return (dev ? dev->dev_unit : 0);
+}
+
+int
+bus_generic_detach(device_t dev)
+{
+	device_t child;
+	int error;
+
+	if (!dev->dev_attached)
+		return (EBUSY);
+
+	TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
+		if ((error = device_detach(child)) != 0)
+			return (error);
+	}
+	return (0);
+}
+
+const char *
+device_get_nameunit(device_t dev)
+{
+	if (dev && dev->dev_nameunit[0])
+		return (dev->dev_nameunit);
+
+	return (unknown_string);
+}
+
+static uint8_t
+devclass_create(devclass_t *dc_pp)
+{
+	if (dc_pp == NULL) {
+		return (1);
+	}
+	if (dc_pp[0] == NULL) {
+		dc_pp[0] = malloc(sizeof(**(dc_pp)),
+		    M_DEVBUF, M_WAITOK | M_ZERO);
+
+		if (dc_pp[0] == NULL) {
+			return (1);
+		}
+	}
+	return (0);
+}
+
+static const struct module_data *
+devclass_find_create(const char *classname)
+{
+	const struct module_data *mod;
+
+	TAILQ_FOREACH(mod, &module_head, entry) {
+		if (devclass_equal(mod->mod_name, classname)) {
+			if (devclass_create(mod->devclass_pp)) {
+				continue;
+			}
+			return (mod);
+		}
+	}
+	return (NULL);
+}
+
+static uint8_t
+devclass_add_device(const struct module_data *mod, device_t dev)
+{
+	device_t *pp_dev;
+	device_t *end;
+	uint8_t unit;
+
+	pp_dev = mod->devclass_pp[0]->dev_list;
+	end = pp_dev + DEVCLASS_MAXUNIT;
+	unit = 0;
+
+	while (pp_dev != end) {
+		if (*pp_dev == NULL) {
+			*pp_dev = dev;
+			dev->dev_unit = unit;
+			dev->dev_module = mod;
+			snprintf(dev->dev_nameunit,
+			    sizeof(dev->dev_nameunit),
+			    "%s%d", device_get_name(dev), unit);
+			return (0);
+		}
+		pp_dev++;
+		unit++;
+	}
+	DPRINTF("Could not add device to devclass.\n");
+	return (1);
+}

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list