Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/rump/dev/wip/librumpusbhc Checkpoint rump usb host contr...



details:   https://anonhg.NetBSD.org/src/rev/f3afd999353e
branches:  trunk
changeset: 747794:f3afd999353e
user:      pooka <pooka%NetBSD.org@localhost>
date:      Fri Oct 02 15:35:46 2009 +0000

description:
Checkpoint rump usb host controller implementation.  It's pretty
barebones, but manages to succesfully probe and attach the two USB
memory sticks I own.  (I don't own much USB junk, *hint hint*)

"dmesg":
pain-rustique:50:~> ./rumpusbprobe
mainbus0 (root)
rumpusbhc0 at mainbus0
usb0 at rumpusbhc0: USB revision 2.0
uhub0 at usb0: vendor 0x0000 product 0x0000, class 9/0, rev 0.00/0.00, addr 1
umass0 at uhub0 port 1 configuration 1 interface 0
umass0: vendor 0x1221 product 0x3234, rev 2.00/0.00, addr 2
scsibus0 at umass0: 2 targets, 1 lun per target
sd0 at scsibus0 target 0 lun 0: <USB2.0, Flash Disk, 2.20> disk removable
sd0: fabricating a geometry
sd0: 2023 MB, 2023 cyl, 64 head, 32 sec, 512 bytes/sect x 4143104 sectors

[switch the other stick in]

pain-rustique:51:~> ./rumpusbprobe
mainbus0 (root)
rumpusbhc0 at mainbus0
usb0 at rumpusbhc0: USB revision 2.0
uhub0 at usb0: vendor 0x0000 product 0x0000, class 9/0, rev 0.00/0.00, addr 1
umass0 at uhub0 port 1 configuration 1 interface 0
umass0: Kingston Technology product 0x1603, rev 2.00/2.00, addr 2
scsibus0 at umass0: 2 targets, 1 lun per target
sd0 at scsibus0 target 0 lun 0: <Kingston, DataTraveler 2.0, 1.00> disk removable
sd0: fabricating a geometry
sd0: 974 MB, 974 cyl, 64 head, 32 sec, 512 bytes/sect x 1994752 sectors
pain-rustique:52:~>

diffstat:

 sys/rump/dev/wip/librumpusbhc/Makefile      |    9 +
 sys/rump/dev/wip/librumpusbhc/rumpusbhc.c   |  851 ++++++++++++++++++++++++++++
 sys/rump/dev/wip/librumpusbhc/shlib_version |    4 +
 3 files changed, 864 insertions(+), 0 deletions(-)

diffs (truncated from 876 to 300 lines):

diff -r aed1cabe8ba2 -r f3afd999353e sys/rump/dev/wip/librumpusbhc/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/rump/dev/wip/librumpusbhc/Makefile    Fri Oct 02 15:35:46 2009 +0000
@@ -0,0 +1,9 @@
+#      $NetBSD: Makefile,v 1.1 2009/10/02 15:35:46 pooka Exp $
+#
+
+LIB=   rumpdev_usbhc
+
+SRCS=  rumpusbhc.c
+
+.include <bsd.lib.mk>
+.include <bsd.klinks.mk>
diff -r aed1cabe8ba2 -r f3afd999353e sys/rump/dev/wip/librumpusbhc/rumpusbhc.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/rump/dev/wip/librumpusbhc/rumpusbhc.c Fri Oct 02 15:35:46 2009 +0000
@@ -0,0 +1,851 @@
+/*     $NetBSD: rumpusbhc.c,v 1.1 2009/10/02 15:35:46 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 (lennart%augustsson.net@localhost) 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 ....
+ */
+
+/* hardcoded /dev/ugenN for now */
+#define UGENDEV 2
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: rumpusbhc.c,v 1.1 2009/10/02 15:35:46 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 <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usb_mem.h>
+#include <dev/usb/usbroothub_subr.h>
+
+#include <rump/rumpuser.h>
+
+#include "rump_dev_private.h"
+
+#define UGEN_NEPTS 16
+#define UGEN_EPT_CTRL 0 /* ugenx.00 is the control endpoint */
+
+struct rumpusbhc_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 const struct cfiattrdata usb_iattrdata = {
+        "usbus", 0, {
+               { NULL, NULL, 0 },
+       }
+};
+static const struct cfiattrdata *const rumpusbhc_attrs[] = {
+       &usb_iattrdata,
+       NULL,
+};
+
+static int     rumpusbhc_match(struct device *, struct cfdata *, void *);
+static void    rumpusbhc_attach(struct device *, struct device *, void *);
+
+CFATTACH_DECL_NEW(rumpusbhc, sizeof(struct rumpusbhc_softc),
+       rumpusbhc_match, rumpusbhc_attach, NULL, NULL);
+CFDRIVER_DECL(rumpusbhc, DV_DULL, rumpusbhc_attrs);
+
+struct cfparent rumpusbhcpar = {
+       "mainbus",
+       "mainbus",
+       DVUNIT_ANY
+};
+
+struct cfdata rumpusbhc_cfdata[] = {
+       { "rumpusbhc", "rumpusbhc", 0, FSTATE_STAR, NULL, 0, &rumpusbhcpar},
+};
+
+#define UGENDEV_BASESTR "/dev/ugen"
+#define UGENDEV_BUFSIZE 32
+static void
+makeugendevstr(struct rumpusbhc_softc *sc, int endpoint, char *buf)
+{
+
+       CTASSERT(UGENDEV_BUFSIZE > sizeof(UGENDEV_BASESTR)+sizeof("0.00")+1);
+       sprintf(buf, "%s%d.%02d", UGENDEV_BASESTR, sc->sc_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,
+};
+
+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 rumpusbhc_softc *sc = xfer->pipe->device->bus->hci_private;
+       int len, totlen, value, curlen, err;
+       uint8_t *buf;
+
+       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");



Home | Main Index | Thread Index | Old Index