diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-03-19 10:29:17 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-03-19 10:29:17 +0000 |
commit | 8a2dc096f7398aeaecfb5a2d432e39cac203db40 (patch) | |
tree | 94bf69b6659a7907b6e55452a8f763133aecab91 /sys/dev/usb | |
parent | ac96b236166f8ac2ecd3cd82b494036fbea13644 (diff) |
Use the same workaround as ehci(4) and ohci(4) in setaddr() to deal with
half configured control pipe, from Patrick Wildt.
Diffstat (limited to 'sys/dev/usb')
-rw-r--r-- | sys/dev/usb/dwc2/dwc2.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/sys/dev/usb/dwc2/dwc2.c b/sys/dev/usb/dwc2/dwc2.c index afa749d80b6..1016bbc288b 100644 --- a/sys/dev/usb/dwc2/dwc2.c +++ b/sys/dev/usb/dwc2/dwc2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2.c,v 1.22 2015/02/14 05:52:19 uebayasi Exp $ */ +/* $OpenBSD: dwc2.c,v 1.23 2015/03/19 10:29:16 mpi Exp $ */ /* $NetBSD: dwc2.c,v 1.32 2014/09/02 23:26:20 macallan Exp $ */ /*- @@ -91,6 +91,7 @@ int dwc2debug = 0; #endif STATIC usbd_status dwc2_open(struct usbd_pipe *); +STATIC int dwc2_setaddr(struct usbd_device *, int); STATIC void dwc2_poll(struct usbd_bus *); STATIC void dwc2_softintr(void *); STATIC void dwc2_waitintr(struct dwc2_softc *, struct usbd_xfer *); @@ -172,6 +173,7 @@ dwc2_free_bus_bandwidth(struct dwc2_hsotg *hsotg, u16 bw, STATIC struct usbd_bus_methods dwc2_bus_methods = { .open_pipe = dwc2_open, + .dev_setaddr = dwc2_setaddr, .soft_intr = dwc2_softintr, .do_poll = dwc2_poll, #if 0 @@ -269,6 +271,29 @@ dwc2_freem(struct usbd_bus *bus, struct usb_dma *dma) } #endif +/* + * Work around the half configured control (default) pipe when setting + * the address of a device. + */ +STATIC int +dwc2_setaddr(struct usbd_device *dev, int addr) +{ + if (usbd_set_address(dev, addr)) + return (1); + + dev->address = addr; + + /* + * Re-establish the default pipe with the new address and the + * new max packet size. + */ + dwc2_close_pipe(dev->default_pipe); + if (dwc2_open(dev->default_pipe)) + return (EINVAL); + + return (0); +} + struct usbd_xfer * dwc2_allocx(struct usbd_bus *bus) { |