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 ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to