Module Name: src
Committed By: skrll
Date: Thu Dec 4 08:04:32 UTC 2014
Modified Files:
src/sys/arch/mips/adm5120/dev [nick-nhusb]: ahci.c
src/sys/arch/mips/conf [nick-nhusb]: files.adm5120
src/sys/dev/ic [nick-nhusb]: sl811hs.c sl811hsvar.h
src/sys/dev/usb [nick-nhusb]: ehci.c ehcivar.h motg.c motgvar.h ohci.c
ohcivar.h uhci.c uhcivar.h usbdivar.h usbroothub.c usbroothub.h
xhci.c xhcivar.h
src/sys/external/bsd/dwc2 [nick-nhusb]: dwc2.c dwc2var.h
src/sys/rump/dev/lib/libugenhc [nick-nhusb]: ugenhc.c
Log Message:
Rework roothub control transfers so that much of the code is shared
across HCDs.
I have retained the vendor/product reporting for each HCD for now,
but it maybe get removed later.
ahci(4) now reports a language table and uses the usb_makestrdesc
function instead of rolling its own version.
To generate a diff of this commit:
cvs rdiff -u -r1.12.6.9 -r1.12.6.10 src/sys/arch/mips/adm5120/dev/ahci.c
cvs rdiff -u -r1.3 -r1.3.32.1 src/sys/arch/mips/conf/files.adm5120
cvs rdiff -u -r1.47.6.9 -r1.47.6.10 src/sys/dev/ic/sl811hs.c
cvs rdiff -u -r1.11 -r1.11.6.1 src/sys/dev/ic/sl811hsvar.h
cvs rdiff -u -r1.234.2.12 -r1.234.2.13 src/sys/dev/usb/ehci.c
cvs rdiff -u -r1.42.14.3 -r1.42.14.4 src/sys/dev/usb/ehcivar.h
cvs rdiff -u -r1.12.2.8 -r1.12.2.9 src/sys/dev/usb/motg.c
cvs rdiff -u -r1.4.2.2 -r1.4.2.3 src/sys/dev/usb/motgvar.h
cvs rdiff -u -r1.254.2.11 -r1.254.2.12 src/sys/dev/usb/ohci.c
cvs rdiff -u -r1.55.6.2 -r1.55.6.3 src/sys/dev/usb/ohcivar.h
cvs rdiff -u -r1.264.4.11 -r1.264.4.12 src/sys/dev/usb/uhci.c
cvs rdiff -u -r1.52.14.2 -r1.52.14.3 src/sys/dev/usb/uhcivar.h
cvs rdiff -u -r1.109.2.6 -r1.109.2.7 src/sys/dev/usb/usbdivar.h
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/dev/usb/usbroothub.c \
src/sys/dev/usb/usbroothub.h
cvs rdiff -u -r1.28.2.11 -r1.28.2.12 src/sys/dev/usb/xhci.c
cvs rdiff -u -r1.4.12.1 -r1.4.12.2 src/sys/dev/usb/xhcivar.h
cvs rdiff -u -r1.32.2.8 -r1.32.2.9 src/sys/external/bsd/dwc2/dwc2.c
cvs rdiff -u -r1.3.12.2 -r1.3.12.3 src/sys/external/bsd/dwc2/dwc2var.h
cvs rdiff -u -r1.22.4.6 -r1.22.4.7 src/sys/rump/dev/lib/libugenhc/ugenhc.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/arch/mips/adm5120/dev/ahci.c
diff -u src/sys/arch/mips/adm5120/dev/ahci.c:1.12.6.9 src/sys/arch/mips/adm5120/dev/ahci.c:1.12.6.10
--- src/sys/arch/mips/adm5120/dev/ahci.c:1.12.6.9 Wed Dec 3 22:40:54 2014
+++ src/sys/arch/mips/adm5120/dev/ahci.c Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ahci.c,v 1.12.6.9 2014/12/03 22:40:54 skrll Exp $ */
+/* $NetBSD: ahci.c,v 1.12.6.10 2014/12/04 08:04:31 skrll Exp $ */
/*-
* Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko.
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.12.6.9 2014/12/03 22:40:54 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.12.6.10 2014/12/04 08:04:31 skrll Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -81,6 +81,7 @@ __KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.1
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_mem.h>
#include <dev/usb/usbdevs.h>
+#include <dev/usb/usbroothub.h>
#include <mips/adm5120/include/adm5120reg.h>
#include <mips/adm5120/include/adm5120var.h>
@@ -98,14 +99,8 @@ static usbd_xfer_handle ahci_allocx(stru
static void ahci_freex(struct usbd_bus *, usbd_xfer_handle);
static void ahci_get_lock(struct usbd_bus *, kmutex_t **);
-
-static int ahci_str(usb_string_descriptor_t *, int, const char *);
-
-static usbd_status ahci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status ahci_root_ctrl_start(usbd_xfer_handle);
-static void ahci_root_ctrl_abort(usbd_xfer_handle);
-static void ahci_root_ctrl_close(usbd_pipe_handle);
-static void ahci_root_ctrl_done(usbd_xfer_handle);
+static int ahci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *,
+ void *, int);
static usbd_status ahci_root_intr_transfer(usbd_xfer_handle);
static usbd_status ahci_root_intr_start(usbd_xfer_handle);
@@ -150,9 +145,6 @@ int ahci_dummy;
#define AHCI_DEBUG
-/* For root hub */
-#define AHCI_INTR_ENDPT (1)
-
#ifdef AHCI_DEBUG
#define D_TRACE (0x0001) /* function trace */
#define D_MSG (0x0002) /* debug messages */
@@ -177,15 +169,7 @@ struct usbd_bus_methods ahci_bus_methods
.ubm_allocx = ahci_allocx,
.ubm_freex = ahci_freex,
.ubm_getlock = ahci_get_lock,
-};
-
-struct usbd_pipe_methods ahci_root_ctrl_methods = {
- .upm_transfer = ahci_root_ctrl_transfer,
- .upm_start = ahci_root_ctrl_start,
- .upm_abort = ahci_root_ctrl_abort,
- .upm_close = ahci_root_ctrl_close,
- .upm_cleartoggle = ahci_noop,
- .upm_done = ahci_root_ctrl_done,
+ .ubm_rhctrl = ahci_roothub_ctrl,
};
struct usbd_pipe_methods ahci_root_intr_methods = {
@@ -368,21 +352,21 @@ usbd_status
ahci_open(usbd_pipe_handle pipe)
{
usbd_device_handle dev = pipe->up_dev;
- struct ahci_softc *sc = (struct ahci_softc *)dev->ud_bus;
struct ahci_pipe *apipe = (struct ahci_pipe *)pipe;
usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
+ uint8_t rhaddr = dev->ud_bus->ub_rhaddr;
DPRINTF(D_TRACE, ("ahci_open(addr=%d,ep=%d,scaddr=%d)",
- dev->ud_addr, ed->bEndpointAddress, sc->sc_addr));
+ dev->ud_addr, ed->bEndpointAddress, rhaddr));
apipe->toggle=0;
- if (dev->ud_addr == sc->sc_addr) {
+ if (dev->ud_addr == rhaddr) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
- pipe->up_methods = &ahci_root_ctrl_methods;
+ pipe->up_methods = &roothub_ctrl_methods;
break;
- case UE_DIR_IN | AHCI_INTR_ENDPT:
+ case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
pipe->up_methods = &ahci_root_intr_methods;
break;
default:
@@ -531,275 +515,52 @@ ahci_noop(usbd_pipe_handle pipe)
/*
* Data structures and routines to emulate the root hub.
*/
-usb_device_descriptor_t ahci_devd = {
- .bLength = USB_DEVICE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x01, 0x01},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = 0,
- .bMaxPacketSize = 64,
- .idVendor = {
- USB_VENDOR_SCANLOGIC & 0xff,
- USB_VENDOR_SCANLOGIC >> 8
- },
- .idProduct = {0},
- .bcdDevice = {0},
- .iManufacturer = 1,
- .iProduct = 2,
- .iSerialNumber = 0,
- .bNumConfigurations = 1
-};
-
-usb_config_descriptor_t ahci_confd = {
- .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength = USETWD(
- USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 250
-};
-
-usb_interface_descriptor_t ahci_ifcd = {
- .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = 0,
- .iInterface = 0
-};
-
-usb_endpoint_descriptor_t ahci_endpd = {
- .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | AHCI_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize = USETWD(8),
- .bInterval = 255
-};
-
-usb_hub_descriptor_t ahci_hubd = {
- .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 2,
- .wHubCharacteristics = USETWD(0),
- .bPwrOn2PwrGood = 0,
- .bHubContrCurrent = 0,
- .DeviceRemovable = { 0x00 },
- .PortPowerCtrlMask = { 0x00 }
-};
static int
-ahci_str(usb_string_descriptor_t *p, int l, const char *s)
-{
- int i;
-
- if (l == 0)
- return 0;
- p->bLength = 2 * strlen(s) + 2;
- if (l == 1)
- return 1;
- p->bDescriptorType = UDESC_STRING;
- l -= 2;
- for (i = 0; s[i] && l > 1; i++, l -= 2)
- USETW2(p->bString[i], 0, s[i]);
- return 2 * i + 2;
-}
-
-usbd_status
-ahci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- struct ahci_softc *sc = (struct ahci_softc *)xfer->ux_pipe->up_dev->ud_bus;
- usbd_status error;
-
- DPRINTF(D_TRACE, ("SLRCtrans "));
-
- /* Insert last in queue */
- mutex_enter(&sc->sc_lock);
- error = usb_insert_transfer(xfer);
- mutex_exit(&sc->sc_lock);
- if (error) {
- DPRINTF(D_MSG, ("usb_insert_transfer returns err! "));
- return error;
- }
-
- /*
- * Pipe isn't running (otherwise error would be USBD_INPROG),
- * so start it first.
- */
- return ahci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
-}
-
-usbd_status
-ahci_root_ctrl_start(usbd_xfer_handle xfer)
+ahci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
+ void *buf, int buflen)
{
- struct ahci_softc *sc = (struct ahci_softc *)xfer->ux_pipe->up_dev->ud_bus;
- usb_device_request_t *req;
- int len, value, index, l, status;
- int totlen = 0;
- void *buf = NULL;
+ struct ahci_softc *sc = bus->ub_hcpriv;
+ uint16_t len, value, index;
usb_port_status_t ps;
- usbd_status error;
-
+ int totlen = 0;
+ int status;
DPRINTF(D_TRACE, ("SLRCstart "));
- req = &xfer->ux_request;
-
len = UGETW(req->wLength);
value = UGETW(req->wValue);
index = UGETW(req->wIndex);
- if (len)
- buf = KERNADDR(&xfer->ux_dmabuf, 0);
-
-#ifdef AHCI_DEBUG
- if ((ahci_debug & D_TRACE))
- print_req_hub(req);
-#endif
-
#define C(x,y) ((x) | ((y) << 8))
switch (C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- DPRINTF(D_MSG, ("UR_CLEAR_FEATURE(DEVICE)XXX "));
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- DPRINTF(D_MSG, ("UR_CLEAR_FEATURE(INTERFACE)XXX "));
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- DPRINTF(D_MSG, ("UR_CLEAR_FEATURE(ENDPOINT)XXX "));
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- DPRINTF(D_MSG, ("UR_GET_CONFIG "));
- if (len > 0) {
- *(uint8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- switch (value >> 8) {
- case UDESC_DEVICE:
+ switch (value) {
+ case C(0, UDESC_DEVICE): {
+ usb_device_descriptor_t devd;
+
DPRINTF(D_MSG, ("UDESC_DEVICE "));
- if ((value & 0xff) != 0) {
- error = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- memcpy(buf, &ahci_devd, l);
- break;
- case UDESC_CONFIG:
- DPRINTF(D_MSG, ("UDESC_CONFIG "));
- if ((value & 0xff) != 0) {
- error = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &ahci_confd, l);
- buf = (char *)buf + l;
- len -= l;
-
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ahci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
-
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ahci_endpd, l);
- break;
- case UDESC_STRING:
- DPRINTF(D_MSG, ("UDESC_STR "));
- if (len == 0)
- break;
- *(uint8_t *)buf = 0;
- totlen = 1;
- switch (value & 0xff) {
- case 0:
- break;
- case 1: /* Vendor */
- totlen = ahci_str(buf, len, "ADMTek");
- break;
- case 2: /* Product */
- totlen = ahci_str(buf, len, "ADM5120 root hub");
- break;
- default:
- printf("strerr%d ", value & 0xff);
- break;
- }
+ totlen = min(buflen, sizeof(devd));
+ memcpy(&devd, buf, totlen);
+ USETW(devd.idVendor, USB_VENDOR_SCANLOGIC);
+ memcpy(buf, &devd, totlen);
+ break;
+ }
+#define sd ((usb_string_descriptor_t *)buf)
+ case C(1, UDESC_STRING):
+ /* Vendor */
+ totlen = usb_makestrdesc(sd, len, "ADMTek");
+ break;
+ case C(2, UDESC_STRING):
+ /* Product */
+ totlen = usb_makestrdesc(sd, len, "ADM5120 root hub");
break;
default:
printf("unknownGetDescriptor=%x", value);
- error = USBD_IOERROR;
- break;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- /* Get Interface, 9.4.4 */
- if (len > 0) {
- *(uint8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- /* Get Status from device, 9.4.5 */
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- /* Get Status from interface, endpoint, 9.4.5 */
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- /* Set Address, 9.4.6 */
- DPRINTF(D_MSG, ("UR_SET_ADDRESS "));
- if (value >= USB_MAX_DEVICES) {
- error = USBD_IOERROR;
- goto ret;
+ /* default from usbroothub */
+ return buflen;
}
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- /* Set Configuration, 9.4.7 */
- DPRINTF(D_MSG, ("UR_SET_CONFIG "));
- if (value != 0 && value != 1) {
- error = USBD_IOERROR;
- goto ret;
- }
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- /* Set Descriptor, 9.4.8, not supported */
- DPRINTF(D_MSG, ("UR_SET_DESCRIPTOR,WRITE_DEVICE not supported\n"));
break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- /* Set Feature, 9.4.9, not supported */
- DPRINTF(D_MSG, ("UR_SET_FEATURE not supported\n"));
- error = USBD_IOERROR;
- break;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- /* Set Interface, 9.4.10, not supported */
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- /* Synch Frame, 9.4.11, not supported */
- break;
-
/*
* Hub specific requests
*/
@@ -812,8 +573,7 @@ ahci_root_ctrl_start(usbd_xfer_handle xf
#define WPS(x) REG_WRITE(ADMHCD_REG_PORTSTATUS0+(index-1)*4, (x))
/* Clear Port Feature, 11.16.2.2 */
if (index != 1 && index != 2 ) {
- error = USBD_IOERROR;
- goto ret;
+ return -1;
}
switch (value) {
case UHF_PORT_POWER:
@@ -845,8 +605,7 @@ ahci_root_ctrl_start(usbd_xfer_handle xf
break;
default:
printf("ClrPortFeatERR:value=0x%x ", value);
- error = USBD_IOERROR;
- break;
+ return -1;
}
//DPRINTF(D_XFER, ("CH=%04x ", sc->sc_change));
#undef WPS
@@ -859,19 +618,22 @@ ahci_root_ctrl_start(usbd_xfer_handle xf
/* Get Hub Descriptor, 11.16.2.4 */
DPRINTF(D_MSG, ("UR_GET_DESCRIPTOR RCD"));
if ((value&0xff) != 0) {
- error = USBD_IOERROR;
- goto ret;
+ return -1;
}
- l = min(len, USB_HUB_DESCRIPTOR_SIZE);
- totlen = l;
- memcpy(buf, &ahci_hubd, l);
+ usb_hub_descriptor_t hubd;
+
+ totlen = min(buflen, sizeof(hubd));
+ memcpy(&hubd, buf, totlen);
+ hubd.bNbrPorts = 2;
+ USETW(hubd.wHubCharacteristics, 0);
+ hubd.bPwrOn2PwrGood = 0;
+ memcpy(buf, &hubd, totlen);
break;
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
/* Get Hub Status, 11.16.2.5 */
DPRINTF(D_MSG, ("UR_GET_STATUS RCD"));
if (len != 4) {
- error = USBD_IOERROR;
- goto ret;
+ return -1;
}
memset(buf, 0, len);
totlen = len;
@@ -880,8 +642,7 @@ ahci_root_ctrl_start(usbd_xfer_handle xf
/* Get Port Status, 11.16.2.6 */
if ((index != 1 && index != 2) || len != 4) {
printf("index=%d,len=%d ", index, len);
- error = USBD_IOERROR;
- goto ret;
+ return -1;
}
status = REG_READ(ADMHCD_REG_PORTSTATUS0+(index-1)*4);
DPRINTF(D_MSG, ("UR_GET_STATUS RCO=%x ", status));
@@ -889,15 +650,13 @@ ahci_root_ctrl_start(usbd_xfer_handle xf
//DPRINTF(D_XFER, ("ST=%04x,CH=%04x ", status, sc->sc_change));
USETW(ps.wPortStatus, status & (UPS_CURRENT_CONNECT_STATUS|UPS_PORT_ENABLED|UPS_SUSPEND|UPS_OVERCURRENT_INDICATOR|UPS_RESET|UPS_PORT_POWER|UPS_LOW_SPEED));
USETW(ps.wPortChange, (status>>16) & (UPS_C_CONNECT_STATUS|UPS_C_PORT_ENABLED|UPS_C_SUSPEND|UPS_C_OVERCURRENT_INDICATOR|UPS_C_PORT_RESET));
- l = min(len, sizeof(ps));
- memcpy(buf, &ps, l);
- totlen = l;
+ totlen = min(len, sizeof(ps));
+ memcpy(buf, &ps, totlen);
break;
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
/* Set Hub Descriptor, 11.16.2.7, not supported */
/* STALL ? */
- error = USBD_IOERROR;
- break;
+ return -1;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
/* Set Hub Feature, 11.16.2.8, not supported */
break;
@@ -906,8 +665,7 @@ ahci_root_ctrl_start(usbd_xfer_handle xf
/* Set Port Feature, 11.16.2.9 */
if ((index != 1) && (index !=2)) {
printf("index=%d ", index);
- error = USBD_IOERROR;
- goto ret;
+ return -1;
}
switch (value) {
case UHF_PORT_RESET:
@@ -924,43 +682,18 @@ ahci_root_ctrl_start(usbd_xfer_handle xf
break;
default:
printf("SetPortFeatERR=0x%x ", value);
- error = USBD_IOERROR;
- break;
+ return -1;
}
#undef WPS
break;
default:
DPRINTF(D_MSG, ("ioerr(UR=%02x,UT=%02x) ",
req->bRequest, req->bmRequestType));
- error = USBD_IOERROR;
- goto ret;
+ /* default from usbroothub */
+ return buflen;
}
- xfer->ux_actlen = totlen;
- error = USBD_NORMAL_COMPLETION;
- ret:
- xfer->ux_status = error;
- mutex_enter(&sc->sc_lock);
- usb_transfer_complete(xfer);
- mutex_exit(&sc->sc_lock);
- return USBD_IN_PROGRESS;
-}
-
-void
-ahci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("SLRCabort "));
-}
-void
-ahci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("SLRCclose "));
-}
-
-void
-ahci_root_ctrl_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("SLRCdone\n"));
+ return totlen;
}
static usbd_status
Index: src/sys/arch/mips/conf/files.adm5120
diff -u src/sys/arch/mips/conf/files.adm5120:1.3 src/sys/arch/mips/conf/files.adm5120:1.3.32.1
--- src/sys/arch/mips/conf/files.adm5120:1.3 Mon Apr 4 20:01:14 2011
+++ src/sys/arch/mips/conf/files.adm5120 Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-# $NetBSD: files.adm5120,v 1.3 2011/04/04 20:01:14 dyoung Exp $
+# $NetBSD: files.adm5120,v 1.3.32.1 2014/12/04 08:04:31 skrll Exp $
file arch/mips/adm5120/adm5120_intr.c
@@ -44,6 +44,6 @@ attach wdc at extio with wdc_extio
file arch/mips/adm5120/dev/wdc_extio.c wdc_extio
# On-chip USB controller
-device ahci: usbus, usb_dma
+device ahci: usbus, usbroothub, usb_dma
attach ahci at obio
file arch/mips/adm5120/dev/ahci.c ahci
Index: src/sys/dev/ic/sl811hs.c
diff -u src/sys/dev/ic/sl811hs.c:1.47.6.9 src/sys/dev/ic/sl811hs.c:1.47.6.10
--- src/sys/dev/ic/sl811hs.c:1.47.6.9 Wed Dec 3 23:05:06 2014
+++ src/sys/dev/ic/sl811hs.c Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: sl811hs.c,v 1.47.6.9 2014/12/03 23:05:06 skrll Exp $ */
+/* $NetBSD: sl811hs.c,v 1.47.6.10 2014/12/04 08:04:31 skrll Exp $ */
/*
* Not (c) 2007 Matthew Orgass
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.47.6.9 2014/12/03 23:05:06 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.47.6.10 2014/12/04 08:04:31 skrll Exp $");
#include "opt_slhci.h"
@@ -252,9 +252,6 @@ static const struct timeval overflow_war
#endif
const int slhci_wait_time = SLHCI_WAIT_TIME;
-/* Root hub intr endpoint */
-#define ROOT_INTR_ENDPT 1
-
#ifndef SLHCI_MAX_RETRIES
#define SLHCI_MAX_RETRIES 3
#endif
@@ -432,6 +429,9 @@ usbd_status slhci_start(struct usbd_xfer
usbd_status slhci_root_start(struct usbd_xfer *);
usbd_status slhci_open(struct usbd_pipe *);
+static int slhci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *,
+ void *, int);
+
/*
* slhci_supported_rev, slhci_preinit, slhci_attach, slhci_detach,
* slhci_activate
@@ -684,6 +684,7 @@ const struct usbd_bus_methods slhci_bus_
.ubm_allocx = slhci_allocx,
.ubm_freex = slhci_freex,
.ubm_getlock = slhci_get_lock,
+ .ubm_rhctrl = slhci_roothub_ctrl,
};
const struct usbd_pipe_methods slhci_pipe_methods = {
@@ -992,17 +993,17 @@ slhci_open(struct usbd_pipe *pipe)
struct slhci_softc *sc;
struct slhci_pipe *spipe;
usb_endpoint_descriptor_t *ed;
- struct slhci_transfers *t;
unsigned int max_packet, pmaxpkt;
+ uint8_t rhaddr;
dev = pipe->up_dev;
sc = dev->ud_bus->ub_hcpriv;
spipe = (struct slhci_pipe *)pipe;
ed = pipe->up_endpoint->ue_edesc;
- t = &sc->sc_transfers;
+ rhaddr = dev->ud_bus->ub_rhaddr;
DLOG(D_TRACE, "slhci_open(addr=%d,ep=%d,rootaddr=%d)",
- dev->ud_addr, ed->bEndpointAddress, t->rootaddr, 0);
+ dev->ud_addr, ed->bEndpointAddress, rhaddr, 0);
spipe->pflags = 0;
spipe->frame = 0;
@@ -1024,7 +1025,7 @@ slhci_open(struct usbd_pipe *pipe)
if (dev->ud_speed == USB_SPEED_LOW) {
spipe->pflags |= PF_LS;
- if (dev->ud_myhub->ud_addr != t->rootaddr) {
+ if (dev->ud_myhub->ud_addr != rhaddr) {
spipe->pflags |= PF_PREAMBLE;
if (!slhci_try_lsvh)
return slhci_lock_call(sc, &slhci_lsvh_warn,
@@ -1040,15 +1041,17 @@ slhci_open(struct usbd_pipe *pipe)
return USBD_INVAL;
}
- if (dev->ud_addr == t->rootaddr) {
+ if (dev->ud_addr == rhaddr) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
spipe->ptype = PT_ROOT_CTRL;
pipe->up_interval = 0;
+ pipe->up_methods = &roothub_ctrl_methods;
break;
- case UE_DIR_IN | ROOT_INTR_ENDPT:
+ case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
spipe->ptype = PT_ROOT_INTR;
pipe->up_interval = 1;
+ pipe->up_methods = &slhci_root_methods;
break;
default:
printf("%s: Invalid root endpoint!\n", SC_NAME(sc));
@@ -1056,7 +1059,6 @@ slhci_open(struct usbd_pipe *pipe)
0,0,0);
return USBD_INVAL;
}
- pipe->up_methods = __UNCONST(&slhci_root_methods);
return USBD_NORMAL_COMPLETION;
} else {
switch (ed->bmAttributes & UE_XFERTYPE) {
@@ -2929,64 +2931,6 @@ slhci_insert(struct slhci_softc *sc)
/*
* Data structures and routines to emulate the root hub.
*/
-static const usb_device_descriptor_t slhci_devd = {
- .bLength = USB_DEVICE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x01, 0x01},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = 0,
- .bMaxPacketSize = 64,
- .idVendor = {
- USB_VENDOR_SCANLOGIC & 0xff, /* vendor ID (low) */
- USB_VENDOR_SCANLOGIC >> 8
- },
- .idProduct = {0},
- .bcdDevice = {0},
- .iManufacturer = 1,
- .iProduct = 2,
- .iSerialNumber = 0,
- .bNumConfigurations = 1
-};
-
-static const struct slhci_confd_t {
- const usb_config_descriptor_t confd;
- const usb_interface_descriptor_t ifcd;
- const usb_endpoint_descriptor_t endpd;
-} UPACKED slhci_confd = {
- .confd = {
- .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength = USETWD(
- USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 0
- },
- .ifcd = {
- .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = 0,
- .iInterface = 0
- },
- .endpd = {
- .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | ROOT_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize = USETWD(240),
- .bInterval = 255
- }
-};
static const usb_hub_descriptor_t slhci_hubd = {
.bDescLength = USB_HUB_DESCRIPTOR_SIZE,
@@ -3149,13 +3093,8 @@ slhci_root(struct slhci_softc *sc, struc
*xfer)
{
struct slhci_transfers *t;
- usb_device_request_t *req;
- unsigned int len, value, index, actlen, type;
- uint8_t *buf;
- usbd_status error;
t = &sc->sc_transfers;
- buf = NULL;
LK_SLASSERT(spipe != NULL && xfer != NULL, sc, spipe, xfer, return
USBD_CANCELLED);
@@ -3163,18 +3102,25 @@ slhci_root(struct slhci_softc *sc, struc
DLOG(D_TRACE, "%s start", pnames(SLHCI_XFER_TYPE(xfer)), 0,0,0);
KASSERT(mutex_owned(&sc->sc_intr_lock));
- if (spipe->ptype == PT_ROOT_INTR) {
- LK_SLASSERT(t->rootintr == NULL, sc, spipe, xfer, return
- USBD_CANCELLED);
- t->rootintr = xfer;
- if (t->flags & F_CHANGE)
- t->flags |= F_ROOTINTR;
- return USBD_IN_PROGRESS;
- }
+ KASSERT(spipe->ptype == PT_ROOT_INTR);
+ LK_SLASSERT(t->rootintr == NULL, sc, spipe, xfer, return
+ USBD_CANCELLED);
+ t->rootintr = xfer;
+ if (t->flags & F_CHANGE)
+ t->flags |= F_ROOTINTR;
+ return USBD_IN_PROGRESS;
+}
- error = USBD_IOERROR; /* XXX should be STALL */
- actlen = 0;
- req = &xfer->ux_request;
+static int
+slhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
+ void *buf, int buflen)
+{
+ struct slhci_softc *sc = bus->ub_hcpriv;
+ struct slhci_transfers *t = &sc->sc_transfers;
+ usbd_status error = USBD_IOERROR; /* XXX should be STALL */
+ uint16_t len, value, index;
+ uint8_t type;
+ int actlen = 0;
len = UGETW(req->wLength);
value = UGETW(req->wValue);
@@ -3182,9 +3128,6 @@ slhci_root(struct slhci_softc *sc, struc
type = req->bmRequestType;
- if (len)
- buf = xfer->ux_buf;
-
SLHCI_DEXEC(D_TRACE, slhci_log_req_hub(req));
/*
@@ -3244,24 +3187,7 @@ slhci_root(struct slhci_softc *sc, struc
"ENDPOINT_HALT or DEVICE_REMOTE_WAKEUP "
"not supported", 0,0,0,0);
break;
- case UR_SET_ADDRESS:
- if (type == UT_WRITE_DEVICE) {
- DLOG(D_ROOT, "Set Address %#.4x", value, 0,0,0);
- if (value < USB_MAX_DEVICES) {
- t->rootaddr = value;
- error = USBD_NORMAL_COMPLETION;
- }
- }
- break;
- case UR_SET_CONFIG:
- if (type == UT_WRITE_DEVICE) {
- DLOG(D_ROOT, "Set Config %#.4x", value, 0,0,0);
- if (value == 0 || value == 1) {
- t->rootconf = value;
- error = USBD_NORMAL_COMPLETION;
- }
- }
- break;
+
/* Read Requests */
case UR_GET_STATUS:
if (type == UT_READ_CLASS_OTHER) {
@@ -3284,57 +3210,29 @@ slhci_root(struct slhci_softc *sc, struc
} else
DLOG(D_ROOT, "Get Hub Status bad len %#.4x",
len, 0,0,0);
- } else if (type == UT_READ_DEVICE) {
- if (len >= 2) {
- USETW(((usb_status_t *)buf)->wStatus, UDS_SELF_POWERED);
- actlen = 2;
- error = USBD_NORMAL_COMPLETION;
- }
- } else if (type == (UT_READ_INTERFACE|UT_READ_ENDPOINT)) {
- if (len >= 2) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- actlen = 2;
- error = USBD_NORMAL_COMPLETION;
- }
- }
- break;
- case UR_GET_CONFIG:
- if (type == UT_READ_DEVICE) {
- DLOG(D_ROOT, "Get Config", 0,0,0,0);
- if (len > 0) {
- *buf = t->rootconf;
- actlen = 1;
- error = USBD_NORMAL_COMPLETION;
- }
- }
- break;
- case UR_GET_INTERFACE:
- if (type == UT_READ_INTERFACE) {
- if (len > 0) {
- *buf = 0;
- actlen = 1;
- error = USBD_NORMAL_COMPLETION;
- }
}
break;
case UR_GET_DESCRIPTOR:
if (type == UT_READ_DEVICE) {
/* value is type (&0xff00) and index (0xff) */
if (value == (UDESC_DEVICE<<8)) {
- actlen = min(len, sizeof(slhci_devd));
- memcpy(buf, &slhci_devd, actlen);
+ usb_device_descriptor_t devd;
+
+ actlen = min(buflen, sizeof(devd));
+ memcpy(&devd, buf, actlen);
+ USETW(devd.idVendor, USB_VENDOR_SCANLOGIC);
+ memcpy(buf, &devd, actlen);
error = USBD_NORMAL_COMPLETION;
} else if (value == (UDESC_CONFIG<<8)) {
- actlen = min(len, sizeof(slhci_confd));
- memcpy(buf, &slhci_confd, actlen);
- if (actlen > offsetof(usb_config_descriptor_t,
- bMaxPower))
- ((usb_config_descriptor_t *)
- buf)->bMaxPower = t->max_current;
- /* 2 mA units */
+ struct usb_roothub_descriptors confd;
+
+ actlen = min(buflen, sizeof(confd));
+ memcpy(&confd, buf, actlen);
+
+ /* 2 mA units */
+ confd.urh_confd.bMaxPower = t->max_current;
+ memcpy(buf, &confd, actlen);
error = USBD_NORMAL_COMPLETION;
- } else if (value == (UDESC_STRING<<8)) {
- /* language table XXX */
} else if (value == ((UDESC_STRING<<8)|1)) {
/* Vendor */
actlen = usb_makestrdesc((usb_string_descriptor_t *)
@@ -3351,29 +3249,28 @@ slhci_root(struct slhci_softc *sc, struc
} else if (type == UT_READ_CLASS_DEVICE) {
/* Descriptor number is 0 */
if (value == (UDESC_HUB<<8)) {
- actlen = min(len, sizeof(slhci_hubd));
- memcpy(buf, &slhci_hubd, actlen);
- if (actlen > offsetof(usb_config_descriptor_t,
- bMaxPower))
- ((usb_hub_descriptor_t *)
- buf)->bHubContrCurrent = 500 -
- t->max_current;
+ usb_hub_descriptor_t hubd;
+
+ actlen = min(buflen, sizeof(hubd));
+ memcpy(&hubd, buf, actlen);
+ hubd.bHubContrCurrent =
+ 500 - t->max_current;
+ memcpy(buf, &hubd, actlen);
error = USBD_NORMAL_COMPLETION;
} else
DDOLOG("Unknown Get Hub Descriptor %#.4x",
value, 0,0,0);
}
break;
+ default:
+ /* default from usbroothub */
+ return buflen;
}
if (error == USBD_NORMAL_COMPLETION)
- xfer->ux_actlen = actlen;
- xfer->ux_status = error;
- KASSERT(spipe->xfer == NULL);
- spipe->xfer = xfer;
- enter_callback(t, spipe);
+ return actlen;
- return USBD_IN_PROGRESS;
+ return -1;
}
/* End in lock functions. Start debug functions. */
Index: src/sys/dev/ic/sl811hsvar.h
diff -u src/sys/dev/ic/sl811hsvar.h:1.11 src/sys/dev/ic/sl811hsvar.h:1.11.6.1
--- src/sys/dev/ic/sl811hsvar.h:1.11 Wed Oct 2 22:55:04 2013
+++ src/sys/dev/ic/sl811hsvar.h Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: sl811hsvar.h,v 1.11 2013/10/02 22:55:04 skrll Exp $ */
+/* $NetBSD: sl811hsvar.h,v 1.11.6.1 2014/12/04 08:04:31 skrll Exp $ */
/*
* Not (c) 2007 Matthew Orgass
@@ -36,8 +36,6 @@ struct slhci_transfers {
int16_t len[2]; /* length of transfer or -1 if none */
uint8_t current_tregs[2][4]; /* ab, ADR, LEN, PID, DEV */
uint8_t copyin[2]; /* copyin ADR, LEN */
- uint8_t rootaddr; /* device address of root hub */
- uint8_t rootconf; /* root configuration */
uint8_t max_current; /* max current / 2 */
uint8_t sltype; /* revision */
};
Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.234.2.12 src/sys/dev/usb/ehci.c:1.234.2.13
--- src/sys/dev/usb/ehci.c:1.234.2.12 Wed Dec 3 23:05:06 2014
+++ src/sys/dev/usb/ehci.c Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci.c,v 1.234.2.12 2014/12/03 23:05:06 skrll Exp $ */
+/* $NetBSD: ehci.c,v 1.234.2.13 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 2004-2012 The NetBSD Foundation, Inc.
@@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.234.2.12 2014/12/03 23:05:06 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.234.2.13 2014/12/04 08:04:31 skrll Exp $");
#include "ohci.h"
#include "uhci.h"
@@ -81,10 +81,10 @@ __KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.2
#include <dev/usb/usbhist.h>
#include <dev/usb/usb_mem.h>
#include <dev/usb/usb_quirks.h>
-#include <dev/usb/usbroothub.h>
#include <dev/usb/ehcireg.h>
#include <dev/usb/ehcivar.h>
+#include <dev/usb/usbroothub.h>
#ifdef USB_DEBUG
@@ -173,12 +173,8 @@ Static void ehci_pcd(void *);
Static usbd_xfer_handle ehci_allocx(struct usbd_bus *);
Static void ehci_freex(struct usbd_bus *, usbd_xfer_handle);
Static void ehci_get_lock(struct usbd_bus *, kmutex_t **);
-
-Static usbd_status ehci_root_ctrl_transfer(usbd_xfer_handle);
-Static usbd_status ehci_root_ctrl_start(usbd_xfer_handle);
-Static void ehci_root_ctrl_abort(usbd_xfer_handle);
-Static void ehci_root_ctrl_close(usbd_pipe_handle);
-Static void ehci_root_ctrl_done(usbd_xfer_handle);
+Static int ehci_roothub_ctrl(struct usbd_bus *,
+ usb_device_request_t *, void *, int);
Static usbd_status ehci_root_intr_transfer(usbd_xfer_handle);
Static usbd_status ehci_root_intr_start(usbd_xfer_handle);
@@ -276,8 +272,6 @@ Static void ehci_dump_exfer(struct ehci
#define EHCI_NULL htole32(EHCI_LINK_TERMINATE)
-#define EHCI_INTR_ENDPT 1
-
#define ehci_add_intr_list(sc, ex) \
TAILQ_INSERT_TAIL(&(sc)->sc_intrhead, (ex), inext);
#define ehci_del_intr_list(sc, ex) \
@@ -294,16 +288,7 @@ Static const struct usbd_bus_methods ehc
.ubm_allocx = ehci_allocx,
.ubm_freex = ehci_freex,
.ubm_getlock = ehci_get_lock,
- .ubm_newdev = NULL,
-};
-
-Static const struct usbd_pipe_methods ehci_root_ctrl_methods = {
- .upm_transfer = ehci_root_ctrl_transfer,
- .upm_start = ehci_root_ctrl_start,
- .upm_abort = ehci_root_ctrl_abort,
- .upm_close = ehci_root_ctrl_close,
- .upm_cleartoggle = ehci_noop,
- .upm_done = ehci_root_ctrl_done,
+ .ubm_rhctrl = ehci_roothub_ctrl,
};
Static const struct usbd_pipe_methods ehci_root_intr_methods = {
@@ -1840,6 +1825,7 @@ ehci_open(usbd_pipe_handle pipe)
usbd_device_handle dev = pipe->up_dev;
ehci_softc_t *sc = dev->ud_bus->ub_hcpriv;
usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
+ uint8_t rhaddr = dev->ud_bus->ub_rhaddr;
uint8_t addr = dev->ud_addr;
uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes);
struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
@@ -1851,7 +1837,7 @@ ehci_open(usbd_pipe_handle pipe)
USBHIST_FUNC(); USBHIST_CALLED(ehcidebug);
USBHIST_LOG(ehcidebug, "pipe=%p, addr=%d, endpt=%d (%d)",
- pipe, addr, ed->bEndpointAddress, sc->sc_addr);
+ pipe, addr, ed->bEndpointAddress, rhaddr);
if (dev->ud_myhsport) {
/*
@@ -1860,7 +1846,7 @@ ehci_open(usbd_pipe_handle pipe)
* address to 0 (us).
*/
if (!(sc->sc_flags & EHCIF_ETTF)
- || (dev->ud_myhsport->up_parent->ud_addr != sc->sc_addr)) {
+ || (dev->ud_myhsport->up_parent->ud_addr != rhaddr)) {
hshubaddr = dev->ud_myhsport->up_parent->ud_addr;
} else {
hshubaddr = 0;
@@ -1877,12 +1863,12 @@ ehci_open(usbd_pipe_handle pipe)
/* toggle state needed for bulk endpoints */
epipe->nexttoggle = pipe->up_endpoint->ue_toggle;
- if (addr == sc->sc_addr) {
+ if (addr == rhaddr) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
- pipe->up_methods = &ehci_root_ctrl_methods;
+ pipe->up_methods = &roothub_ctrl_methods;
break;
- case UE_DIR_IN | EHCI_INTR_ENDPT:
+ case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
pipe->up_methods = &ehci_root_intr_methods;
break;
default:
@@ -2248,131 +2234,24 @@ ehci_rem_free_sitd_chain(ehci_softc_t *s
exfer->sitdend = NULL;
}
-
/***********/
-/*
- * Data structures and routines to emulate the root hub.
- */
-Static usb_device_descriptor_t ehci_devd = {
- .bLength = USB_DEVICE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_HSHUBSTT,
- .bMaxPacketSize = 64,
- .idVendor = {0},
- .idProduct = {0},
- .bcdDevice = {0x00,0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .iSerialNumber = 0,
- .bNumConfigurations = 1
-};
-
-Static const usb_device_qualifier_t ehci_odevd = {
- .bLength = USB_DEVICE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_DEVICE_QUALIFIER,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_FSHUB,
- .bMaxPacketSize0 = 64,
- .bNumConfigurations = 1,
- 0
-};
-
-Static const usb_config_descriptor_t ehci_confd = {
- .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength = USETWD(
- USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_ATTR_MBO | UC_SELF_POWERED,
- .bMaxPower = 0
-};
-
-Static const usb_interface_descriptor_t ehci_ifcd = {
- .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_HSHUBSTT,
- .iInterface = 0
-};
-
-Static const usb_endpoint_descriptor_t ehci_endpd = {
- .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | EHCI_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize = USETWD(8),
- .bInterval = 12
-};
-
-Static const usb_hub_descriptor_t ehci_hubd = {
- .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 0,
- .wHubCharacteristics = USETWD(0),
- .bPwrOn2PwrGood = 0,
- .bHubContrCurrent = 0,
- .DeviceRemovable = {""},
- .PortPowerCtrlMask = {""},
-};
-
-/*
- * Simulate a hardware hub by handling all the necessary requests.
- */
-Static usbd_status
-ehci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- ehci_softc_t *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usbd_status err;
-
- /* Insert last in queue. */
- mutex_enter(&sc->sc_lock);
- err = usb_insert_transfer(xfer);
- mutex_exit(&sc->sc_lock);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ehci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)));
-}
-
-Static usbd_status
-ehci_root_ctrl_start(usbd_xfer_handle xfer)
+Static int
+ehci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
+ void *buf, int buflen)
{
- ehci_softc_t *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usb_device_request_t *req;
- void *buf = NULL;
- int port, i;
- int len, value, index, l, totlen = 0;
- usb_port_status_t ps;
+ ehci_softc_t *sc = bus->ub_hcpriv;
usb_hub_descriptor_t hubd;
- usbd_status err;
+ usb_port_status_t ps;
+ uint16_t len, value, index;
+ int l, totlen = 0;
+ int port, i;
uint32_t v;
USBHIST_FUNC(); USBHIST_CALLED(ehcidebug);
if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->ux_rqflags & URQ_REQUEST))
- /* XXX panic */
- return (USBD_INVAL);
-#endif
- req = &xfer->ux_request;
+ return -1;
USBHIST_LOG(ehcidebug, "type=0x%02x request=%02x",
req->bmRequestType, req->bRequest, 0, 0);
@@ -2381,142 +2260,37 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
value = UGETW(req->wValue);
index = UGETW(req->wIndex);
- if (len != 0)
- buf = xfer->ux_buf;
-
#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(uint8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
+ switch (C(req->bRequest, req->bmRequestType)) {
case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- USBHIST_LOG(ehcidebug, "wValue=0x%04x", value, 0, 0, 0);
if (len == 0)
break;
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(ehci_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &ehci_devd, l);
- break;
- /*
- * We can't really operate at another speed, but the spec says
- * we need this descriptor.
- */
- case UDESC_DEVICE_QUALIFIER:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- memcpy(buf, &ehci_odevd, l);
- break;
- /*
- * We can't really operate at another speed, but the spec says
- * we need this descriptor.
- */
- case UDESC_OTHER_SPEED_CONFIGURATION:
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &ehci_confd, l);
- ((usb_config_descriptor_t *)buf)->bDescriptorType =
- value >> 8;
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ehci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ehci_endpd, l);
+ switch (value) {
+ case C(0, UDESC_DEVICE): {
+ usb_device_descriptor_t devd;
+ totlen = min(buflen, sizeof(devd));
+ memcpy(&devd, buf, totlen);
+ USETW(devd.idVendor, sc->sc_id_vendor);
+ memcpy(buf, &devd, totlen);
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,
- sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = usb_makestrdesc(sd, len,
- "EHCI root hub");
- break;
- }
-#undef sd
+ case C(1, UDESC_STRING):
+ /* Vendor */
+ totlen = usb_makestrdesc(sd, len, sc->sc_vendor);
+ break;
+ case C(2, UDESC_STRING):
+ /* Product */
+ totlen = usb_makestrdesc(sd, len, "EHCI root hub");
break;
+#undef sd
default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(uint8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- err = USBD_IOERROR;
- goto ret;
+ /* default from usbroothub */
+ return buflen;
}
- 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_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
break;
+
/* Hub requests */
case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
@@ -2525,14 +2299,13 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
"UR_CLEAR_PORT_FEATURE port=%d feature=%d", index, value,
0, 0);
if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
port = EHCI_PORTSC(index);
v = EOREAD4(sc, port);
USBHIST_LOG(ehcidebug, "portsc=0x%08x", v, 0, 0, 0);
v &= ~EHCI_PS_CLEAR;
- switch(value) {
+ switch (value) {
case UHF_PORT_ENABLE:
EOWRITE4(sc, port, v &~ EHCI_PS_PE);
break;
@@ -2580,8 +2353,7 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
sc->sc_isreset[index] = 0;
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
#if 0
switch(value) {
@@ -2599,10 +2371,10 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
if (len == 0)
break;
if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
- hubd = ehci_hubd;
+ totlen = min(buflen, sizeof(hubd));
+ memcpy(&hubd, buf, totlen);
hubd.bNbrPorts = sc->sc_noport;
v = EOREAD4(sc, EHCI_HCSPARAMS);
USETW(hubd.wHubCharacteristics,
@@ -2613,14 +2385,12 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
hubd.DeviceRemovable[i++] = 0; /* XXX can't find out? */
hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
- l = min(len, hubd.bDescLength);
- totlen = l;
- memcpy(buf, &hubd, l);
+ totlen = min(totlen, hubd.bDescLength);
+ memcpy(buf, &hubd, totlen);
break;
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
memset(buf, 0, len); /* ? XXX */
totlen = len;
@@ -2628,12 +2398,10 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
USBHIST_LOG(ehcidebug, "get port status i=%d", index, 0, 0, 0);
if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
v = EOREAD4(sc, EHCI_PORTSC(index));
USBHIST_LOG(ehcidebug, "port status=0x%04x", v, 0, 0, 0);
@@ -2663,19 +2431,16 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
if (v & EHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR;
if (sc->sc_isreset[index]) i |= UPS_C_PORT_RESET;
USETW(ps.wPortChange, i);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
+ totlen = min(len, sizeof(ps));
+ memcpy(buf, &ps, totlen);
break;
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
+ return -1;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
port = EHCI_PORTSC(index);
v = EOREAD4(sc, port);
@@ -2706,8 +2471,7 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
/* Wait for reset to complete. */
usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
/*
* An embedded transaction translator will automatically
@@ -2722,8 +2486,7 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
usb_delay_ms(&sc->sc_bus,
EHCI_PORT_RESET_COMPLETE);
if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
}
@@ -2762,8 +2525,7 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
EOWRITE4(sc, port, v | EHCI_PS_PIC);
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
break;
case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER):
@@ -2772,17 +2534,11 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ /* default from usbroothub */
+ return buflen;
}
- xfer->ux_actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- mutex_enter(&sc->sc_lock);
- xfer->ux_status = err;
- usb_transfer_complete(xfer);
- mutex_exit(&sc->sc_lock);
- return (USBD_IN_PROGRESS);
+
+ return totlen;
}
Static void
@@ -2815,27 +2571,6 @@ ehci_disown(ehci_softc_t *sc, int index,
EOWRITE4(sc, port, v | EHCI_PS_PO);
}
-/* Abort a root control request. */
-Static void
-ehci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-
-/* Close the root pipe. */
-Static void
-ehci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- USBHIST_FUNC(); USBHIST_CALLED(ehcidebug);
- /* Nothing to do. */
-}
-
-Static void
-ehci_root_ctrl_done(usbd_xfer_handle xfer)
-{
- xfer->ux_hcpriv = NULL;
-}
-
Static usbd_status
ehci_root_intr_transfer(usbd_xfer_handle xfer)
{
Index: src/sys/dev/usb/ehcivar.h
diff -u src/sys/dev/usb/ehcivar.h:1.42.14.3 src/sys/dev/usb/ehcivar.h:1.42.14.4
--- src/sys/dev/usb/ehcivar.h:1.42.14.3 Tue Dec 2 09:00:33 2014
+++ src/sys/dev/usb/ehcivar.h Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ehcivar.h,v 1.42.14.3 2014/12/02 09:00:33 skrll Exp $ */
+/* $NetBSD: ehcivar.h,v 1.42.14.4 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -170,8 +170,6 @@ typedef struct ehci_softc {
int sc_noport;
uint8_t sc_hasppc; /* has Port Power Control */
- uint8_t sc_addr; /* device address */
- uint8_t sc_conf; /* device configuration */
usbd_xfer_handle sc_intrxfer;
char sc_isreset[EHCI_MAX_PORTS];
char sc_softwake;
Index: src/sys/dev/usb/motg.c
diff -u src/sys/dev/usb/motg.c:1.12.2.8 src/sys/dev/usb/motg.c:1.12.2.9
--- src/sys/dev/usb/motg.c:1.12.2.8 Wed Dec 3 23:05:06 2014
+++ src/sys/dev/usb/motg.c Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: motg.c,v 1.12.2.8 2014/12/03 23:05:06 skrll Exp $ */
+/* $NetBSD: motg.c,v 1.12.2.9 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 1998, 2004, 2011, 2012, 2014 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
#include "opt_motg.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.12.2.8 2014/12/03 23:05:06 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.12.2.9 2014/12/04 08:04:31 skrll Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -101,11 +101,6 @@ int motgdebug = 0;
#define NAK_TO_BULK_HIGH 0
static void motg_hub_change(struct motg_softc *);
-static usbd_status motg_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status motg_root_ctrl_start(usbd_xfer_handle);
-static void motg_root_ctrl_abort(usbd_xfer_handle);
-static void motg_root_ctrl_close(usbd_pipe_handle);
-static void motg_root_ctrl_done(usbd_xfer_handle);
static usbd_status motg_root_intr_transfer(usbd_xfer_handle);
static usbd_status motg_root_intr_start(usbd_xfer_handle);
@@ -119,6 +114,9 @@ static void motg_softintr(void *);
static usbd_xfer_handle motg_allocx(struct usbd_bus *);
static void motg_freex(struct usbd_bus *, usbd_xfer_handle);
static void motg_get_lock(struct usbd_bus *, kmutex_t **);
+static int motg_roothub_ctrl(struct usbd_bus *, usb_device_request_t *,
+ void *, int);
+
static void motg_noop(usbd_pipe_handle pipe);
static usbd_status motg_portreset(struct motg_softc*);
@@ -148,7 +146,6 @@ static void motg_waitintr(struct motg_s
static void motg_device_clear_toggle(usbd_pipe_handle);
static void motg_device_xfer_abort(usbd_xfer_handle);
-#define MOTG_INTR_ENDPT 1
#define UBARR(sc) bus_space_barrier((sc)->sc_iot, (sc)->sc_ioh, 0, (sc)->sc_size, \
BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
#define UWRITE1(sc, r, x) \
@@ -207,16 +204,7 @@ const struct usbd_bus_methods motg_bus_m
.ubm_allocx = motg_allocx,
.ubm_freex = motg_freex,
.ubm_getlock = motg_get_lock,
- .ubm_newdev = NULL,
-};
-
-const struct usbd_pipe_methods motg_root_ctrl_methods = {
- .upm_transfer = motg_root_ctrl_transfer,
- .upm_start = motg_root_ctrl_start,
- .upm_abort = motg_root_ctrl_abort,
- .upm_close = motg_root_ctrl_close,
- .upm_cleartoggle = motg_noop,
- .upm_done = motg_root_ctrl_done,
+ .ubm_rhctrl = motg_roothub_ctrl,
};
const struct usbd_pipe_methods motg_root_intr_methods = {
@@ -496,10 +484,11 @@ motg_open(usbd_pipe_handle pipe)
struct motg_softc *sc = pipe->up_dev->ud_bus->ub_hcpriv;
struct motg_pipe *otgpipe = (struct motg_pipe *)pipe;
usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
+ uint8_t rhaddr = pipe->up_dev->ud_bus->ub_rhaddr;
DPRINTF(("motg_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
pipe, pipe->up_dev->ud_addr,
- ed->bEndpointAddress, sc->sc_root_addr));
+ ed->bEndpointAddress, rhaddr));
if (sc->sc_dying)
return USBD_IOERROR;
@@ -507,12 +496,12 @@ motg_open(usbd_pipe_handle pipe)
/* toggle state needed for bulk endpoints */
otgpipe->nexttoggle = pipe->up_endpoint->ue_toggle;
- if (pipe->up_dev->ud_addr == sc->sc_root_addr) {
+ if (pipe->up_dev->ud_addr == rhaddr) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
- pipe->up_methods = &motg_root_ctrl_methods;
+ pipe->up_methods = &roothub_ctrl_methods;
break;
- case UE_DIR_IN | MOTG_INTR_ENDPT:
+ case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
pipe->up_methods = &motg_root_intr_methods;
break;
default:
@@ -756,250 +745,69 @@ motg_get_lock(struct usbd_bus *bus, kmut
}
/*
- * Data structures and routines to emulate the root hub.
- */
-usb_device_descriptor_t motg_devd = {
- .bLength = USB_DEVICE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x01},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_FSHUB,
- .bMaxPacketSize = 64,
- .idVendor = {0},
- .idProduct = {0},
- .bcdDevice = {0x00,0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .iSerialNumber = 0,
- .bNumConfigurations = 1
-};
-
-const usb_config_descriptor_t motg_confd = {
- .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength = USETWD(
- USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_ATTR_MBO | UC_SELF_POWERED,
- .bMaxPower = 0
-};
-
-const usb_interface_descriptor_t motg_ifcd = {
- .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_FSHUB,
-};
-
-const usb_endpoint_descriptor_t motg_endpd = {
- .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | MOTG_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize = USETWD(8),
- .bInterval = 255
-};
-
-const usb_hub_descriptor_t motg_hubd = {
- .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 1,
- .wHubCharacteristics = USETWD(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL),
- .bPwrOn2PwrGood = 50,
- .bHubContrCurrent = 0,
- .DeviceRemovable = { 0 },
- .PortPowerCtrlMask = { 0 },
-};
-
-/*
- * Simulate a hardware hub by handling all the necessary requests.
+ * Routines to emulate the root hub.
*/
-usbd_status
-motg_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- struct motg_softc *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usbd_status err;
-
- /* Insert last in queue. */
- mutex_enter(&sc->sc_lock);
- err = usb_insert_transfer(xfer);
- mutex_exit(&sc->sc_lock);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (motg_root_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)));
-}
-
-usbd_status
-motg_root_ctrl_start(usbd_xfer_handle xfer)
+Static int
+motg_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
+ void *buf, int buflen)
{
- struct motg_softc *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usb_device_request_t *req;
- void *buf = NULL;
- int len, value, index, status, change, l, totlen = 0;
+ struct motg_softc *sc = bus->ub_hcpriv;
+ int status, change, totlen = 0;
+ uint16_t len, value, index;
usb_port_status_t ps;
usbd_status err;
uint32_t val;
if (sc->sc_dying)
- return (USBD_IOERROR);
+ return -1;
-#ifdef DIAGNOSTIC
- if (!(xfer->ux_rqflags & URQ_REQUEST))
- panic("motg_root_ctrl_start: not a request");
-#endif
- req = &xfer->ux_request;
-
- DPRINTFN(MD_ROOT,("motg_root_ctrl_control type=0x%02x request=%02x\n",
+ DPRINTFN(MD_ROOT,("%s type=0x%02x request=%02x\n", __func__,
req->bmRequestType, req->bRequest));
len = UGETW(req->wLength);
value = UGETW(req->wValue);
index = UGETW(req->wIndex);
- if (len != 0)
- buf = xfer->ux_buf;
-
#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(uint8_t *)buf = sc->sc_root_conf;
- totlen = 1;
- }
- break;
+ switch (C(req->bRequest, req->bmRequestType)) {
case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- DPRINTFN(MD_ROOT,("motg_root_ctrl_control wValue=0x%04x\n", value));
- if (len == 0)
+ DPRINTFN(MD_ROOT,("%s wValue=0x%04x\n", __func__, value));
+ switch (value) {
+ case C(0, UDESC_DEVICE): {
+ usb_device_descriptor_t devd;
+
+ totlen = min(buflen, sizeof(devd));
+ memcpy(&devd, buf, totlen);
+ USETW(devd.idVendor, sc->sc_id_vendor);
+ memcpy(buf, &devd, totlen);
break;
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(motg_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &motg_devd, l);
- break;
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &motg_confd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &motg_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &motg_endpd, l);
- break;
- case UDESC_STRING:
+ }
+ case C(1, 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,
- sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = usb_makestrdesc(sd, len,
- "MOTG root hub");
- break;
- }
-#undef sd
+ /* Vendor */
+ totlen = usb_makestrdesc(sd, len, sc->sc_vendor);
break;
+ case C(2, UDESC_STRING):
+ /* Product */
+ totlen = usb_makestrdesc(sd, len, "MOTG root hub");
+ break;
+#undef sd
default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(uint8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
+ /* default from usbroothub */
+ return buflen;
}
break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_root_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if (value != 0 && value != 1) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_root_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- break;
/* Hub requests */
case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
DPRINTFN(MD_ROOT,
- ("motg_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
- index, value));
+ ("%s: UR_CLEAR_PORT_FEATURE port=%d feature=%d\n",
+ __func__, index, value));
if (index != 1) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
- switch(value) {
+ switch (value) {
case UHF_PORT_ENABLE:
sc->sc_port_enabled = 0;
break;
@@ -1028,8 +836,7 @@ motg_root_ctrl_start(usbd_xfer_handle xf
break;
case UHF_C_PORT_RESET:
sc->sc_isreset = 0;
- err = USBD_NORMAL_COMPLETION;
- goto ret;
+ break;
case UHF_PORT_POWER:
/* XXX todo */
break;
@@ -1038,40 +845,32 @@ motg_root_ctrl_start(usbd_xfer_handle xf
case UHF_PORT_LOW_SPEED:
case UHF_C_PORT_SUSPEND:
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
break;
case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
- err = USBD_IOERROR;
- goto ret;
+ return -1;
case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
if (len == 0)
break;
if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
- l = min(len, USB_HUB_DESCRIPTOR_SIZE);
- totlen = l;
- memcpy(buf, &motg_hubd, l);
+ totlen = buflen;
break;
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
memset(buf, 0, len);
totlen = len;
break;
case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
if (index != 1) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
status = change = 0;
if (sc->sc_connected)
@@ -1095,19 +894,16 @@ motg_root_ctrl_start(usbd_xfer_handle xf
change |= UPS_C_PORT_RESET;
USETW(ps.wPortStatus, status);
USETW(ps.wPortChange, change);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
+ totlen = min(len, sizeof(ps));
+ memcpy(buf, &ps, totlen);
break;
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
+ return -1;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
if (index != 1) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
switch(value) {
case UHF_PORT_ENABLE:
@@ -1126,11 +922,12 @@ motg_root_ctrl_start(usbd_xfer_handle xf
break;
case UHF_PORT_RESET:
err = motg_portreset(sc);
- goto ret;
+ if (err != USBD_NORMAL_COMPLETION)
+ return -1;
+ return 0;
case UHF_PORT_POWER:
/* XXX todo */
- err = USBD_NORMAL_COMPLETION;
- goto ret;
+ return 0;
case UHF_C_PORT_CONNECTION:
case UHF_C_PORT_ENABLE:
case UHF_C_PORT_OVER_CURRENT:
@@ -1140,41 +937,15 @@ motg_root_ctrl_start(usbd_xfer_handle xf
case UHF_C_PORT_SUSPEND:
case UHF_C_PORT_RESET:
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ /* default from usbroothub */
+ return buflen;
}
- xfer->ux_actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- xfer->ux_status = err;
- mutex_enter(&sc->sc_lock);
- usb_transfer_complete(xfer);
- mutex_exit(&sc->sc_lock);
- return (USBD_IN_PROGRESS);
-}
-/* Abort a root control request. */
-void
-motg_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-
-/* Close the root pipe. */
-void
-motg_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTFN(MD_ROOT, ("motg_root_ctrl_close\n"));
-}
-
-void
-motg_root_ctrl_done(usbd_xfer_handle xfer)
-{
+ return totlen;
}
/* Abort a root interrupt request. */
Index: src/sys/dev/usb/motgvar.h
diff -u src/sys/dev/usb/motgvar.h:1.4.2.2 src/sys/dev/usb/motgvar.h:1.4.2.3
--- src/sys/dev/usb/motgvar.h:1.4.2.2 Tue Dec 2 09:00:33 2014
+++ src/sys/dev/usb/motgvar.h Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: motgvar.h,v 1.4.2.2 2014/12/02 09:00:33 skrll Exp $ */
+/* $NetBSD: motgvar.h,v 1.4.2.3 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -93,8 +93,6 @@ struct motg_softc {
/* Info for the root hub interrupt "pipe". */
usbd_xfer_handle sc_intr_xfer; /* root hub interrupt transfer */
- uint8_t sc_root_addr; /* address of the root hub */
- uint8_t sc_root_conf; /* configuration of the root hub */
char sc_vendor[32]; /* vendor string for root hub */
int sc_id_vendor; /* vendor ID for root hub */
Index: src/sys/dev/usb/ohci.c
diff -u src/sys/dev/usb/ohci.c:1.254.2.11 src/sys/dev/usb/ohci.c:1.254.2.12
--- src/sys/dev/usb/ohci.c:1.254.2.11 Wed Dec 3 23:05:06 2014
+++ src/sys/dev/usb/ohci.c Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ohci.c,v 1.254.2.11 2014/12/03 23:05:06 skrll Exp $ */
+/* $NetBSD: ohci.c,v 1.254.2.12 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.254.2.11 2014/12/03 23:05:06 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.254.2.12 2014/12/04 08:04:31 skrll Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -130,12 +130,8 @@ Static void ohci_device_isoc_enter(usbd
Static usbd_xfer_handle ohci_allocx(struct usbd_bus *);
Static void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
Static void ohci_get_lock(struct usbd_bus *, kmutex_t **);
-
-Static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
-Static usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
-Static void ohci_root_ctrl_abort(usbd_xfer_handle);
-Static void ohci_root_ctrl_close(usbd_pipe_handle);
-Static void ohci_root_ctrl_done(usbd_xfer_handle);
+Static int ohci_roothub_ctrl(struct usbd_bus *,
+ usb_device_request_t *, void *, int);
Static usbd_status ohci_root_intr_transfer(usbd_xfer_handle);
Static usbd_status ohci_root_intr_start(usbd_xfer_handle);
@@ -245,8 +241,6 @@ struct ohci_pipe {
} u;
};
-#define OHCI_INTR_ENDPT 1
-
Static const struct usbd_bus_methods ohci_bus_methods = {
.ubm_open = ohci_open,
.ubm_softint = ohci_softintr,
@@ -254,16 +248,7 @@ Static const struct usbd_bus_methods ohc
.ubm_allocx = ohci_allocx,
.ubm_freex = ohci_freex,
.ubm_getlock = ohci_get_lock,
- .ubm_newdev = NULL,
-};
-
-Static const struct usbd_pipe_methods ohci_root_ctrl_methods = {
- .upm_transfer = ohci_root_ctrl_transfer,
- .upm_start = ohci_root_ctrl_start,
- .upm_abort = ohci_root_ctrl_abort,
- .upm_close = ohci_root_ctrl_close,
- .upm_cleartoggle = ohci_noop,
- .upm_done = ohci_root_ctrl_done,
+ .ubm_rhctrl = ohci_roothub_ctrl,
};
Static const struct usbd_pipe_methods ohci_root_intr_methods = {
@@ -1588,11 +1573,6 @@ ohci_root_intr_done(usbd_xfer_handle xfe
{
}
-void
-ohci_root_ctrl_done(usbd_xfer_handle xfer)
-{
-}
-
/*
* Wait here until controller claims to have an interrupt.
* Then call ohci_intr and return. Use timeout to avoid waiting
@@ -2076,6 +2056,7 @@ usbd_status
ohci_open(usbd_pipe_handle pipe)
{
usbd_device_handle dev = pipe->up_dev;
+ struct usbd_bus *bus = dev->ud_bus;
ohci_softc_t *sc = dev->ud_bus->ub_hcpriv;
usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
@@ -2090,7 +2071,7 @@ ohci_open(usbd_pipe_handle pipe)
int ival;
DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
- pipe, addr, ed->bEndpointAddress, sc->sc_addr));
+ pipe, addr, ed->bEndpointAddress, bus->ub_rhaddr));
if (sc->sc_dying) {
return USBD_IOERROR;
@@ -2099,12 +2080,12 @@ ohci_open(usbd_pipe_handle pipe)
std = NULL;
sed = NULL;
- if (addr == sc->sc_addr) {
+ if (addr == bus->ub_rhaddr) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
- pipe->up_methods = &ohci_root_ctrl_methods;
+ pipe->up_methods = &roothub_ctrl_methods;
break;
- case UE_DIR_IN | OHCI_INTR_ENDPT:
+ case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
pipe->up_methods = &ohci_root_intr_methods;
break;
default:
@@ -2394,240 +2375,68 @@ done:
/*
* Data structures and routines to emulate the root hub.
*/
-Static usb_device_descriptor_t ohci_devd = {
- .bLength = USB_DEVICE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x01},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_FSHUB,
- .bMaxPacketSize = 64,
- .idVendor = {0},
- .idProduct = {0},
- .bcdDevice = {0x00,0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .iSerialNumber = 0,
- .bNumConfigurations = 1
-};
-
-Static const usb_config_descriptor_t ohci_confd = {
- .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength = USETWD(
- USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_ATTR_MBO | UC_SELF_POWERED,
- .bMaxPower = 0
-};
-
-Static const usb_interface_descriptor_t ohci_ifcd = {
- .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_FSHUB,
- .iInterface = 0
-};
-
-Static const usb_endpoint_descriptor_t ohci_endpd = {
- .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | OHCI_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize = USETWD(8),
- .bInterval = 255,
-};
-
-Static const usb_hub_descriptor_t ohci_hubd = {
- .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_HUB,
-};
-
-/*
- * Simulate a hardware hub by handling all the necessary requests.
- */
-Static usbd_status
-ohci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- ohci_softc_t *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usbd_status err;
-
- /* Insert last in queue. */
- mutex_enter(&sc->sc_lock);
- err = usb_insert_transfer(xfer);
- mutex_exit(&sc->sc_lock);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)));
-}
-
-Static usbd_status
-ohci_root_ctrl_start(usbd_xfer_handle xfer)
+Static int
+ohci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
+ void *buf, int buflen)
{
- ohci_softc_t *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usb_device_request_t *req;
- void *buf = NULL;
- int port, i;
- int len, value, index, l, totlen = 0;
+ ohci_softc_t *sc = bus->ub_hcpriv;
usb_port_status_t ps;
- usb_hub_descriptor_t hubd;
- usbd_status err;
+ uint16_t len, value, index;
+ int l, totlen = 0;
+ int port, i;
uint32_t v;
if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->ux_rqflags & URQ_REQUEST))
- /* XXX panic */
- return (USBD_INVAL);
-#endif
- req = &xfer->ux_request;
+ return -1;
- DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
- req->bmRequestType, req->bRequest));
+ DPRINTFN(4,("%s: type=0x%02x request=%02x\n", __func__,
+ req->bmRequestType, req->bRequest));
len = UGETW(req->wLength);
value = UGETW(req->wValue);
index = UGETW(req->wIndex);
- if (len != 0)
- buf = xfer->ux_buf;
-
#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(uint8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
+ switch (C(req->bRequest, req->bmRequestType)) {
case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value));
+ DPRINTFN(8,("%s: wValue=0x%04x\n", __func__, value));
if (len == 0)
break;
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(ohci_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &ohci_devd, l);
- break;
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &ohci_confd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ohci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ohci_endpd, l);
+ switch (value) {
+ case C(0, UDESC_DEVICE): {
+ usb_device_descriptor_t devd;
+
+ totlen = min(buflen, sizeof(devd));
+ memcpy(&devd, buf, totlen);
+ USETW(devd.idVendor, sc->sc_id_vendor);
+ memcpy(buf, &devd, totlen);
break;
- case UDESC_STRING:
+ }
+ case C(1, 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,
- sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = usb_makestrdesc(sd, len,
- "OHCI root hub");
- break;
- }
-#undef sd
+ /* Vendor */
+ totlen = usb_makestrdesc(sd, len, sc->sc_vendor);
+ break;
+ case C(2, UDESC_STRING):
+ /* Product */
+ totlen = usb_makestrdesc(sd, len, "OHCI root hub");
break;
+#undef sd
default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(uint8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- 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;
+ /* default from usbroothub */
+ return buflen;
}
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
break;
+
/* Hub requests */
case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
+ DPRINTFN(8, ("%s: UR_CLEAR_PORT_FEATURE "
+ "port=%d feature=%d\n", __func__,
index, value));
if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
port = OHCI_RH_PORT_STATUS(index);
switch(value) {
@@ -2657,8 +2466,7 @@ ohci_root_ctrl_start(usbd_xfer_handle xf
OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
switch(value) {
case UHF_C_PORT_CONNECTION:
@@ -2678,11 +2486,14 @@ ohci_root_ctrl_start(usbd_xfer_handle xf
if (len == 0)
break;
if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
+ usb_hub_descriptor_t hubd;
+
+ totlen = min(buflen, sizeof(hubd));
+ memcpy(&hubd, buf, totlen);
+
v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
- hubd = ohci_hubd;
hubd.bNbrPorts = sc->sc_noport;
USETW(hubd.wHubCharacteristics,
(v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
@@ -2694,47 +2505,40 @@ ohci_root_ctrl_start(usbd_xfer_handle xf
for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
hubd.DeviceRemovable[i++] = (uint8_t)v;
hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
- l = min(len, hubd.bDescLength);
- totlen = l;
- memcpy(buf, &hubd, l);
+ totlen = min(totlen, hubd.bDescLength);
+ memcpy(buf, &hubd, totlen);
break;
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
memset(buf, 0, len); /* ? XXX */
totlen = len;
break;
case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
+ DPRINTFN(8,("%s: get port status i=%d\n", __func__,
index));
if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
+ return -1;
+ }
v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
- DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n",
+ DPRINTFN(8,("%s: port status=0x%04x\n", __func__,
v));
USETW(ps.wPortStatus, v);
USETW(ps.wPortChange, v >> 16);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
+ totlen = min(len, sizeof(ps));
+ memcpy(buf, &ps, totlen);
break;
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
+ return -1;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
port = OHCI_RH_PORT_STATUS(index);
switch(value) {
@@ -2745,15 +2549,14 @@ ohci_root_ctrl_start(usbd_xfer_handle xf
OWRITE4(sc, port, UPS_SUSPEND);
break;
case UHF_PORT_RESET:
- DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n",
+ DPRINTFN(5,("%s: reset port %d\n", __func__,
index));
OWRITE4(sc, port, UPS_RESET);
for (i = 0; i < 5; i++) {
usb_delay_ms(&sc->sc_bus,
USB_PORT_ROOT_RESET_DELAY);
if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
if ((OREAD4(sc, port) & UPS_RESET) == 0)
break;
@@ -2762,42 +2565,20 @@ ohci_root_ctrl_start(usbd_xfer_handle xf
index, OREAD4(sc, port)));
break;
case UHF_PORT_POWER:
- DPRINTFN(2,("ohci_root_ctrl_transfer: set port power "
- "%d\n", index));
+ DPRINTFN(2,("%s: set port power "
+ "%d\n", __func__, index));
OWRITE4(sc, port, UPS_PORT_POWER);
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ /* default from usbroothub */
+ return buflen;
}
- xfer->ux_actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- xfer->ux_status = err;
- mutex_enter(&sc->sc_lock);
- usb_transfer_complete(xfer);
- mutex_exit(&sc->sc_lock);
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a root control request. */
-Static void
-ohci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-/* Close the root pipe. */
-Static void
-ohci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(("ohci_root_ctrl_close\n"));
- /* Nothing to do. */
+ return totlen;
}
Static usbd_status
Index: src/sys/dev/usb/ohcivar.h
diff -u src/sys/dev/usb/ohcivar.h:1.55.6.2 src/sys/dev/usb/ohcivar.h:1.55.6.3
--- src/sys/dev/usb/ohcivar.h:1.55.6.2 Tue Dec 2 09:00:33 2014
+++ src/sys/dev/usb/ohcivar.h Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ohcivar.h,v 1.55.6.2 2014/12/02 09:00:33 skrll Exp $ */
+/* $NetBSD: ohcivar.h,v 1.55.6.3 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -109,8 +109,6 @@ typedef struct ohci_softc {
LIST_HEAD(, ohci_soft_itd) sc_hash_itds[OHCI_HASH_SIZE];
int sc_noport;
- uint8_t sc_addr; /* device address */
- uint8_t sc_conf; /* device configuration */
int sc_endian;
#define OHCI_LITTLE_ENDIAN 0 /* typical (uninitialized default) */
Index: src/sys/dev/usb/uhci.c
diff -u src/sys/dev/usb/uhci.c:1.264.4.11 src/sys/dev/usb/uhci.c:1.264.4.12
--- src/sys/dev/usb/uhci.c:1.264.4.11 Wed Dec 3 23:05:06 2014
+++ src/sys/dev/usb/uhci.c Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: uhci.c,v 1.264.4.11 2014/12/03 23:05:06 skrll Exp $ */
+/* $NetBSD: uhci.c,v 1.264.4.12 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.264.4.11 2014/12/03 23:05:06 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.264.4.12 2014/12/04 08:04:31 skrll Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -168,6 +168,8 @@ Static void uhci_device_isoc_enter(usbd
Static usbd_xfer_handle uhci_allocx(struct usbd_bus *);
Static void uhci_freex(struct usbd_bus *, usbd_xfer_handle);
Static void uhci_get_lock(struct usbd_bus *, kmutex_t **);
+Static int uhci_roothub_ctrl(struct usbd_bus *,
+ usb_device_request_t *, void *, int);
Static usbd_status uhci_device_ctrl_transfer(usbd_xfer_handle);
Static usbd_status uhci_device_ctrl_start(usbd_xfer_handle);
@@ -193,12 +195,6 @@ Static void uhci_device_isoc_abort(usbd
Static void uhci_device_isoc_close(usbd_pipe_handle);
Static void uhci_device_isoc_done(usbd_xfer_handle);
-Static usbd_status uhci_root_ctrl_transfer(usbd_xfer_handle);
-Static usbd_status uhci_root_ctrl_start(usbd_xfer_handle);
-Static void uhci_root_ctrl_abort(usbd_xfer_handle);
-Static void uhci_root_ctrl_close(usbd_pipe_handle);
-Static void uhci_root_ctrl_done(usbd_xfer_handle);
-
Static usbd_status uhci_root_intr_transfer(usbd_xfer_handle);
Static usbd_status uhci_root_intr_start(usbd_xfer_handle);
Static void uhci_root_intr_abort(usbd_xfer_handle);
@@ -277,8 +273,6 @@ UREAD4(uhci_softc_t *sc, bus_size_t r)
#define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
-#define UHCI_INTR_ENDPT 1
-
const struct usbd_bus_methods uhci_bus_methods = {
.ubm_open = uhci_open,
.ubm_softint = uhci_softintr,
@@ -286,16 +280,7 @@ const struct usbd_bus_methods uhci_bus_m
.ubm_allocx = uhci_allocx,
.ubm_freex = uhci_freex,
.ubm_getlock = uhci_get_lock,
- .ubm_newdev = NULL,
-};
-
-const struct usbd_pipe_methods uhci_root_ctrl_methods = {
- .upm_transfer = uhci_root_ctrl_transfer,
- .upm_start = uhci_root_ctrl_start,
- .upm_abort = uhci_root_ctrl_abort,
- .upm_close = uhci_root_ctrl_close,
- .upm_cleartoggle = uhci_noop,
- .upm_done = uhci_root_ctrl_done,
+ .ubm_rhctrl = uhci_roothub_ctrl,
};
const struct usbd_pipe_methods uhci_root_intr_methods = {
@@ -969,11 +954,6 @@ uhci_root_intr_done(usbd_xfer_handle xfe
{
}
-void
-uhci_root_ctrl_done(usbd_xfer_handle xfer)
-{
-}
-
/*
* Let the last QH loop back to the high speed control transfer QH.
* This is what intel calls "bandwidth reclamation" and improves
@@ -3245,6 +3225,7 @@ usbd_status
uhci_open(usbd_pipe_handle pipe)
{
uhci_softc_t *sc = pipe->up_dev->ud_bus->ub_hcpriv;
+ struct usbd_bus *bus = pipe->up_dev->ud_bus;
struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
usbd_status err = USBD_NOMEM;
@@ -3252,7 +3233,7 @@ uhci_open(usbd_pipe_handle pipe)
DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
pipe, pipe->up_dev->ud_addr,
- ed->bEndpointAddress, sc->sc_addr));
+ ed->bEndpointAddress, bus->ub_rhaddr));
if (sc->sc_dying)
return USBD_IOERROR;
@@ -3261,12 +3242,12 @@ uhci_open(usbd_pipe_handle pipe)
/* toggle state needed for bulk endpoints */
upipe->nexttoggle = pipe->up_endpoint->ue_toggle;
- if (pipe->up_dev->ud_addr == sc->sc_addr) {
+ if (pipe->up_dev->ud_addr == bus->ub_rhaddr) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
- pipe->up_methods = &uhci_root_ctrl_methods;
+ pipe->up_methods = &roothub_ctrl_methods;
break;
- case UE_DIR_IN | UHCI_INTR_ENDPT:
+ case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
pipe->up_methods = &uhci_root_intr_methods;
break;
default:
@@ -3326,69 +3307,6 @@ uhci_open(usbd_pipe_handle pipe)
/*
* Data structures and routines to emulate the root hub.
*/
-usb_device_descriptor_t uhci_devd = {
- .bLength = USB_DEVICE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x01},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_FSHUB,
- .bMaxPacketSize = 64,
- .idVendor = {0},
- .idProduct = {0},
- .bcdDevice = {0x00,0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .iSerialNumber = 0,
- .bNumConfigurations = 1
-};
-
-const usb_config_descriptor_t uhci_confd = {
- .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength = USETWD(
- USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_ATTR_MBO | UC_SELF_POWERED,
- .bMaxPower = 0
-};
-
-const usb_interface_descriptor_t uhci_ifcd = {
- .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_FSHUB,
- .iInterface = 0
-};
-
-const usb_endpoint_descriptor_t uhci_endpd = {
- .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | UHCI_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize = USETWD(8),
- .bInterval = 255
-};
-
-const usb_hub_descriptor_t uhci_hubd_piix = {
- .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 2,
- .wHubCharacteristics = USETWD(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL),
- .bPwrOn2PwrGood = 50,
- .bHubContrCurrent = 0,
- .DeviceRemovable = { 0x00 },
- .PortPowerCtrlMask = { 0 },
-};
-
/*
* The USB hub protocol requires that SET_FEATURE(PORT_RESET) also
* enables the port, and also states that SET_FEATURE(PORT_ENABLE)
@@ -3484,187 +3402,72 @@ uhci_portreset(uhci_softc_t *sc, int ind
return (USBD_NORMAL_COMPLETION);
}
-/*
- * Simulate a hardware hub by handling all the necessary requests.
- */
-usbd_status
-uhci_root_ctrl_transfer(usbd_xfer_handle xfer)
+Static int
+uhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
+ void *buf, int buflen)
{
- uhci_softc_t *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usbd_status err;
-
- /* Insert last in queue. */
- mutex_enter(&sc->sc_lock);
- err = usb_insert_transfer(xfer);
- mutex_exit(&sc->sc_lock);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)));
-}
-
-usbd_status
-uhci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- uhci_softc_t *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usb_device_request_t *req;
- void *buf = NULL;
+ uhci_softc_t *sc = bus->ub_hcpriv;
int port, x;
- int len, value, index, status, change, l, totlen = 0;
+ int status, change, totlen = 0;
+ uint16_t len, value, index;
usb_port_status_t ps;
usbd_status err;
if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->ux_rqflags & URQ_REQUEST))
- panic("uhci_root_ctrl_start: not a request");
-#endif
- req = &xfer->ux_request;
+ return -1;
- DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
- req->bmRequestType, req->bRequest));
+ DPRINTFN(2,("%s: type=0x%02x request=%02x\n", __func__,
+ req->bmRequestType, req->bRequest));
len = UGETW(req->wLength);
value = UGETW(req->wValue);
index = UGETW(req->wIndex);
- if (len != 0)
- buf = xfer->ux_buf;
-
#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(uint8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
+ switch (C(req->bRequest, req->bmRequestType)) {
case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value));
+ DPRINTFN(2,("%s: wValue=0x%04x\n", __func__, value));
if (len == 0)
break;
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(uhci_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &uhci_devd, l);
- break;
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &uhci_confd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &uhci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &uhci_endpd, l);
+ switch (value) {
+ case C(0, UDESC_DEVICE): {
+ usb_device_descriptor_t devd;
+
+ totlen = min(buflen, sizeof(devd));
+ memcpy(&devd, buf, totlen);
+ USETW(devd.idVendor, sc->sc_id_vendor);
+ memcpy(buf, &devd, totlen);
break;
- case UDESC_STRING:
+ }
+ case C(1, 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,
- sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = usb_makestrdesc(sd, len,
- "UHCI root hub");
- break;
- }
-#undef sd
+ /* Vendor */
+ totlen = usb_makestrdesc(sd, len, sc->sc_vendor);
+ break;
+ case C(2, UDESC_STRING):
+ /* Product */
+ totlen = usb_makestrdesc(sd, len, "UHCI root hub");
break;
+#undef sd
default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(uint8_t *)buf = 0;
- totlen = 1;
+ /* default from usbroothub */
+ return buflen;
}
break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- 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_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- break;
+
/* Hub requests */
case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
+ DPRINTFN(3, ("%s: UR_CLEAR_PORT_FEATURE "
+ "port=%d feature=%d\n", __func__,
index, value));
if (index == 1)
port = UHCI_PORTSC1;
else if (index == 2)
port = UHCI_PORTSC2;
else {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
switch(value) {
case UHF_PORT_ENABLE:
@@ -3699,16 +3502,14 @@ uhci_root_ctrl_start(usbd_xfer_handle xf
break;
case UHF_C_PORT_RESET:
sc->sc_isreset = 0;
- err = USBD_NORMAL_COMPLETION;
- goto ret;
+ return -1;
case UHF_PORT_CONNECTION:
case UHF_PORT_OVER_CURRENT:
case UHF_PORT_POWER:
case UHF_PORT_LOW_SPEED:
case UHF_C_PORT_SUSPEND:
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
break;
case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
@@ -3717,8 +3518,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xf
else if (index == 2)
port = UHCI_PORTSC2;
else {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
if (len > 0) {
*(uint8_t *)buf =
@@ -3731,17 +3531,18 @@ uhci_root_ctrl_start(usbd_xfer_handle xf
if (len == 0)
break;
if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
- l = min(len, USB_HUB_DESCRIPTOR_SIZE);
- totlen = l;
- memcpy(buf, &uhci_hubd_piix, l);
+ usb_hub_descriptor_t hubd;
+
+ totlen = min(buflen, sizeof(hubd));
+ memcpy(&hubd, buf, totlen);
+ hubd.bNbrPorts = 2;
+ memcpy(buf, &hubd, totlen);
break;
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
memset(buf, 0, len);
totlen = len;
@@ -3752,12 +3553,10 @@ uhci_root_ctrl_start(usbd_xfer_handle xf
else if (index == 2)
port = UHCI_PORTSC2;
else {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
x = UREAD2(sc, port);
status = change = 0;
@@ -3782,13 +3581,11 @@ uhci_root_ctrl_start(usbd_xfer_handle xf
change |= UPS_C_PORT_RESET;
USETW(ps.wPortStatus, status);
USETW(ps.wPortChange, change);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
+ totlen = min(len, sizeof(ps));
+ memcpy(buf, &ps, totlen);
break;
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
+ return -1;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
@@ -3797,8 +3594,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xf
else if (index == 2)
port = UHCI_PORTSC2;
else {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
switch(value) {
case UHF_PORT_ENABLE:
@@ -3811,11 +3607,12 @@ uhci_root_ctrl_start(usbd_xfer_handle xf
break;
case UHF_PORT_RESET:
err = uhci_portreset(sc, index);
- goto ret;
+ if (err != USBD_NORMAL_COMPLETION)
+ return -1;
+ return 0;
case UHF_PORT_POWER:
/* Pretend we turned on power */
- err = USBD_NORMAL_COMPLETION;
- goto ret;
+ return 0;
case UHF_C_PORT_CONNECTION:
case UHF_C_PORT_ENABLE:
case UHF_C_PORT_OVER_CURRENT:
@@ -3825,36 +3622,15 @@ uhci_root_ctrl_start(usbd_xfer_handle xf
case UHF_C_PORT_SUSPEND:
case UHF_C_PORT_RESET:
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ /* default from usbroothub */
+ return buflen;
}
- xfer->ux_actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- xfer->ux_status = err;
- mutex_enter(&sc->sc_lock);
- usb_transfer_complete(xfer);
- mutex_exit(&sc->sc_lock);
- return (USBD_IN_PROGRESS);
-}
-/* Abort a root control request. */
-void
-uhci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-
-/* Close the root pipe. */
-void
-uhci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(("uhci_root_ctrl_close\n"));
+ return totlen;
}
/* Abort a root interrupt request. */
Index: src/sys/dev/usb/uhcivar.h
diff -u src/sys/dev/usb/uhcivar.h:1.52.14.2 src/sys/dev/usb/uhcivar.h:1.52.14.3
--- src/sys/dev/usb/uhcivar.h:1.52.14.2 Tue Dec 2 09:00:34 2014
+++ src/sys/dev/usb/uhcivar.h Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: uhcivar.h,v 1.52.14.2 2014/12/02 09:00:34 skrll Exp $ */
+/* $NetBSD: uhcivar.h,v 1.52.14.3 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -159,9 +159,6 @@ typedef struct uhci_softc {
pool_cache_t sc_xferpool; /* free xfer pool */
- uint8_t sc_addr; /* device address */
- uint8_t sc_conf; /* device configuration */
-
uint8_t sc_saved_sof;
uint16_t sc_saved_frnum;
Index: src/sys/dev/usb/usbdivar.h
diff -u src/sys/dev/usb/usbdivar.h:1.109.2.6 src/sys/dev/usb/usbdivar.h:1.109.2.7
--- src/sys/dev/usb/usbdivar.h:1.109.2.6 Wed Dec 3 22:19:50 2014
+++ src/sys/dev/usb/usbdivar.h Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdivar.h,v 1.109.2.6 2014/12/03 22:19:50 skrll Exp $ */
+/* $NetBSD: usbdivar.h,v 1.109.2.7 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -98,6 +98,9 @@ struct usbd_bus_methods {
void (*ubm_getlock)(struct usbd_bus *, kmutex_t **);
usbd_status (*ubm_newdev)(device_t, usbd_bus_handle, int,
int, int, struct usbd_port *);
+
+ int (*ubm_rhctrl)(struct usbd_bus *,
+ usb_device_request_t *, void *, int);
};
struct usbd_pipe_methods {
@@ -159,6 +162,8 @@ struct usbd_bus {
/* Filled by usb driver */
kmutex_t *ub_lock;
struct usbd_device *ub_roothub;
+ uint8_t ub_rhaddr; /* roothub address */
+ uint8_t ub_rhconf; /* roothub configuration */
usbd_device_handle ub_devices[USB_MAX_DEVICES];
kcondvar_t ub_needsexplore_cv;
char ub_needsexplore;/* a hub a signalled a change */
Index: src/sys/dev/usb/usbroothub.c
diff -u src/sys/dev/usb/usbroothub.c:1.1.2.1 src/sys/dev/usb/usbroothub.c:1.1.2.2
--- src/sys/dev/usb/usbroothub.c:1.1.2.1 Wed Dec 3 23:05:06 2014
+++ src/sys/dev/usb/usbroothub.c Thu Dec 4 08:04:31 2014
@@ -1,5 +1,36 @@
-/* $NetBSD: usbroothub.c,v 1.1.2.1 2014/12/03 23:05:06 skrll Exp $ */
+/* $NetBSD: usbroothub.c,v 1.1.2.2 2014/12/04 08:04:31 skrll Exp $ */
+/*-
+ * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson ([email protected]) at
+ * Carlstedt Research & Technology, Jared D. McNeill ([email protected]),
+ * Matthew R. Green ([email protected]) and Nick Hudson.
+ *
+ * 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.
+ */
+
/*
* Copyright (c) 2008
* Matthias Drochner. All rights reserved.
@@ -27,10 +58,42 @@
*/
#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
#include <dev/usb/usbroothub.h>
+#ifdef USB_DEBUG
+#define DPRINTFN(n,fmt,...) do { \
+ if (usbdebug >= (n)) { \
+ printf("%s: " fmt, \
+ __FUNCTION__,## __VA_ARGS__); \
+ } \
+} while (0)
+#define DPRINTF(...) DPRINTFN(1, __VA_ARGS__)
+extern int usbdebug;
+#else
+#define DPRINTF(...) do { } while (0)
+#define DPRINTFN(...) do { } while (0)
+#endif
+
/* helper functions for USB root hub emulation */
+static usbd_status roothub_ctrl_transfer(usbd_xfer_handle);
+static usbd_status roothub_ctrl_start(usbd_xfer_handle);
+static void roothub_ctrl_abort(usbd_xfer_handle);
+static void roothub_ctrl_close(usbd_pipe_handle);
+static void roothub_ctrl_done(usbd_xfer_handle);
+static void roothub_noop(usbd_pipe_handle pipe);
+
+const struct usbd_pipe_methods roothub_ctrl_methods = {
+ .upm_transfer = roothub_ctrl_transfer,
+ .upm_start = roothub_ctrl_start,
+ .upm_abort = roothub_ctrl_abort,
+ .upm_close = roothub_ctrl_close,
+ .upm_cleartoggle = roothub_noop,
+ .upm_done = roothub_ctrl_done,
+};
+
int
usb_makestrdesc(usb_string_descriptor_t *p, int l, const char *s)
{
@@ -59,8 +122,378 @@ usb_makelangtbl(usb_string_descriptor_t
if (l == 1)
return (1);
p->bDescriptorType = UDESC_STRING;
- if (l < 4)
+ if (l < 4)
return (2);
USETW(p->bString[0], 0x0409); /* english/US */
return (4);
}
+
+/*
+ * Data structures and routines to emulate the root hub.
+ */
+static const usb_device_descriptor_t usbroothub_devd1 = {
+ .bLength = sizeof(usb_device_descriptor_t),
+ .bDescriptorType = UDESC_DEVICE,
+ .bcdUSB = {0x00, 0x01},
+ .bDeviceClass = UDCLASS_HUB,
+ .bDeviceSubClass = UDSUBCLASS_HUB,
+ .bDeviceProtocol = UDPROTO_FSHUB,
+ .bMaxPacketSize = 64,
+ .idVendor = {0},
+ .idProduct = {0},
+ .bcdDevice = {0x00, 0x01},
+ .iManufacturer = 1,
+ .iProduct = 2,
+ .iSerialNumber = 0,
+ .bNumConfigurations = 1
+};
+
+static const struct usb_roothub_descriptors usbroothub_confd1 = {
+ .urh_confd = {
+ .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
+ .bDescriptorType = UDESC_CONFIG,
+ .wTotalLength = USETWD(sizeof(usbroothub_confd1)),
+ .bNumInterface = 1,
+ .bConfigurationValue = 1,
+ .iConfiguration = 0,
+ .bmAttributes = UC_ATTR_MBO | UC_SELF_POWERED,
+ .bMaxPower = 0,
+ },
+ .urh_ifcd = {
+ .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
+ .bDescriptorType = UDESC_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = UICLASS_HUB,
+ .bInterfaceSubClass = UISUBCLASS_HUB,
+ .bInterfaceProtocol = UIPROTO_FSHUB,
+ .iInterface = 0
+ },
+ .urh_endpd = {
+ .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
+ .bDescriptorType = UDESC_ENDPOINT,
+ .bEndpointAddress = UE_DIR_IN | USBROOTHUB_INTR_ENDPT,
+ .bmAttributes = UE_INTERRUPT,
+ .wMaxPacketSize = USETWD(8), /* max packet */
+ .bInterval = 255,
+ },
+};
+
+static const usb_device_descriptor_t usbroothub_devd2 = {
+ .bLength = sizeof(usb_device_descriptor_t),
+ .bDescriptorType = UDESC_DEVICE,
+ .bcdUSB = {0x00, 0x02},
+ .bDeviceClass = UDCLASS_HUB,
+ .bDeviceSubClass = UDSUBCLASS_HUB,
+ .bDeviceProtocol = UDPROTO_HSHUBSTT,
+ .bMaxPacketSize = 64,
+ .idVendor = {0},
+ .idProduct = {0},
+ .bcdDevice = {0x00, 0x01},
+ .iManufacturer = 1,
+ .iProduct = 2,
+ .iSerialNumber = 0,
+ .bNumConfigurations = 1
+};
+
+static const usb_device_qualifier_t usbroothub_odevd2 = {
+ .bLength = USB_DEVICE_QUALIFIER_SIZE,
+ .bDescriptorType = UDESC_DEVICE_QUALIFIER,
+ .bcdUSB = {0x00, 0x02},
+ .bDeviceClass = UDCLASS_HUB,
+ .bDeviceSubClass = UDSUBCLASS_HUB,
+ .bDeviceProtocol = UDPROTO_FSHUB,
+ .bMaxPacketSize0 = 64,
+ .bNumConfigurations = 1,
+};
+
+static const struct usb_roothub_descriptors usbroothub_confd2 = {
+ .urh_confd = {
+ .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
+ .bDescriptorType = UDESC_CONFIG,
+ .wTotalLength = USETWD(sizeof(usbroothub_confd2)),
+ .bNumInterface = 1,
+ .bConfigurationValue = 1,
+ .iConfiguration = 0,
+ .bmAttributes = UC_ATTR_MBO | UC_SELF_POWERED,
+ .bMaxPower = 0,
+ },
+ .urh_ifcd = {
+ .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
+ .bDescriptorType = UDESC_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = UICLASS_HUB,
+ .bInterfaceSubClass = UISUBCLASS_HUB,
+ .bInterfaceProtocol = UIPROTO_HSHUBSTT,
+ .iInterface = 0
+ },
+ .urh_endpd = {
+ .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
+ .bDescriptorType = UDESC_ENDPOINT,
+ .bEndpointAddress = UE_DIR_IN | USBROOTHUB_INTR_ENDPT,
+ .bmAttributes = UE_INTERRUPT,
+ .wMaxPacketSize = USETWD(8), /* max packet */
+ .bInterval = 12,
+ },
+};
+
+static const usb_hub_descriptor_t usbroothub_hubd = {
+ .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
+ .bDescriptorType = UDESC_HUB,
+ .bNbrPorts = 1,
+ .wHubCharacteristics = USETWD(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL),
+ .bPwrOn2PwrGood = 50,
+ .bHubContrCurrent = 0,
+ .DeviceRemovable = {0}, /* port is removable */
+};
+
+/*
+ * Simulate a hardware hub by handling all the necessary requests.
+ */
+usbd_status
+roothub_ctrl_transfer(usbd_xfer_handle xfer)
+{
+ usbd_pipe_handle pipe = xfer->ux_pipe;
+ struct usbd_bus *bus = pipe->up_dev->ud_bus;
+ usbd_status err;
+
+ /* Insert last in queue. */
+ mutex_enter(bus->ub_lock);
+ err = usb_insert_transfer(xfer);
+ mutex_exit(bus->ub_lock);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running, start first */
+ return roothub_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
+}
+
+static usbd_status
+roothub_ctrl_start(usbd_xfer_handle xfer)
+{
+ usbd_pipe_handle pipe = xfer->ux_pipe;
+ struct usbd_bus *bus = pipe->up_dev->ud_bus;
+ usb_device_request_t *req;
+ usbd_status err = USBD_IOERROR; /* XXX STALL? */
+ uint16_t len, value;
+ int buflen, actlen;
+ void *buf;
+
+ KASSERT(xfer->ux_rqflags & URQ_REQUEST);
+ req = &xfer->ux_request;
+
+ DPRINTFN(4, "type=%#2x request=%#2x\n",
+ req->bmRequestType, req->bRequest);
+
+ len = UGETW(req->wLength);
+ value = UGETW(req->wValue);
+
+ buf = len ? usbd_get_buffer(xfer) : NULL;
+ buflen = 0;
+
+#define C(x,y) ((x) | ((y) << 8))
+ switch (C(req->bRequest, req->bmRequestType)) {
+ case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
+ case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
+ case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
+ /*
+ * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
+ * for the integrated root hub.
+ */
+ break;
+ case C(UR_GET_CONFIG, UT_READ_DEVICE):
+ if (len > 0) {
+ uint8_t *out = buf;
+
+ *out = bus->ub_rhconf;
+ buflen = sizeof(*out);
+ }
+ break;
+ case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
+ DPRINTFN(8, "wValue=%#4x\n", value);
+
+ if (len == 0)
+ break;
+ switch (value) {
+ case C(0, UDESC_DEVICE):
+ if (bus->ub_revision == USBREV_2_0) {
+ buflen = min(len, sizeof(usbroothub_devd2));
+ memcpy(buf, &usbroothub_devd2, buflen);
+ } else {
+ buflen = min(len, sizeof(usbroothub_devd1));
+ memcpy(buf, &usbroothub_devd1, buflen);
+ }
+ break;
+ case C(0, UDESC_CONFIG):
+ if (bus->ub_revision == USBREV_2_0) {
+ buflen = min(len, sizeof(usbroothub_confd2));
+ memcpy(buf, &usbroothub_confd2, buflen);
+ } else {
+ buflen = min(len, sizeof(usbroothub_confd1));
+ memcpy(buf, &usbroothub_confd1, buflen);
+ }
+ break;
+ case C(0, UDESC_DEVICE_QUALIFIER):
+ if (bus->ub_revision == USBREV_2_0) {
+ /*
+ * We can't really operate at another speed,
+ * but the spec says we need this descriptor.
+ */
+ buflen = min(len, sizeof(usbroothub_odevd2));
+ memcpy(buf, &usbroothub_odevd2, buflen);
+ } else
+ goto fail;
+ break;
+ case C(0, UDESC_OTHER_SPEED_CONFIGURATION):
+ if (bus->ub_revision == USBREV_2_0) {
+ struct usb_roothub_descriptors confd;
+
+ /*
+ * We can't really operate at another speed,
+ * but the spec says we need this descriptor.
+ */
+ buflen = min(len, sizeof(usbroothub_confd2));
+ memcpy(&confd, &usbroothub_confd2, buflen);
+ confd.urh_confd.bDescriptorType =
+ UDESC_OTHER_SPEED_CONFIGURATION;
+ memcpy(buf, &confd, buflen);
+ } else
+ goto fail;
+ break;
+#define sd ((usb_string_descriptor_t *)buf)
+ case C(0, UDESC_STRING):
+ /* Language table */
+ buflen = usb_makelangtbl(sd, len);
+ break;
+ case C(1, UDESC_STRING):
+ /* Vendor */
+ buflen = usb_makestrdesc(sd, len, "NetBSD");
+ break;
+ case C(2, UDESC_STRING):
+ /* Product */
+ buflen = usb_makestrdesc(sd, len, "Root hub");
+ break;
+#undef sd
+ default:
+ /* Default to error */
+ buflen = -1;
+ }
+ break;
+ case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
+ buflen = min(len, sizeof(usbroothub_hubd));
+ memcpy(buf, &usbroothub_hubd, buflen);
+ break;
+ case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
+ /* Get Interface, 9.4.4 */
+ if (len > 0) {
+ uint8_t *out = buf;
+
+ *out = 0;
+ buflen = sizeof(*out);
+ }
+ break;
+ case C(UR_GET_STATUS, UT_READ_DEVICE):
+ /* Get Status from device, 9.4.5 */
+ if (len > 1) {
+ usb_status_t *out = buf;
+
+ USETW(out->wStatus, UDS_SELF_POWERED);
+ buflen = sizeof(*out);
+ }
+ break;
+ case C(UR_GET_STATUS, UT_READ_INTERFACE):
+ case C(UR_GET_STATUS, UT_READ_ENDPOINT):
+ /* Get Status from interface, endpoint, 9.4.5 */
+ if (len > 1) {
+ usb_status_t *out = buf;
+
+ USETW(out->wStatus, 0);
+ buflen = sizeof(*out);
+ }
+ break;
+ case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
+ /* Set Address, 9.4.6 */
+ DPRINTF("UR_SET_ADDRESS, UT_WRITE_DEVICE: addr %d\n",
+ value);
+ if (value >= USB_MAX_DEVICES) {
+ goto fail;
+ }
+ bus->ub_rhaddr = value;
+ break;
+ case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
+ /* Set Configuration, 9.4.7 */
+ if (value != 0 && value != 1) {
+ goto fail;
+ }
+ bus->ub_rhconf = value;
+ break;
+ case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
+ /* Set Descriptor, 9.4.8, not supported */
+ break;
+ case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
+ case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
+ case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
+ /* Set Feature, 9.4.9, not supported */
+ goto fail;
+ case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
+ /* Set Interface, 9.4.10, not supported */
+ break;
+ case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
+ /* Synch Frame, 9.4.11, not supported */
+ break;
+ default:
+ /* Default to error */
+ buflen = -1;
+ break;
+ }
+
+ actlen = bus->ub_methods->ubm_rhctrl(bus, req, buf, buflen);
+ if (actlen < 0)
+ goto fail;
+
+ xfer->ux_actlen = actlen;
+ err = USBD_NORMAL_COMPLETION;
+
+ fail:
+ xfer->ux_status = err;
+ mutex_enter(bus->ub_lock);
+ usb_transfer_complete(xfer);
+ mutex_exit(bus->ub_lock);
+
+ return USBD_IN_PROGRESS;
+}
+
+/* Abort a root control request. */
+Static void
+roothub_ctrl_abort(usbd_xfer_handle xfer)
+{
+
+ DPRINTF("\n");
+ /* Nothing to do, all transfers are synchronous. */
+}
+
+/* Close the root pipe. */
+Static void
+roothub_ctrl_close(usbd_pipe_handle pipe)
+{
+
+ DPRINTF("\n");
+ /* Nothing to do. */
+}
+
+Static void
+roothub_ctrl_done(usbd_xfer_handle xfer)
+{
+
+ DPRINTF("\n");
+ /* Nothing to do. */
+}
+
+static void
+roothub_noop(usbd_pipe_handle pipe)
+{
+
+}
Index: src/sys/dev/usb/usbroothub.h
diff -u src/sys/dev/usb/usbroothub.h:1.1.2.1 src/sys/dev/usb/usbroothub.h:1.1.2.2
--- src/sys/dev/usb/usbroothub.h:1.1.2.1 Wed Dec 3 23:05:06 2014
+++ src/sys/dev/usb/usbroothub.h Thu Dec 4 08:04:31 2014
@@ -1,4 +1,43 @@
-/* $NetBSD: usbroothub.h,v 1.1.2.1 2014/12/03 23:05:06 skrll Exp $ */
+/* $NetBSD: usbroothub.h,v 1.1.2.2 2014/12/04 08:04:31 skrll Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nick Hudson
+ *
+ * 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.
+ */
int usb_makestrdesc(usb_string_descriptor_t *, int, const char *);
int usb_makelangtbl(usb_string_descriptor_t *, int);
+
+struct usb_roothub_descriptors {
+ usb_config_descriptor_t urh_confd;
+ usb_interface_descriptor_t urh_ifcd;
+ usb_endpoint_descriptor_t urh_endpd;
+};
+
+#define USBROOTHUB_INTR_ENDPT 1
+
+extern const struct usbd_pipe_methods roothub_ctrl_methods;
Index: src/sys/dev/usb/xhci.c
diff -u src/sys/dev/usb/xhci.c:1.28.2.11 src/sys/dev/usb/xhci.c:1.28.2.12
--- src/sys/dev/usb/xhci.c:1.28.2.11 Wed Dec 3 23:05:06 2014
+++ src/sys/dev/usb/xhci.c Thu Dec 4 08:04:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: xhci.c,v 1.28.2.11 2014/12/03 23:05:06 skrll Exp $ */
+/* $NetBSD: xhci.c,v 1.28.2.12 2014/12/04 08:04:31 skrll Exp $ */
/*
* Copyright (c) 2013 Jonathan A. Kollasch
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.11 2014/12/03 23:05:06 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.12 2014/12/04 08:04:31 skrll Exp $");
#include "opt_usb.h"
@@ -108,7 +108,6 @@ struct xhci_pipe {
struct usbd_pipe xp_pipe;
};
-#define XHCI_INTR_ENDPT 1
#define XHCI_COMMAND_RING_TRBS 256
#define XHCI_EVENT_RING_TRBS 256
#define XHCI_EVENT_RING_SEGMENTS 1
@@ -123,6 +122,8 @@ static void xhci_freex(struct usbd_bus *
static void xhci_get_lock(struct usbd_bus *, kmutex_t **);
static usbd_status xhci_new_device(device_t, usbd_bus_handle, int, int, int,
struct usbd_port *);
+static int xhci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *,
+ void *, int);
static usbd_status xhci_configure_endpoint(usbd_pipe_handle);
static usbd_status xhci_unconfigure_endpoint(usbd_pipe_handle);
@@ -147,12 +148,6 @@ static void xhci_ring_free(struct xhci_s
static void xhci_noop(usbd_pipe_handle);
-static usbd_status xhci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status xhci_root_ctrl_start(usbd_xfer_handle);
-static void xhci_root_ctrl_abort(usbd_xfer_handle);
-static void xhci_root_ctrl_close(usbd_pipe_handle);
-static void xhci_root_ctrl_done(usbd_xfer_handle);
-
static usbd_status xhci_root_intr_transfer(usbd_xfer_handle);
static usbd_status xhci_root_intr_start(usbd_xfer_handle);
static void xhci_root_intr_abort(usbd_xfer_handle);
@@ -188,15 +183,7 @@ static const struct usbd_bus_methods xhc
.ubm_freex = xhci_freex,
.ubm_getlock = xhci_get_lock,
.ubm_newdev = xhci_new_device,
-};
-
-static const struct usbd_pipe_methods xhci_root_ctrl_methods = {
- .upm_transfer = xhci_root_ctrl_transfer,
- .upm_start = xhci_root_ctrl_start,
- .upm_abort = xhci_root_ctrl_abort,
- .upm_close = xhci_root_ctrl_close,
- .upm_cleartoggle = xhci_noop,
- .upm_done = xhci_root_ctrl_done,
+ .ubm_rhctrl = xhci_roothub_ctrl,
};
static const struct usbd_pipe_methods xhci_root_intr_methods = {
@@ -1138,9 +1125,9 @@ xhci_open(usbd_pipe_handle pipe)
dev->ud_speed != USB_SPEED_SUPER) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
- pipe->up_methods = &xhci_root_ctrl_methods;
+ pipe->up_methods = &roothub_ctrl_methods;
break;
- case UE_DIR_IN | XHCI_INTR_ENDPT:
+ case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
pipe->up_methods = &xhci_root_intr_methods;
break;
default:
@@ -1997,255 +1984,47 @@ xhci_noop(usbd_pipe_handle pipe)
XHCIHIST_FUNC(); XHCIHIST_CALLED();
}
-/* root hub descriptors */
-
-static const usb_device_descriptor_t xhci_devd = {
- .bLength = USB_DEVICE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_HSHUBSTT,
- .bMaxPacketSize = 64,
- .idVendor = {0},
- .idProduct = {0},
- .bcdDevice = {0x00,0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .iSerialNumber = 0,
- .bNumConfigurations = 1
-};
-
-static const usb_device_qualifier_t xhci_odevd = {
- .bLength = USB_DEVICE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_DEVICE_QUALIFIER,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_FSHUB,
- .bMaxPacketSize0 = 64,
- .bNumConfigurations = 1,
-};
-
-static const usb_config_descriptor_t xhci_confd = {
- .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength = USETWD(
- USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_ATTR_MBO | UC_SELF_POWERED,
- .bMaxPower = 0
-};
-
-static const usb_interface_descriptor_t xhci_ifcd = {
- .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_HSHUBSTT,
- .iInterface = 0
-};
-
-static const usb_endpoint_descriptor_t xhci_endpd = {
- .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | XHCI_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize = USETWD(8),
- .bInterval = 12
-};
-
-static const usb_hub_descriptor_t xhci_hubd = {
- .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 0,
- .wHubCharacteristics = USETWD(0),
- .bPwrOn2PwrGood = 0,
- .bHubContrCurrent = 0,
- .DeviceRemovable = {""},
- .PortPowerCtrlMask = {""},
-};
-
-/* root hub control */
-
-static usbd_status
-xhci_root_ctrl_transfer(usbd_xfer_handle xfer)
+static int xhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
+ void *buf, int buflen)
{
- struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usbd_status err;
-
- XHCIHIST_FUNC(); XHCIHIST_CALLED();
-
- /* Insert last in queue. */
- mutex_enter(&sc->sc_lock);
- err = usb_insert_transfer(xfer);
- mutex_exit(&sc->sc_lock);
- if (err)
- return err;
-
- /* Pipe isn't running, start first */
- return (xhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)));
-}
-
-static usbd_status
-xhci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- struct xhci_softc * const sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
+ struct xhci_softc * const sc = bus->ub_hcpriv;
usb_port_status_t ps;
- usb_device_request_t *req;
- void *buf = NULL;
- usb_hub_descriptor_t hubd;
- usbd_status err;
- int len, value, index;
int l, totlen = 0;
+ uint16_t len, value, index;
int port, i;
uint32_t v;
XHCIHIST_FUNC(); XHCIHIST_CALLED();
if (sc->sc_dying)
- return USBD_IOERROR;
-
- req = &xfer->ux_request;
+ return -1;
+ len = UGETW(req->wLength);
value = UGETW(req->wValue);
index = UGETW(req->wIndex);
- len = UGETW(req->wLength);
-
- if (len != 0)
- buf = xfer->ux_buf;
DPRINTFN(12, "rhreq: %04x %04x %04x %04x",
req->bmRequestType | (req->bRequest << 8), value, index, len);
#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(uint8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
+ switch (C(req->bRequest, req->bmRequestType)) {
case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
DPRINTFN(8, "getdesc: wValue=0x%04x", value, 0, 0, 0);
if (len == 0)
break;
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- memcpy(buf, &xhci_devd, min(l, sizeof(xhci_devd)));
- break;
- case UDESC_DEVICE_QUALIFIER:
- if ((value & 0xff) != 0) {
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- memcpy(buf, &xhci_odevd, min(l, sizeof(xhci_odevd)));
- break;
- case UDESC_OTHER_SPEED_CONFIGURATION:
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &xhci_confd, min(l, sizeof(xhci_confd)));
- ((usb_config_descriptor_t *)buf)->bDescriptorType =
- value >> 8;
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &xhci_ifcd, min(l, sizeof(xhci_ifcd)));
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &xhci_endpd, min(l, sizeof(xhci_endpd)));
- break;
- case UDESC_STRING:
+ switch (value) {
#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, "NetBSD");
- break;
- case 2: /* Product */
- totlen = usb_makestrdesc(sd, len,
- "xHCI Root Hub");
- break;
- }
-#undef sd
+ case C(2, UDESC_STRING):
+ /* Product */
+ totlen = usb_makestrdesc(sd, len, "xHCI Root Hub");
break;
+#undef sd
default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(uint8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- 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;
+ /* default from usbroothub */
+ return buflen;
}
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
break;
+
/* Hub requests */
case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
@@ -2253,8 +2032,7 @@ xhci_root_ctrl_start(usbd_xfer_handle xf
DPRINTFN(4, "UR_CLEAR_PORT_FEATURE port=%d feature=%d",
index, value, 0, 0);
if (index < 1 || index > sc->sc_hs_port_count) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
port = XHCI_PORTSC(sc->sc_hs_port_start - 1 + index);
v = xhci_op_read_4(sc, port);
@@ -2265,53 +2043,48 @@ xhci_root_ctrl_start(usbd_xfer_handle xf
xhci_op_write_4(sc, port, v &~ XHCI_PS_PED);
break;
case UHF_PORT_SUSPEND:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
case UHF_PORT_POWER:
break;
case UHF_PORT_TEST:
case UHF_PORT_INDICATOR:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
case UHF_C_PORT_CONNECTION:
xhci_op_write_4(sc, port, v | XHCI_PS_CSC);
break;
case UHF_C_PORT_ENABLE:
case UHF_C_PORT_SUSPEND:
case UHF_C_PORT_OVER_CURRENT:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
case UHF_C_PORT_RESET:
xhci_op_write_4(sc, port, v | XHCI_PS_PRC);
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
-
break;
case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
if (len == 0)
break;
if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
- hubd = xhci_hubd;
+ usb_hub_descriptor_t hubd;
+
+ totlen = min(buflen, sizeof(hubd));
+ memcpy(&hubd, buf, totlen);
hubd.bNbrPorts = sc->sc_hs_port_count;
USETW(hubd.wHubCharacteristics, UHD_PWR_NO_SWITCH);
hubd.bPwrOn2PwrGood = 200;
for (i = 0, l = sc->sc_maxports; l > 0; i++, l -= 8)
hubd.DeviceRemovable[i++] = 0; /* XXX can't find out? */
hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
- l = min(len, hubd.bDescLength);
- totlen = l;
- memcpy(buf, &hubd, l);
+ totlen = min(totlen, hubd.bDescLength);
+ memcpy(buf, &hubd, totlen);
break;
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
memset(buf, 0, len); /* ? XXX */
totlen = len;
@@ -2319,12 +2092,10 @@ xhci_root_ctrl_start(usbd_xfer_handle xf
case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
DPRINTFN(8, "get port status i=%d", index, 0, 0, 0);
if (index < 1 || index > sc->sc_maxports) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
v = xhci_op_read_4(sc, XHCI_PORTSC(sc->sc_hs_port_start - 1 +
index));
@@ -2357,19 +2128,16 @@ xhci_root_ctrl_start(usbd_xfer_handle xf
if (v & XHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR;
if (v & XHCI_PS_PRC) i |= UPS_C_PORT_RESET;
USETW(ps.wPortChange, i);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
+ totlen = min(len, sizeof(ps));
+ memcpy(buf, &ps, totlen);
break;
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
+ return -1;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
if (index < 1 || index > sc->sc_hs_port_count) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
port = XHCI_PORTSC(sc->sc_hs_port_start - 1 + index);
v = xhci_op_read_4(sc, port);
@@ -2388,8 +2156,7 @@ xhci_root_ctrl_start(usbd_xfer_handle xf
/* Wait for reset to complete. */
usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
v = xhci_op_read_4(sc, port);
if (v & XHCI_PS_PR) {
@@ -2406,8 +2173,7 @@ xhci_root_ctrl_start(usbd_xfer_handle xf
xhci_op_write_4(sc, port, v | XHCI_PS_PRC);
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ return -1;
}
break;
case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER):
@@ -2416,44 +2182,14 @@ xhci_root_ctrl_start(usbd_xfer_handle xf
case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
break;
default:
- err = USBD_IOERROR;
- goto ret;
+ /* default from usbroothub */
+ return buflen;
}
- xfer->ux_actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
-ret:
- xfer->ux_status = err;
- mutex_enter(&sc->sc_lock);
- usb_transfer_complete(xfer);
- mutex_exit(&sc->sc_lock);
- return USBD_IN_PROGRESS;
-}
-
-
-static void
-xhci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- XHCIHIST_FUNC(); XHCIHIST_CALLED();
- /* Nothing to do, all transfers are synchronous. */
-}
-
-
-static void
-xhci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- XHCIHIST_FUNC(); XHCIHIST_CALLED();
- /* Nothing to do. */
-}
-static void
-xhci_root_ctrl_done(usbd_xfer_handle xfer)
-{
- XHCIHIST_FUNC(); XHCIHIST_CALLED();
-
- xfer->ux_hcpriv = NULL;
+ return totlen;
}
-/* root hub interrupt */
+/* root hub intrerrupt */
static usbd_status
xhci_root_intr_transfer(usbd_xfer_handle xfer)
Index: src/sys/dev/usb/xhcivar.h
diff -u src/sys/dev/usb/xhcivar.h:1.4.12.1 src/sys/dev/usb/xhcivar.h:1.4.12.2
--- src/sys/dev/usb/xhcivar.h:1.4.12.1 Thu Dec 4 06:57:29 2014
+++ src/sys/dev/usb/xhcivar.h Thu Dec 4 08:04:32 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: xhcivar.h,v 1.4.12.1 2014/12/04 06:57:29 skrll Exp $ */
+/* $NetBSD: xhcivar.h,v 1.4.12.2 2014/12/04 08:04:32 skrll Exp $ */
/*
* Copyright (c) 2013 Jonathan A. Kollasch
@@ -109,9 +109,6 @@ struct xhci_softc {
bool sc_ac64;
bool sc_dying;
-
- uint8_t sc_addr;
- uint8_t sc_conf;
};
int xhci_init(struct xhci_softc *);
Index: src/sys/external/bsd/dwc2/dwc2.c
diff -u src/sys/external/bsd/dwc2/dwc2.c:1.32.2.8 src/sys/external/bsd/dwc2/dwc2.c:1.32.2.9
--- src/sys/external/bsd/dwc2/dwc2.c:1.32.2.8 Wed Dec 3 23:05:06 2014
+++ src/sys/external/bsd/dwc2/dwc2.c Thu Dec 4 08:04:32 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc2.c,v 1.32.2.8 2014/12/03 23:05:06 skrll Exp $ */
+/* $NetBSD: dwc2.c,v 1.32.2.9 2014/12/04 08:04:32 skrll Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.32.2.8 2014/12/03 23:05:06 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.32.2.9 2014/12/04 08:04:32 skrll Exp $");
#include "opt_usb.h"
@@ -50,7 +50,6 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.3
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_mem.h>
-
#include <dev/usb/usbroothub.h>
#include <dwc2/dwc2.h>
@@ -88,12 +87,8 @@ Static void dwc2_waitintr(struct dwc2_s
Static usbd_xfer_handle dwc2_allocx(struct usbd_bus *);
Static void dwc2_freex(struct usbd_bus *, usbd_xfer_handle);
Static void dwc2_get_lock(struct usbd_bus *, kmutex_t **);
-
-Static usbd_status dwc2_root_ctrl_transfer(usbd_xfer_handle);
-Static usbd_status dwc2_root_ctrl_start(usbd_xfer_handle);
-Static void dwc2_root_ctrl_abort(usbd_xfer_handle);
-Static void dwc2_root_ctrl_close(usbd_pipe_handle);
-Static void dwc2_root_ctrl_done(usbd_xfer_handle);
+Static int dwc2_roothub_ctrl(struct usbd_bus *, usb_device_request_t *,
+ void *, int);
Static usbd_status dwc2_root_intr_transfer(usbd_xfer_handle);
Static usbd_status dwc2_root_intr_start(usbd_xfer_handle);
@@ -153,8 +148,6 @@ dwc2_free_bus_bandwidth(struct dwc2_hsot
{
}
-#define DWC2_INTR_ENDPT 1
-
Static const struct usbd_bus_methods dwc2_bus_methods = {
.ubm_open = dwc2_open,
.ubm_softint = dwc2_softintr,
@@ -162,15 +155,7 @@ Static const struct usbd_bus_methods dwc
.ubm_allocx = dwc2_allocx,
.ubm_freex = dwc2_freex,
.ubm_getlock = dwc2_get_lock,
-};
-
-Static const struct usbd_pipe_methods dwc2_root_ctrl_methods = {
- .upm_transfer = dwc2_root_ctrl_transfer,
- .upm_start = dwc2_root_ctrl_start,
- .upm_abort = dwc2_root_ctrl_abort,
- .upm_close = dwc2_root_ctrl_close,
- .upm_cleartoggle = dwc2_noop,
- .upm_done = dwc2_root_ctrl_done,
+ .ubm_rhctrl = dwc2_roothub_ctrl,
};
Static const struct usbd_pipe_methods dwc2_root_intr_methods = {
@@ -421,12 +406,12 @@ dwc2_open(usbd_pipe_handle pipe)
return USBD_IOERROR;
}
- if (addr == sc->sc_addr) {
+ if (addr == dev->ud_bus->ub_rhaddr) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
- pipe->up_methods = &dwc2_root_ctrl_methods;
+ pipe->up_methods = &roothub_ctrl_methods;
break;
- case UE_DIR_IN | DWC2_INTR_ENDPT:
+ case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
pipe->up_methods = &dwc2_root_intr_methods;
break;
default:
@@ -577,104 +562,17 @@ dwc2_device_clear_toggle(usbd_pipe_handl
/***********************************************************************/
-/*
- * Data structures and routines to emulate the root hub.
- */
-
-Static const usb_device_descriptor_t dwc2_devd = {
- .bLength = sizeof(usb_device_descriptor_t),
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_HSHUBSTT,
- .bMaxPacketSize = 64,
- .bcdDevice = {0x00, 0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .bNumConfigurations = 1,
-};
-
-struct dwc2_config_desc {
- usb_config_descriptor_t confd;
- usb_interface_descriptor_t ifcd;
- usb_endpoint_descriptor_t endpd;
-} __packed;
-
-Static const struct dwc2_config_desc dwc2_confd = {
- .confd = {
- .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength = USETWD(sizeof(dwc2_confd)),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 0,
- },
- .ifcd = {
- .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_HSHUBSTT,
- .iInterface = 0
- },
- .endpd = {
- .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | DWC2_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize = USETWD(8), /* max packet */
- .bInterval = 255,
- },
-};
-
-#if 0
-/* appears to be unused */
-Static const usb_hub_descriptor_t dwc2_hubd = {
- .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 1,
- .wHubCharacteristics = USETWD(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL),
- .bPwrOn2PwrGood = 50,
- .bHubContrCurrent = 0,
- .DeviceRemovable = {0}, /* port is removable */
-};
-#endif
-
-Static usbd_status
-dwc2_root_ctrl_transfer(usbd_xfer_handle xfer)
+Static int
+dwc2_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
+ void *buf, int buflen)
{
- struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
- usbd_status err;
-
- mutex_enter(&sc->sc_lock);
- err = usb_insert_transfer(xfer);
- mutex_exit(&sc->sc_lock);
- if (err)
- return err;
-
- return dwc2_root_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
-}
-
-Static usbd_status
-dwc2_root_ctrl_start(usbd_xfer_handle xfer)
-{
- struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
- usb_device_request_t *req;
- uint8_t *buf;
- uint16_t len;
- int value, index, l, totlen;
+ struct dwc2_softc *sc = bus->ub_hcpriv;
usbd_status err = USBD_IOERROR;
+ uint16_t len, value, index;
+ int totlen = 0;
if (sc->sc_dying)
- return USBD_IOERROR;
-
- req = &xfer->ux_request;
+ return -1;
DPRINTFN(4, "type=0x%02x request=%02x\n",
req->bmRequestType, req->bRequest);
@@ -683,153 +581,41 @@ dwc2_root_ctrl_start(usbd_xfer_handle xf
value = UGETW(req->wValue);
index = UGETW(req->wIndex);
- buf = len ? KERNADDR(&xfer->ux_dmabuf, 0) : NULL;
-
- totlen = 0;
-
#define C(x,y) ((x) | ((y) << 8))
switch (C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- 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):
DPRINTFN(8, "wValue=0x%04x\n", value);
if (len == 0)
break;
switch (value) {
- case C(0, UDESC_DEVICE):
- l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
-// USETW(dwc2_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &dwc2_devd, l);
- buf += l;
- len -= l;
- totlen += l;
-
- break;
- case C(0, UDESC_CONFIG):
- l = min(len, sizeof(dwc2_confd));
- memcpy(buf, &dwc2_confd, l);
- buf += l;
- len -= l;
- totlen += l;
-
- break;
#define sd ((usb_string_descriptor_t *)buf)
- case C(0, UDESC_STRING):
- totlen = usb_makelangtbl(sd, len);
- break;
case C(1, UDESC_STRING):
- totlen = usb_makestrdesc(sd, len, sc->sc_vendor);
+ /* Vendor */
+ //totlen = usb_makestrdesc(sd, len, sc->sc_vendor);
break;
case C(2, UDESC_STRING):
+ /* Product */
totlen = usb_makestrdesc(sd, len, "DWC2 root hub");
break;
#undef sd
default:
- goto fail;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
+ /* default from usbroothub */
+ return buflen;
}
break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- DPRINTF("UR_SET_ADDRESS, UT_WRITE_DEVICE: addr %d\n",
- value);
- if (value >= USB_MAX_DEVICES)
- goto fail;
-
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if (value != 0 && value != 1)
- goto fail;
-
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto fail;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- break;
default:
- /* Hub requests - XXXNH len check? */
+ /* Hub requests */
err = dwc2_hcd_hub_control(sc->sc_hsotg,
C(req->bRequest, req->bmRequestType), value, index,
buf, len);
if (err) {
- err = USBD_IOERROR;
- goto fail;
+ return -1;
}
totlen = len;
}
- xfer->ux_actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
-
-fail:
- mutex_enter(&sc->sc_lock);
- xfer->ux_status = err;
- usb_transfer_complete(xfer);
- mutex_exit(&sc->sc_lock);
-
- return USBD_IN_PROGRESS;
-}
-
-Static void
-dwc2_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTFN(10, "\n");
-
- /* Nothing to do, all transfers are synchronous. */
-}
-
-Static void
-dwc2_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTFN(10, "\n");
-
- /* Nothing to do. */
-}
-
-Static void
-dwc2_root_ctrl_done(usbd_xfer_handle xfer)
-{
- DPRINTFN(10, "\n");
- /* Nothing to do. */
+ return totlen;
}
Static usbd_status
Index: src/sys/external/bsd/dwc2/dwc2var.h
diff -u src/sys/external/bsd/dwc2/dwc2var.h:1.3.12.2 src/sys/external/bsd/dwc2/dwc2var.h:1.3.12.3
--- src/sys/external/bsd/dwc2/dwc2var.h:1.3.12.2 Wed Dec 3 12:52:07 2014
+++ src/sys/external/bsd/dwc2/dwc2var.h Thu Dec 4 08:04:32 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc2var.h,v 1.3.12.2 2014/12/03 12:52:07 skrll Exp $ */
+/* $NetBSD: dwc2var.h,v 1.3.12.3 2014/12/04 08:04:32 skrll Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -95,13 +95,8 @@ typedef struct dwc2_softc {
device_t sc_child; /* /dev/usb# device */
char sc_dying;
- char sc_vendor[32]; /* vendor string for root hub */
- int sc_id_vendor; /* vendor ID for root hub */
-
TAILQ_HEAD(, dwc2_xfer) sc_complete; /* complete transfers */
- uint8_t sc_addr; /* device address */
- uint8_t sc_conf; /* device configuration */
pool_cache_t sc_xferpool;
pool_cache_t sc_qhpool;
Index: src/sys/rump/dev/lib/libugenhc/ugenhc.c
diff -u src/sys/rump/dev/lib/libugenhc/ugenhc.c:1.22.4.6 src/sys/rump/dev/lib/libugenhc/ugenhc.c:1.22.4.7
--- src/sys/rump/dev/lib/libugenhc/ugenhc.c:1.22.4.6 Wed Dec 3 23:05:07 2014
+++ src/sys/rump/dev/lib/libugenhc/ugenhc.c Thu Dec 4 08:04:32 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ugenhc.c,v 1.22.4.6 2014/12/03 23:05:07 skrll Exp $ */
+/* $NetBSD: ugenhc.c,v 1.22.4.7 2014/12/04 08:04:32 skrll Exp $ */
/*
* Copyright (c) 2009, 2010 Antti Kantee. All Rights Reserved.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ugenhc.c,v 1.22.4.6 2014/12/03 23:05:07 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ugenhc.c,v 1.22.4.7 2014/12/04 08:04:32 skrll Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -99,8 +99,6 @@ struct ugenhc_softc {
int sc_port_status;
int sc_port_change;
- int sc_addr;
- int sc_conf;
struct lwp *sc_rhintr;
usbd_xfer_handle sc_intrxfer;
@@ -130,144 +128,45 @@ makeugendevstr(int devnum, int endpoint,
snprintf(buf, len, "%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,
- .idVendor = { 0x75, 0x72 },
- .idProduct = { 0x70, 0x6d },
- .bNumConfigurations = 1,
-};
-
-static const usb_config_descriptor_t rumphub_ucd = {
- .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength = USETWD(
- USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE),
- .bNumInterface = 1,
- .bmAttributes = UC_SELF_POWERED | UC_ATTR_MBO,
-};
-
-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 = USETWD(64),
-};
-
-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)
+static int
+ugenhc_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
+ void *buf, int buflen)
{
- usb_device_request_t *req = &xfer->ux_request;
- struct ugenhc_softc *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- int len, totlen, value, curlen, err;
- uint8_t *buf = NULL;
+ struct ugenhc_softc *sc = bus->ub_hcpriv;
+ int totlen = 0;
+ uint16_t len, value;
- len = totlen = UGETW(req->wLength);
- if (len)
- buf = KERNADDR(&xfer->ux_dmabuf, 0);
+ len = UGETW(req->wLength);
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;
-
+ switch (C(req->bRequest, req->bmRequestType)) {
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;
+ switch (value) {
+ case C(0, UDESC_DEVICE): {
+ usb_device_descriptor_t devd;
- 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;
+ totlen = min(buflen, sizeof(devd));
+ memcpy(&devd, buf, totlen);
+ USETW(devd.idVendor, 0x7275);
+ USETW(devd.idProduct, 0x6d72);
+ memcpy(buf, &devd, totlen);
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
+ case C(1, UDESC_STRING):
+ /* Vendor */
+ totlen = usb_makestrdesc(sd, len, "rod nevada");
+ break;
+ case C(2, UDESC_STRING):
+ /* Product */
+ totlen = usb_makestrdesc(sd, len, "RUMPUSBHC root hub");
break;
-
+#undef sd
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;
+ /* default from usbroothub */
+ return buflen;
}
- sc->sc_conf = value;
break;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
@@ -278,7 +177,7 @@ rumpusb_root_ctrl_start(usbd_xfer_handle
case UHF_PORT_POWER:
break;
default:
- panic("unhandled");
+ return -1;
}
break;
@@ -287,8 +186,7 @@ rumpusb_root_ctrl_start(usbd_xfer_handle
break;
case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- totlen = min(len, USB_HUB_DESCRIPTOR_SIZE);
- memcpy(buf, &rumphub_hdd, totlen);
+ totlen = buflen;
break;
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
@@ -297,8 +195,7 @@ rumpusb_root_ctrl_start(usbd_xfer_handle
totlen = len;
break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- {
+ case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): {
usb_port_status_t ps;
USETW(ps.wPortStatus, sc->sc_port_status);
@@ -306,73 +203,16 @@ rumpusb_root_ctrl_start(usbd_xfer_handle
totlen = min(len, sizeof(ps));
memcpy(buf, &ps, totlen);
break;
- }
-
+ }
default:
- panic("unhandled request");
- break;
+ /* default from usbroothub */
+ return buflen;
}
- err = USBD_NORMAL_COMPLETION;
- xfer->ux_actlen = totlen;
-ret:
- xfer->ux_status = err;
- mutex_enter(&sc->sc_lock);
- usb_transfer_complete(xfer);
- mutex_exit(&sc->sc_lock);
-
- return (USBD_IN_PROGRESS);
+ return totlen;
}
static usbd_status
-rumpusb_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- struct ugenhc_softc *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv;
- usbd_status err;
-
- mutex_enter(&sc->sc_lock);
- err = usb_insert_transfer(xfer);
- mutex_exit(&sc->sc_lock);
- if (err)
- return (err);
-
- return (rumpusb_root_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_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 = {
- .upm_transfer = rumpusb_root_ctrl_transfer,
- .upm_start = rumpusb_root_ctrl_start,
- .upm_abort = rumpusb_root_ctrl_abort,
- .upm_close = rumpusb_root_ctrl_close,
- .upm_cleartoggle = rumpusb_root_ctrl_cleartoggle,
- .upm_done = rumpusb_root_ctrl_done,
-};
-
-static usbd_status
rumpusb_device_ctrl_start(usbd_xfer_handle xfer)
{
usb_device_request_t *req = &xfer->ux_request;
@@ -385,7 +225,7 @@ rumpusb_device_ctrl_start(usbd_xfer_hand
len = totlen = UGETW(req->wLength);
if (len)
- buf = KERNADDR(&xfer->ux_dmabuf, 0);
+ buf = xfer->ux_buf;
value = UGETW(req->wValue);
#define C(x,y) ((x) | ((y) << 8))
@@ -955,16 +795,17 @@ ugenhc_open(struct usbd_pipe *pipe)
usbd_device_handle dev = pipe->up_dev;
struct ugenhc_softc *sc = dev->ud_bus->ub_hcpriv;
usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
+ uint8_t rhaddr = dev->ud_bus->ub_rhaddr;
uint8_t addr = dev->ud_addr;
uint8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
char buf[UGENDEV_BUFSIZE];
int endpt, oflags, error;
int fd, val;
- if (addr == sc->sc_addr) {
+ if (addr == rhaddr) {
switch (xfertype) {
case UE_CONTROL:
- pipe->up_methods = &rumpusb_root_ctrl_methods;
+ pipe->up_methods = &roothub_ctrl_methods;
break;
case UE_INTERRUPT:
pipe->up_methods = &rumpusb_root_intr_methods;
@@ -1077,7 +918,8 @@ static const struct usbd_bus_methods uge
.ubm_dopoll = ugenhc_poll,
.ubm_allocx = ugenhc_allocx,
.ubm_freex = ugenhc_freex,
- .ubm_getlock = ugenhc_getlock
+ .ubm_getlock = ugenhc_getlock,
+ .ubm_rhctrl = ugenhc_roothub_ctrl,
};
static int