Module Name: src Committed By: pooka Date: Wed Feb 10 02:26:24 UTC 2010
Modified Files: src/sys/rump/dev/wip: Makefile files.rump src/sys/rump/dev/wip/libucom: ucom_at_usb.c src/sys/rump/dev/wip/libukbd: ukbd_at_usb.c src/sys/rump/dev/wip/libulpt: ulpt_at_usb.c src/sys/rump/dev/wip/libumass: sd_at_scsibus_at_umass.c src/sys/rump/dev/wip/libums: ums_at_usb.c src/sys/rump/dev/wip/libusbrum: rum_at_usb.c src/sys/rump/dev/wip/libwscons: component.c Added Files: src/sys/rump/dev/wip/libugenhc: Makefile shlib_version ugenhc.c Removed Files: src/sys/rump/dev/wip/librumpusbhc: Makefile rumpusbhc.c shlib_version Log Message: Rename rumpusbhc to ugenhc, as that better describes what it does. (the full component name is rumpdev_ugenhc) To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/rump/dev/wip/Makefile cvs rdiff -u -r1.1 -r1.2 src/sys/rump/dev/wip/files.rump cvs rdiff -u -r1.2 -r0 src/sys/rump/dev/wip/librumpusbhc/Makefile cvs rdiff -u -r1.15 -r0 src/sys/rump/dev/wip/librumpusbhc/rumpusbhc.c cvs rdiff -u -r1.1 -r0 src/sys/rump/dev/wip/librumpusbhc/shlib_version cvs rdiff -u -r1.3 -r1.4 src/sys/rump/dev/wip/libucom/ucom_at_usb.c cvs rdiff -u -r0 -r1.1 src/sys/rump/dev/wip/libugenhc/Makefile \ src/sys/rump/dev/wip/libugenhc/shlib_version \ src/sys/rump/dev/wip/libugenhc/ugenhc.c cvs rdiff -u -r1.2 -r1.3 src/sys/rump/dev/wip/libukbd/ukbd_at_usb.c cvs rdiff -u -r1.1 -r1.2 src/sys/rump/dev/wip/libulpt/ulpt_at_usb.c cvs rdiff -u -r1.9 -r1.10 \ src/sys/rump/dev/wip/libumass/sd_at_scsibus_at_umass.c cvs rdiff -u -r1.2 -r1.3 src/sys/rump/dev/wip/libums/ums_at_usb.c cvs rdiff -u -r1.2 -r1.3 src/sys/rump/dev/wip/libusbrum/rum_at_usb.c cvs rdiff -u -r1.1 -r1.2 src/sys/rump/dev/wip/libwscons/component.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/rump/dev/wip/Makefile diff -u src/sys/rump/dev/wip/Makefile:1.5 src/sys/rump/dev/wip/Makefile:1.6 --- src/sys/rump/dev/wip/Makefile:1.5 Fri Feb 5 22:01:38 2010 +++ src/sys/rump/dev/wip/Makefile Wed Feb 10 02:26:23 2010 @@ -1,7 +1,7 @@ -# $NetBSD: Makefile,v 1.5 2010/02/05 22:01:38 pooka Exp $ +# $NetBSD: Makefile,v 1.6 2010/02/10 02:26:23 pooka Exp $ # -SUBDIR= librumpusbhc libucom libumass libulpt libusb libusbrum +SUBDIR= libugenhc libucom libumass libulpt libusb libusbrum SUBDIR+=libums libukbd SUBDIR+=libwscons Index: src/sys/rump/dev/wip/files.rump diff -u src/sys/rump/dev/wip/files.rump:1.1 src/sys/rump/dev/wip/files.rump:1.2 --- src/sys/rump/dev/wip/files.rump:1.1 Thu Feb 4 00:37:08 2010 +++ src/sys/rump/dev/wip/files.rump Wed Feb 10 02:26:23 2010 @@ -1,20 +1,20 @@ -# $NetBSD: files.rump,v 1.1 2010/02/04 00:37:08 pooka Exp $ +# $NetBSD: files.rump,v 1.2 2010/02/10 02:26:23 pooka Exp $ # device mainbus { } attach mainbus at root -device rumpusbhc: usbus, usbroothub -attach rumpusbhc at mainbus +device ugenhc: usbus, usbroothub +attach ugenhc at mainbus # ugen0 - ugen3 mainbus0 at root -rumpusbhc0 at mainbus0 -rumpusbhc1 at mainbus0 -rumpusbhc2 at mainbus0 -rumpusbhc3 at mainbus0 +ugenhc0 at mainbus0 +ugenhc1 at mainbus0 +ugenhc2 at mainbus0 +ugenhc3 at mainbus0 # USB bus support -usb* at rumpusbhc? +usb* at ugenhc? # USB ROOT Hub # Index: src/sys/rump/dev/wip/libucom/ucom_at_usb.c diff -u src/sys/rump/dev/wip/libucom/ucom_at_usb.c:1.3 src/sys/rump/dev/wip/libucom/ucom_at_usb.c:1.4 --- src/sys/rump/dev/wip/libucom/ucom_at_usb.c:1.3 Wed Feb 3 21:18:38 2010 +++ src/sys/rump/dev/wip/libucom/ucom_at_usb.c Wed Feb 10 02:26:23 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: ucom_at_usb.c,v 1.3 2010/02/03 21:18:38 pooka Exp $ */ +/* $NetBSD: ucom_at_usb.c,v 1.4 2010/02/10 02:26:23 pooka Exp $ */ #include <sys/param.h> #include <sys/types.h> @@ -32,8 +32,8 @@ FLAWLESSCALL(config_cfdriver_attach(&mainbus_cd)); FLAWLESSCALL(config_cfattach_attach("mainbus", &mainbus_ca)); - FLAWLESSCALL(config_cfdriver_attach(&rumpusbhc_cd)); - FLAWLESSCALL(config_cfattach_attach("rumpusbhc", &rumpusbhc_ca)); + FLAWLESSCALL(config_cfdriver_attach(&ugenhc_cd)); + FLAWLESSCALL(config_cfattach_attach("ugenhc", &ugenhc_ca)); FLAWLESSCALL(config_cfdriver_attach(&usb_cd)); FLAWLESSCALL(config_cfattach_attach("usb", &usb_ca)); Index: src/sys/rump/dev/wip/libukbd/ukbd_at_usb.c diff -u src/sys/rump/dev/wip/libukbd/ukbd_at_usb.c:1.2 src/sys/rump/dev/wip/libukbd/ukbd_at_usb.c:1.3 --- src/sys/rump/dev/wip/libukbd/ukbd_at_usb.c:1.2 Wed Feb 3 21:18:38 2010 +++ src/sys/rump/dev/wip/libukbd/ukbd_at_usb.c Wed Feb 10 02:26:23 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: ukbd_at_usb.c,v 1.2 2010/02/03 21:18:38 pooka Exp $ */ +/* $NetBSD: ukbd_at_usb.c,v 1.3 2010/02/10 02:26:23 pooka Exp $ */ #include <sys/param.h> #include <sys/conf.h> @@ -28,8 +28,8 @@ FLAWLESSCALL(config_cfdriver_attach(&mainbus_cd)); FLAWLESSCALL(config_cfattach_attach("mainbus", &mainbus_ca)); - FLAWLESSCALL(config_cfdriver_attach(&rumpusbhc_cd)); - FLAWLESSCALL(config_cfattach_attach("rumpusbhc", &rumpusbhc_ca)); + FLAWLESSCALL(config_cfdriver_attach(&ugenhc_cd)); + FLAWLESSCALL(config_cfattach_attach("ugenhc", &ugenhc_ca)); FLAWLESSCALL(config_cfdriver_attach(&usb_cd)); FLAWLESSCALL(config_cfattach_attach("usb", &usb_ca)); Index: src/sys/rump/dev/wip/libulpt/ulpt_at_usb.c diff -u src/sys/rump/dev/wip/libulpt/ulpt_at_usb.c:1.1 src/sys/rump/dev/wip/libulpt/ulpt_at_usb.c:1.2 --- src/sys/rump/dev/wip/libulpt/ulpt_at_usb.c:1.1 Tue Dec 15 15:52:30 2009 +++ src/sys/rump/dev/wip/libulpt/ulpt_at_usb.c Wed Feb 10 02:26:23 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: ulpt_at_usb.c,v 1.1 2009/12/15 15:52:30 pooka Exp $ */ +/* $NetBSD: ulpt_at_usb.c,v 1.2 2010/02/10 02:26:23 pooka Exp $ */ /* * MACHINE GENERATED: DO NOT EDIT @@ -347,15 +347,10 @@ CFDRIVER_DECL(ulpt, DV_DULL, NULL); -static const struct cfiattrdata * const rumpusbhc_attrs[] = { &usbuscf_iattrdata, NULL }; -CFDRIVER_DECL(rumpusbhc, DV_DULL, rumpusbhc_attrs); - - extern struct cfattach usb_ca; extern struct cfattach uroothub_ca; extern struct cfattach ulpt_ca; -extern struct cfattach rumpusbhc_ca; /* locators */ static int loc[6] = { Index: src/sys/rump/dev/wip/libumass/sd_at_scsibus_at_umass.c diff -u src/sys/rump/dev/wip/libumass/sd_at_scsibus_at_umass.c:1.9 src/sys/rump/dev/wip/libumass/sd_at_scsibus_at_umass.c:1.10 --- src/sys/rump/dev/wip/libumass/sd_at_scsibus_at_umass.c:1.9 Wed Feb 10 02:08:34 2010 +++ src/sys/rump/dev/wip/libumass/sd_at_scsibus_at_umass.c Wed Feb 10 02:26:24 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: sd_at_scsibus_at_umass.c,v 1.9 2010/02/10 02:08:34 pooka Exp $ */ +/* $NetBSD: sd_at_scsibus_at_umass.c,v 1.10 2010/02/10 02:26:24 pooka Exp $ */ #include <sys/param.h> #include <sys/conf.h> @@ -21,7 +21,7 @@ void rump_device_configuration(void) { - extern struct cfattach rumpusbhc_ca; + extern struct cfattach ugenhc_ca; extern struct cfattach usb_ca, uhub_ca, uroothub_ca, umass_ca; extern struct cfattach scsibus_ca, atapibus_ca, sd_ca, cd_ca; extern struct bdevsw sd_bdevsw, cd_bdevsw; @@ -33,8 +33,8 @@ FLAWLESSCALL(config_cfdriver_attach(&mainbus_cd)); FLAWLESSCALL(config_cfattach_attach("mainbus", &mainbus_ca)); - FLAWLESSCALL(config_cfdriver_attach(&rumpusbhc_cd)); - FLAWLESSCALL(config_cfattach_attach("rumpusbhc", &rumpusbhc_ca)); + FLAWLESSCALL(config_cfdriver_attach(&ugenhc_cd)); + FLAWLESSCALL(config_cfattach_attach("ugenhc", &ugenhc_ca)); FLAWLESSCALL(config_cfdriver_attach(&usb_cd)); FLAWLESSCALL(config_cfattach_attach("usb", &usb_ca)); Index: src/sys/rump/dev/wip/libums/ums_at_usb.c diff -u src/sys/rump/dev/wip/libums/ums_at_usb.c:1.2 src/sys/rump/dev/wip/libums/ums_at_usb.c:1.3 --- src/sys/rump/dev/wip/libums/ums_at_usb.c:1.2 Wed Feb 3 21:18:38 2010 +++ src/sys/rump/dev/wip/libums/ums_at_usb.c Wed Feb 10 02:26:24 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: ums_at_usb.c,v 1.2 2010/02/03 21:18:38 pooka Exp $ */ +/* $NetBSD: ums_at_usb.c,v 1.3 2010/02/10 02:26:24 pooka Exp $ */ #include <sys/param.h> #include <sys/conf.h> @@ -26,8 +26,8 @@ FLAWLESSCALL(config_cfdriver_attach(&mainbus_cd)); FLAWLESSCALL(config_cfattach_attach("mainbus", &mainbus_ca)); - FLAWLESSCALL(config_cfdriver_attach(&rumpusbhc_cd)); - FLAWLESSCALL(config_cfattach_attach("rumpusbhc", &rumpusbhc_ca)); + FLAWLESSCALL(config_cfdriver_attach(&ugenhc_cd)); + FLAWLESSCALL(config_cfattach_attach("ugenhc", &ugenhc_ca)); FLAWLESSCALL(config_cfdriver_attach(&usb_cd)); FLAWLESSCALL(config_cfattach_attach("usb", &usb_ca)); Index: src/sys/rump/dev/wip/libusbrum/rum_at_usb.c diff -u src/sys/rump/dev/wip/libusbrum/rum_at_usb.c:1.2 src/sys/rump/dev/wip/libusbrum/rum_at_usb.c:1.3 --- src/sys/rump/dev/wip/libusbrum/rum_at_usb.c:1.2 Wed Feb 3 21:18:38 2010 +++ src/sys/rump/dev/wip/libusbrum/rum_at_usb.c Wed Feb 10 02:26:24 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: rum_at_usb.c,v 1.2 2010/02/03 21:18:38 pooka Exp $ */ +/* $NetBSD: rum_at_usb.c,v 1.3 2010/02/10 02:26:24 pooka Exp $ */ #include <sys/param.h> #include <sys/types.h> @@ -45,14 +45,14 @@ CFDRIVER_DECL(rum, DV_IFNET, NULL); -struct cfparent rumpusbhc_pspec = { +struct cfparent ugenhc_pspec = { "usbus", - "rumpusbhc", + "ugenhc", DVUNIT_ANY }; struct cfdata usb_cfdata[] = { - { "usb", "usb", 0, FSTATE_STAR, NULL, 0, &rumpusbhc_pspec }, + { "usb", "usb", 0, FSTATE_STAR, NULL, 0, &ugenhc_pspec }, }; struct cfparent usb_pspec = { Index: src/sys/rump/dev/wip/libwscons/component.c diff -u src/sys/rump/dev/wip/libwscons/component.c:1.1 src/sys/rump/dev/wip/libwscons/component.c:1.2 --- src/sys/rump/dev/wip/libwscons/component.c:1.1 Mon Jan 11 02:12:51 2010 +++ src/sys/rump/dev/wip/libwscons/component.c Wed Feb 10 02:26:24 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: component.c,v 1.1 2010/01/11 02:12:51 pooka Exp $ */ +/* $NetBSD: component.c,v 1.2 2010/02/10 02:26:24 pooka Exp $ */ /* * MACHINE GENERATED: DO NOT EDIT @@ -380,9 +380,6 @@ static const struct cfiattrdata * const mainbus_attrs[] = { &mainbuscf_iattrdata, NULL }; CFDRIVER_DECL(mainbus, DV_DULL, mainbus_attrs); -static const struct cfiattrdata * const rumpusbhc_attrs[] = { &usbuscf_iattrdata, NULL }; -CFDRIVER_DECL(rumpusbhc, DV_DULL, rumpusbhc_attrs); - extern struct cfattach wskbd_ca; @@ -395,7 +392,6 @@ extern struct cfattach ukbd_ca; extern struct cfattach ums_ca; extern struct cfattach mainbus_ca; -extern struct cfattach rumpusbhc_ca; /* locators */ static int loc[18] = { Added files: Index: src/sys/rump/dev/wip/libugenhc/Makefile diff -u /dev/null src/sys/rump/dev/wip/libugenhc/Makefile:1.1 --- /dev/null Wed Feb 10 02:26:24 2010 +++ src/sys/rump/dev/wip/libugenhc/Makefile Wed Feb 10 02:26:23 2010 @@ -0,0 +1,11 @@ +# $NetBSD: Makefile,v 1.1 2010/02/10 02:26:23 pooka Exp $ +# + +LIB= rumpdev_ugenhc + +SRCS= ugenhc.c + +CPPFLAGS+= -I${RUMPTOP}/librump/rumpkern + +.include <bsd.lib.mk> +.include <bsd.klinks.mk> Index: src/sys/rump/dev/wip/libugenhc/shlib_version diff -u /dev/null src/sys/rump/dev/wip/libugenhc/shlib_version:1.1 --- /dev/null Wed Feb 10 02:26:24 2010 +++ src/sys/rump/dev/wip/libugenhc/shlib_version Wed Feb 10 02:26:23 2010 @@ -0,0 +1,4 @@ +# $NetBSD: shlib_version,v 1.1 2010/02/10 02:26:23 pooka Exp $ +# +major=0 +minor=0 Index: src/sys/rump/dev/wip/libugenhc/ugenhc.c diff -u /dev/null src/sys/rump/dev/wip/libugenhc/ugenhc.c:1.1 --- /dev/null Wed Feb 10 02:26:24 2010 +++ src/sys/rump/dev/wip/libugenhc/ugenhc.c Wed Feb 10 02:26:23 2010 @@ -0,0 +1,995 @@ +/* $NetBSD: ugenhc.c,v 1.1 2010/02/10 02:26:23 pooka Exp $ */ + +/* + * Copyright (c) 2009 Antti Kantee. 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 ``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. + */ + +/* + * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lenn...@augustsson.net) at + * Carlstedt Research & Technology. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * This rump driver attaches ugen as a kernel usb host controller. + * It's still somewhat under the hammer .... + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: ugenhc.c,v 1.1 2010/02/10 02:26:23 pooka Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/conf.h> +#include <sys/device.h> +#include <sys/fcntl.h> +#include <sys/kmem.h> +#include <sys/kernel.h> +#include <sys/kthread.h> + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> +#include <dev/usb/usbhid.h> +#include <dev/usb/usbdivar.h> +#include <dev/usb/usb_mem.h> +#include <dev/usb/usbroothub_subr.h> + +#include <rump/rumpuser.h> + +#include "rump_private.h" +#include "rump_dev_private.h" + +#define UGEN_NEPTS 16 +#define UGEN_EPT_CTRL 0 /* ugenx.00 is the control endpoint */ + +struct ugenhc_softc { + struct usbd_bus sc_bus; + int sc_devnum; + + int sc_ugenfd[UGEN_NEPTS]; + int sc_fdmodes[UGEN_NEPTS]; + + int sc_port_status; + int sc_port_change; + int sc_addr; + int sc_conf; +}; + +static int ugenhc_probe(struct device *, struct cfdata *, void *); +static void ugenhc_attach(struct device *, struct device *, void *); + +CFATTACH_DECL_NEW(ugenhc, sizeof(struct ugenhc_softc), + ugenhc_probe, ugenhc_attach, NULL, NULL); + +struct rusb_xfer { + struct usbd_xfer rusb_xfer; + int rusb_status; /* now this is a cheap trick */ +}; +#define RUSB(x) ((struct rusb_xfer *)x) + +#define UGENDEV_BASESTR "/dev/ugen" +#define UGENDEV_BUFSIZE 32 +static void +makeugendevstr(int devnum, int endpoint, char *buf) +{ + + CTASSERT(UGENDEV_BUFSIZE > sizeof(UGENDEV_BASESTR)+sizeof("0.00")+1); + sprintf(buf, "%s%d.%02d", UGENDEV_BASESTR, devnum, endpoint); +} + +/* + * Our fictional hubbie. + */ + +static const usb_device_descriptor_t rumphub_udd = { + .bLength = USB_DEVICE_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_DEVICE, + .bDeviceClass = UDCLASS_HUB, + .bDeviceSubClass = UDSUBCLASS_HUB, + .bDeviceProtocol = UDPROTO_FSHUB, + .bMaxPacketSize = 64, + .bNumConfigurations = 1, +}; + +static const usb_config_descriptor_t rumphub_ucd = { + .bLength = USB_CONFIG_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_CONFIG, + .wTotalLength = { USB_CONFIG_DESCRIPTOR_SIZE + + USB_INTERFACE_DESCRIPTOR_SIZE + + USB_ENDPOINT_DESCRIPTOR_SIZE }, + .bNumInterface = 1, + .bmAttributes = UC_SELF_POWERED | UC_ATTR_MBO, +}; +/* XXX: spec says UC_ATTR_MBO is reserved and set to one. required? */ + +static const usb_interface_descriptor_t rumphub_uid = { + .bLength = USB_INTERFACE_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 1, + .bInterfaceClass = UICLASS_HUB, + .bInterfaceSubClass = UISUBCLASS_HUB, + .bInterfaceProtocol = UIPROTO_FSHUB, +}; + +static const usb_endpoint_descriptor_t rumphub_epd = { + .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_ENDPOINT, + .bmAttributes = UE_INTERRUPT, + .wMaxPacketSize = {64, 0}, +}; + +static const usb_hub_descriptor_t rumphub_hdd = { + .bDescLength = USB_HUB_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_HUB, + .bNbrPorts = 1, +}; + +static usbd_status +rumpusb_root_ctrl_start(usbd_xfer_handle xfer) +{ + usb_device_request_t *req = &xfer->request; + struct ugenhc_softc *sc = xfer->pipe->device->bus->hci_private; + int len, totlen, value, curlen, err; + uint8_t *buf = NULL; + + len = totlen = UGETW(req->wLength); + if (len) + buf = KERNADDR(&xfer->dmabuf, 0); + value = UGETW(req->wValue); + +#define C(x,y) ((x) | ((y) << 8)) + switch(C(req->bRequest, req->bmRequestType)) { + + case C(UR_GET_CONFIG, UT_READ_DEVICE): + if (len > 0) { + *buf = sc->sc_conf; + totlen = 1; + } + break; + + case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): + switch (value >> 8) { + case UDESC_DEVICE: + totlen = min(len, USB_DEVICE_DESCRIPTOR_SIZE); + memcpy(buf, &rumphub_udd, totlen); + break; + + case UDESC_CONFIG: + totlen = 0; + curlen = min(len, USB_CONFIG_DESCRIPTOR_SIZE); + memcpy(buf, &rumphub_ucd, curlen); + len -= curlen; + buf += curlen; + totlen += curlen; + + curlen = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); + memcpy(buf, &rumphub_uid, curlen); + len -= curlen; + buf += curlen; + totlen += curlen; + + curlen = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); + memcpy(buf, &rumphub_epd, curlen); + len -= curlen; + buf += curlen; + totlen += curlen; + break; + + case UDESC_STRING: +#define sd ((usb_string_descriptor_t *)buf) + switch (value & 0xff) { + case 0: /* Language table */ + totlen = usb_makelangtbl(sd, len); + break; + case 1: /* Vendor */ + totlen = usb_makestrdesc(sd, len, "rod nevada"); + break; + case 2: /* Product */ + totlen = usb_makestrdesc(sd, len, + "RUMPUSBHC root hub"); + break; + } +#undef sd + break; + + default: + panic("unhandled read device request"); + break; + } + break; + + case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): + if (value >= USB_MAX_DEVICES) { + err = USBD_IOERROR; + goto ret; + } + sc->sc_addr = value; + break; + + case C(UR_SET_CONFIG, UT_WRITE_DEVICE): + if (value != 0 && value != 1) { + err = USBD_IOERROR; + goto ret; + } + sc->sc_conf = value; + break; + + case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): + switch (value) { + case UHF_PORT_RESET: + sc->sc_port_change |= UPS_C_PORT_RESET; + break; + case UHF_PORT_POWER: + break; + default: + panic("unhandled"); + } + break; + + case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): + sc->sc_port_change &= ~value; + break; + + case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): + totlen = min(len, USB_HUB_DESCRIPTOR_SIZE); + memcpy(buf, &rumphub_hdd, totlen); + break; + + case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): + /* huh? other hc's do this */ + memset(buf, 0, len); + totlen = len; + break; + + case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): + { + usb_port_status_t ps; + + USETW(ps.wPortStatus, sc->sc_port_status); + USETW(ps.wPortChange, sc->sc_port_change); + totlen = min(len, sizeof(ps)); + memcpy(buf, &ps, totlen); + break; + } + + default: + panic("unhandled request"); + break; + } + err = USBD_NORMAL_COMPLETION; + xfer->actlen = totlen; + +ret: + xfer->status = err; + usb_transfer_complete(xfer); + return (USBD_IN_PROGRESS); +} + +static usbd_status +rumpusb_root_ctrl_transfer(usbd_xfer_handle xfer) +{ + usbd_status err; + + err = usb_insert_transfer(xfer); + if (err) + return (err); + + return (rumpusb_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); +} + +static void +rumpusb_root_ctrl_abort(usbd_xfer_handle xfer) +{ + +} + +static void +rumpusb_root_ctrl_close(usbd_pipe_handle pipe) +{ + +} + +static void +rumpusb_root_ctrl_cleartoggle(usbd_pipe_handle pipe) +{ + +} + +static void +rumpusb_root_ctrl_done(usbd_xfer_handle xfer) +{ + +} + +static const struct usbd_pipe_methods rumpusb_root_ctrl_methods = { + .transfer = rumpusb_root_ctrl_transfer, + .start = rumpusb_root_ctrl_start, + .abort = rumpusb_root_ctrl_abort, + .close = rumpusb_root_ctrl_close, + .cleartoggle = rumpusb_root_ctrl_cleartoggle, + .done = rumpusb_root_ctrl_done, +}; + +static usbd_status +rumpusb_device_ctrl_start(usbd_xfer_handle xfer) +{ + usb_device_request_t *req = &xfer->request; + struct ugenhc_softc *sc = xfer->pipe->device->bus->hci_private; + uint8_t *buf = NULL; + int len, totlen; + int value; + int err = 0; + int ru_error, mightfail = 0; + + len = totlen = UGETW(req->wLength); + if (len) + buf = KERNADDR(&xfer->dmabuf, 0); + value = UGETW(req->wValue); + +#define C(x,y) ((x) | ((y) << 8)) + switch(C(req->bRequest, req->bmRequestType)) { + case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): + switch (value>>8) { + case UDESC_DEVICE: + { + usb_device_descriptor_t uddesc; + totlen = min(len, USB_DEVICE_DESCRIPTOR_SIZE); + memset(buf, 0, totlen); + if (rumpuser_ioctl(sc->sc_ugenfd[UGEN_EPT_CTRL], + USB_GET_DEVICE_DESC, &uddesc, &ru_error) == -1) + panic("%d", ru_error); + memcpy(buf, &uddesc, totlen); + } + + break; + case UDESC_CONFIG: + { + struct usb_full_desc ufdesc; + ufdesc.ufd_config_index = 0; + ufdesc.ufd_size = len; + ufdesc.ufd_data = buf; + memset(buf, 0, totlen); + if (rumpuser_ioctl(sc->sc_ugenfd[UGEN_EPT_CTRL], + USB_GET_FULL_DESC, &ufdesc, &ru_error) == -1) + panic("%d", ru_error); + totlen = len; + } + break; + + case UDESC_STRING: + { + struct usb_device_info udi; + + if (rumpuser_ioctl(sc->sc_ugenfd[UGEN_EPT_CTRL], + USB_GET_DEVICEINFO, &udi, &ru_error) == -1) { + printf("ugenhc: get dev info failed: %d\n", + ru_error); + err = USBD_IOERROR; + goto ret; + } + + switch (value & 0xff) { +#define sd ((usb_string_descriptor_t *)buf) + case 0: /* language table */ + break; + case 1: /* vendor */ + totlen = usb_makestrdesc(sd, len, + udi.udi_vendor); + break; + case 2: /* product */ + totlen = usb_makestrdesc(sd, len, + udi.udi_product); + break; + } +#undef sd + } + break; + + default: + panic("not handled"); + } + break; + + case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): + /* ignored, ugen won't let us */ + break; + + case C(UR_SET_CONFIG, UT_WRITE_DEVICE): + /* ignored, ugen won't let us .... REALLY? */ + break; + + case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): + { + struct usb_alt_interface uai; + + totlen = 0; + uai.uai_interface_index = UGETW(req->wIndex); + uai.uai_alt_no = value; + if (rumpuser_ioctl(sc->sc_ugenfd[UGEN_EPT_CTRL], + USB_SET_ALTINTERFACE, &uai, &ru_error) == -1) { + printf("ugenhc: set alt interface failed: %d\n", + ru_error); + err = USBD_IOERROR; + goto ret; + } + break; + } + + /* + * This request might fail unknown reasons. "EIO" doesn't + * give much help, and debugging the host ugen would be + * necessary. However, since it doesn't seem to really + * affect anything, just let it fail for now. + */ + case C(0x00, UT_WRITE_CLASS_INTERFACE): + mightfail = 1; + /*FALLTHROUGH*/ + + /* + * XXX: don't wildcard these yet. I want to better figure + * out what to trap here. This is kinda silly, though ... + */ + + case C(0x01, UT_WRITE_VENDOR_DEVICE): + case C(0x06, UT_WRITE_VENDOR_DEVICE): + case C(0x07, UT_READ_VENDOR_DEVICE): + case C(0x09, UT_READ_VENDOR_DEVICE): + case C(0xfe, UT_READ_CLASS_INTERFACE): + case C(0x01, UT_READ_CLASS_INTERFACE): + case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): + case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): + case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): + case C(UR_GET_DESCRIPTOR, UT_READ_INTERFACE): + case C(0xff, UT_WRITE_CLASS_INTERFACE): + case C(0x20, UT_WRITE_CLASS_INTERFACE): + case C(0x22, UT_WRITE_CLASS_INTERFACE): + case C(0x0a, UT_WRITE_CLASS_INTERFACE): + case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): + case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): + case C(UR_SET_REPORT, UT_WRITE_CLASS_INTERFACE): + case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): + { + struct usb_ctl_request ucr; + + memcpy(&ucr.ucr_request, req, sizeof(ucr.ucr_request)); + ucr.ucr_data = buf; + if (rumpuser_ioctl(sc->sc_ugenfd[UGEN_EPT_CTRL], + USB_DO_REQUEST, &ucr, &ru_error) == -1) { + if (!mightfail) + panic("request failed: %d", ru_error); + else + err = ru_error; + } + } + break; + + default: + panic("unhandled request"); + break; + } + xfer->actlen = totlen; + err = USBD_NORMAL_COMPLETION; + + ret: + xfer->status = err; + usb_transfer_complete(xfer); + return (USBD_IN_PROGRESS); +} + +static usbd_status +rumpusb_device_ctrl_transfer(usbd_xfer_handle xfer) +{ + usbd_status err; + + err = usb_insert_transfer(xfer); + if (err) + return (err); + + return (rumpusb_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); +} + +static void +rumpusb_device_ctrl_abort(usbd_xfer_handle xfer) +{ + +} + +static void +rumpusb_device_ctrl_close(usbd_pipe_handle pipe) +{ + +} + +static void +rumpusb_device_ctrl_cleartoggle(usbd_pipe_handle pipe) +{ + +} + +static void +rumpusb_device_ctrl_done(usbd_xfer_handle xfer) +{ + +} + +static const struct usbd_pipe_methods rumpusb_device_ctrl_methods = { + .transfer = rumpusb_device_ctrl_transfer, + .start = rumpusb_device_ctrl_start, + .abort = rumpusb_device_ctrl_abort, + .close = rumpusb_device_ctrl_close, + .cleartoggle = rumpusb_device_ctrl_cleartoggle, + .done = rumpusb_device_ctrl_done, +}; + +struct intrent { + usbd_xfer_handle xfer; + LIST_ENTRY(intrent) entries; +}; + +static LIST_HEAD(, intrent) intrlist = LIST_HEAD_INITIALIZER(intrlist); + +static void +rhscintr(void) +{ + struct intrent *ie, *ie_next; + usbd_xfer_handle xfer; + + for (ie = LIST_FIRST(&intrlist); ie; ie = ie_next) { + xfer = ie->xfer; + xfer->actlen = xfer->length; + xfer->status = USBD_NORMAL_COMPLETION; + usb_transfer_complete(xfer); + + ie_next = LIST_NEXT(ie, entries); + LIST_REMOVE(ie, entries); + kmem_free(ie, sizeof(*ie)); + } +} + +static usbd_status +rumpusb_root_intr_start(usbd_xfer_handle xfer) +{ + struct intrent *ie; + + ie = kmem_alloc(sizeof(*ie), KM_SLEEP); + ie->xfer = xfer; + LIST_INSERT_HEAD(&intrlist, ie, entries); + + return (USBD_IN_PROGRESS); +} + +static usbd_status +rumpusb_root_intr_transfer(usbd_xfer_handle xfer) +{ + usbd_status err; + + err = usb_insert_transfer(xfer); + if (err) + return (err); + + return (rumpusb_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); +} + +static void +rumpusb_root_intr_abort(usbd_xfer_handle xfer) +{ + +} + +static void +rumpusb_root_intr_close(usbd_pipe_handle pipe) +{ + +} + +static void +rumpusb_root_intr_cleartoggle(usbd_pipe_handle pipe) +{ + +} + +static void +rumpusb_root_intr_done(usbd_xfer_handle xfer) +{ + +} + +static const struct usbd_pipe_methods rumpusb_root_intr_methods = { + .transfer = rumpusb_root_intr_transfer, + .start = rumpusb_root_intr_start, + .abort = rumpusb_root_intr_abort, + .close = rumpusb_root_intr_close, + .cleartoggle = rumpusb_root_intr_cleartoggle, + .done = rumpusb_root_intr_done, +}; + +static usbd_status +rumpusb_device_bulk_start(usbd_xfer_handle xfer) +{ + struct ugenhc_softc *sc = xfer->pipe->device->bus->hci_private; + ssize_t n; + ssize_t done; + bool isread; + int len, error, endpt; + uint8_t *buf; + int xfererr = 0; + int val; + + endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; + isread = UE_GET_DIR(endpt) == UE_DIR_IN; + endpt = UE_GET_ADDR(endpt); + KASSERT(endpt < UGEN_NEPTS); + + KASSERT(xfer->length); + len = xfer->length; + buf = KERNADDR(&xfer->dmabuf, 0); + done = 0; + + while (RUSB(xfer)->rusb_status == 0) { + if (isread) { + if (xfer->flags & USBD_SHORT_XFER_OK) + val = 1; + else + val = 0; + rumpuser_ioctl(sc->sc_ugenfd[endpt], + USB_SET_SHORT_XFER, &val, &error); + n = rumpuser_read(sc->sc_ugenfd[endpt], + buf+done, len-done, &error); + if (n == -1) { + if (error == ETIMEDOUT) + continue; + n = 0; + xfer->status = USBD_IOERROR; + goto out; + } + done += n; + if (done == len) + break; + } else { + n = rumpuser_write(sc->sc_ugenfd[endpt], + buf, len, &error); + done = n; + if (done == len) + break; + else + panic("short write"); + } + + if (xfer->flags & USBD_SHORT_XFER_OK) + break; + } + + if (RUSB(xfer)->rusb_status == 0) { + xfer->actlen = done; + xfer->status = USBD_NORMAL_COMPLETION; + /* override */ + if (xfererr) { + printf("err!\n"); + xfer->status = xfererr; + } + } else { + xfer->status = USBD_CANCELLED; + RUSB(xfer)->rusb_status = 2; + } + out: + val = 0; + rumpuser_ioctl(sc->sc_ugenfd[endpt], USB_SET_SHORT_XFER, &val, &error); + usb_transfer_complete(xfer); + return (USBD_IN_PROGRESS); +} + +static void +doxfer_kth(void *arg) +{ + usbd_xfer_handle xfer = arg; + + do { + rumpusb_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); + } while (!SIMPLEQ_EMPTY(&xfer->pipe->queue)); + kthread_exit(0); +} + +static usbd_status +rumpusb_device_bulk_transfer(usbd_xfer_handle xfer) +{ + usbd_status err; + + if (!rump_threads) { + /* XXX: lie about supporting async transfers */ + if ((xfer->flags & USBD_SYNCHRONOUS) == 0) { + printf("non-threaded rump does not support " + "async transfers.\n"); + return USBD_IN_PROGRESS; + } + + err = usb_insert_transfer(xfer); + if (err) + return err; + + return rumpusb_device_bulk_start( + SIMPLEQ_FIRST(&xfer->pipe->queue)); + } else { + /* biglocked */ + err = usb_insert_transfer(xfer); + if (err) + return err; + kthread_create(PRI_NONE, 0, NULL, doxfer_kth, xfer, NULL, + "rusbhcxf"); + + return USBD_IN_PROGRESS; + } +} + +/* wait for transfer to abort. yea, this is cheesy (from a spray can) */ +static void +rumpusb_device_bulk_abort(usbd_xfer_handle xfer) +{ + struct rusb_xfer *rx = RUSB(xfer); + + rx->rusb_status = 1; + while (rx->rusb_status < 2) { + kpause("jopo", false, hz/10, NULL); + } +} + +static void +rumpusb_device_bulk_close(usbd_pipe_handle pipe) +{ + +} + +static void +rumpusb_device_bulk_cleartoggle(usbd_pipe_handle pipe) +{ + +} + +static void +rumpusb_device_bulk_done(usbd_xfer_handle xfer) +{ + +} + +static const struct usbd_pipe_methods rumpusb_device_bulk_methods = { + .transfer = rumpusb_device_bulk_transfer, + .start = rumpusb_device_bulk_start, + .abort = rumpusb_device_bulk_abort, + .close = rumpusb_device_bulk_close, + .cleartoggle = rumpusb_device_bulk_cleartoggle, + .done = rumpusb_device_bulk_done, +}; + +static const struct usbd_pipe_methods rumpusb_device_intr_methods = { + .transfer = rumpusb_root_intr_transfer, + .start = rumpusb_root_intr_start, + .abort = rumpusb_root_intr_abort, + .close = rumpusb_root_intr_close, + .cleartoggle = rumpusb_root_intr_cleartoggle, + .done = rumpusb_root_intr_done, +}; + +static usbd_status +ugenhc_open(struct usbd_pipe *pipe) +{ + usbd_device_handle dev = pipe->device; + struct ugenhc_softc *sc = dev->bus->hci_private; + usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; + u_int8_t addr = dev->address; + u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE; + char buf[UGENDEV_BUFSIZE]; + int endpt, oflags, error; + int fd, val; + + sc->sc_port_status = UPS_CURRENT_CONNECT_STATUS + | UPS_PORT_ENABLED | UPS_PORT_POWER; + sc->sc_port_change = UPS_C_CONNECT_STATUS; + + if (addr == sc->sc_addr) { + switch (xfertype) { + case UE_CONTROL: + pipe->methods = &rumpusb_root_ctrl_methods; + break; + case UE_INTERRUPT: + pipe->methods = &rumpusb_root_intr_methods; + break; + default: + panic("%d not supported", xfertype); + break; + } + } else { + switch (xfertype) { + case UE_CONTROL: + pipe->methods = &rumpusb_device_ctrl_methods; + break; + case UE_INTERRUPT: + case UE_BULK: + pipe->methods = &rumpusb_device_bulk_methods; + endpt = pipe->endpoint->edesc->bEndpointAddress; + if (UE_GET_DIR(endpt) == UE_DIR_IN) { + oflags = O_RDONLY; + } else { + oflags = O_WRONLY; + } + endpt = UE_GET_ADDR(endpt); + + if (sc->sc_fdmodes[endpt] == oflags + || sc->sc_fdmodes[endpt] == O_RDWR) + break; + + if (sc->sc_fdmodes[endpt] != -1) { + /* XXX: closing from under someone? */ + rumpuser_close(sc->sc_ugenfd[endpt], &error); + oflags = O_RDWR; + } + + makeugendevstr(sc->sc_devnum, endpt, buf); + fd = rumpuser_open(buf, oflags, &error); + if (fd == -1) + return USBD_INVAL; /* XXX: no mapping */ + val = 100; + if (rumpuser_ioctl(fd, USB_SET_TIMEOUT, &val, + &error) == -1) + panic("timeout set failed"); + sc->sc_ugenfd[endpt] = fd; + sc->sc_fdmodes[endpt] = oflags; + break; + default: + panic("%d not supported", xfertype); + break; + + } + } + return 0; +} + +static void +ugenhc_softint(void *arg) +{ + +} + +static void +ugenhc_poll(struct usbd_bus *ubus) +{ + +} + +static usbd_status +ugenhc_allocm(struct usbd_bus *bus, usb_dma_t *dma, uint32_t size) +{ + struct ugenhc_softc *sc = bus->hci_private; + + return usb_allocmem(&sc->sc_bus, size, 0, dma); +} + +static void +ugenhc_freem(struct usbd_bus *ubus, usb_dma_t *udma) +{ + +} + +static struct usbd_xfer * +ugenhc_allocx(struct usbd_bus *bus) +{ + usbd_xfer_handle xfer; + + xfer = kmem_zalloc(sizeof(struct usbd_xfer), KM_SLEEP); + xfer->busy_free = XFER_BUSY; + + return xfer; +} + +static void +ugenhc_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) +{ + + kmem_free(xfer, sizeof(struct usbd_xfer)); +} + +struct ugenhc_pipe { + struct usbd_pipe pipe; +}; + +static const struct usbd_bus_methods ugenhc_bus_methods = { + .open_pipe = ugenhc_open, + .soft_intr = ugenhc_softint, + .do_poll = ugenhc_poll, + .allocm = ugenhc_allocm, + .freem = ugenhc_freem, + .allocx = ugenhc_allocx, + .freex = ugenhc_freex, +}; + +static int +ugenhc_probe(struct device *parent, struct cfdata *match, void *aux) +{ + char buf[UGENDEV_BUFSIZE]; + int fd, error; + + makeugendevstr(match->cf_unit, 0, buf); + fd = rumpuser_open(buf, O_RDWR, &error); + if (fd == -1) + return 0; + + rumpuser_close(fd, &error); + return 1; +} + +static void +ugenhc_attach(struct device *parent, struct device *self, void *aux) +{ + struct mainbus_attach_args *maa = aux; + struct ugenhc_softc *sc = device_private(self); + char buf[UGENDEV_BUFSIZE]; + int error; + + aprint_normal("\n"); + + memset(sc, 0, sizeof(*sc)); + memset(&sc->sc_ugenfd, -1, sizeof(sc->sc_ugenfd)); + memset(&sc->sc_fdmodes, -1, sizeof(sc->sc_fdmodes)); + + sc->sc_bus.usbrev = USBREV_2_0; + sc->sc_bus.methods = &ugenhc_bus_methods; + sc->sc_bus.hci_private = sc; + sc->sc_bus.pipe_size = sizeof(struct ugenhc_pipe); + sc->sc_devnum = maa->maa_unit; + + makeugendevstr(sc->sc_devnum, 0, buf); + sc->sc_ugenfd[UGEN_EPT_CTRL] = rumpuser_open(buf, O_RDWR, &error); + if (error) + panic("ugenhc_attach: failed to open ctrl ept %s\n", buf); + + config_found(self, &sc->sc_bus, usbctlprint); + + /* whoah, like extreme XXX, bro */ + rhscintr(); + if (!rump_threads) + config_pending_decr(); +}