On 22/11/13(Fri) 13:48, Stuart Henderson wrote:
uhub2: port 2, set config at addr 3 failed
uhub2: device problem, disabling port 2
When this happens, is there any way to get the port back without rebooting?
Have you tried suspending/resuming the machine?
Apart from that, the diff below is adapted from FreeBSD's r162977 and
should fix most of the cases that generate such disabling port X
error. Miod has recently bugged me about it, but as always I'm
slacking...
Can you give it a try and tell me if it improves your situation? I
have a hard time finding the right machine/device combinaison to test
it.
Index: ehci.c
===
RCS file: /home/ncvs/src/sys/dev/usb/ehci.c,v
retrieving revision 1.138
diff -u -p -r1.138 ehci.c
--- ehci.c 9 Nov 2013 08:46:05 - 1.138
+++ ehci.c 25 Nov 2013 14:12:20 -
@@ -3052,7 +3052,6 @@ ehci_device_request(struct usbd_xfer *xf
usb_device_request_t *req = xfer-request;
struct usbd_device *dev = epipe-pipe.device;
struct ehci_softc *sc = (struct ehci_softc *)dev-bus;
- int addr = dev-address;
struct ehci_soft_qtd *setup, *stat, *next;
struct ehci_soft_qh *sqh;
int isread;
@@ -3066,7 +3065,7 @@ ehci_device_request(struct usbd_xfer *xf
DPRINTFN(3,(ehci_device_request: type=0x%02x, request=0x%02x,
wValue=0x%04x, wIndex=0x%04x len=%u, addr=%d, endpt=%d\n,
req-bmRequestType, req-bRequest, UGETW(req-wValue),
- UGETW(req-wIndex), len, addr,
+ UGETW(req-wIndex), len, dev-address,
epipe-pipe.endpoint-edesc-bEndpointAddress));
setup = ehci_alloc_sqtd(sc);
@@ -3082,17 +3081,6 @@ ehci_device_request(struct usbd_xfer *xf
sqh = epipe-sqh;
epipe-u.ctl.length = len;
-
- /* Update device address and length since they may have changed
- during the setup of the control pipe in usbd_new_device(). */
- /* XXX This only needs to be done once, but it's too early in open. */
- /* Should not touch ED here! */
- sqh-qh.qh_endp =
- (sqh-qh.qh_endp htole32(~(EHCI_QH_ADDRMASK | EHCI_QH_MPLMASK))) |
- htole32(
-EHCI_QH_SET_ADDR(addr) |
-EHCI_QH_SET_MPL(UGETW(epipe-pipe.endpoint-edesc-wMaxPacketSize))
- );
/* Set up data transaction */
if (len != 0) {
Index: ohci.c
===
RCS file: /home/ncvs/src/sys/dev/usb/ohci.c,v
retrieving revision 1.116
diff -u -p -r1.116 ohci.c
--- ohci.c 9 Nov 2013 08:46:05 - 1.116
+++ ohci.c 25 Nov 2013 14:12:20 -
@@ -1604,7 +1604,6 @@ ohci_device_request(struct usbd_xfer *xf
usb_device_request_t *req = xfer-request;
struct usbd_device *dev = opipe-pipe.device;
struct ohci_softc *sc = (struct ohci_softc *)dev-bus;
- int addr = dev-address;
struct ohci_soft_td *setup, *stat, *next, *tail;
struct ohci_soft_ed *sed;
int isread;
@@ -1618,7 +1617,7 @@ ohci_device_request(struct usbd_xfer *xf
DPRINTFN(3,(ohci_device_control type=0x%02x, request=0x%02x,
wValue=0x%04x, wIndex=0x%04x len=%u, addr=%d, endpt=%d\n,
req-bmRequestType, req-bRequest, UGETW(req-wValue),
- UGETW(req-wIndex), len, addr,
+ UGETW(req-wIndex), len, dev-address,
opipe-pipe.endpoint-edesc-bEndpointAddress));
setup = opipe-tail.td;
@@ -1636,15 +1635,6 @@ ohci_device_request(struct usbd_xfer *xf
sed = opipe-sed;
opipe-u.ctl.length = len;
-
- /* Update device address and length since they may have changed
- during the setup of the control pipe in usbd_new_device(). */
- /* XXX This only needs to be done once, but it's too early in open. */
- /* Should not touch ED here! */
- sed-ed.ed_flags = htole32(
-(letoh32(sed-ed.ed_flags) ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) |
-OHCI_ED_SET_FA(addr) |
-OHCI_ED_SET_MAXP(UGETW(opipe-pipe.endpoint-edesc-wMaxPacketSize)));
next = stat;
Index: usb_subr.c
===
RCS file: /home/ncvs/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.95
diff -u -p -r1.95 usb_subr.c
--- usb_subr.c 19 Nov 2013 14:04:07 - 1.95
+++ usb_subr.c 25 Nov 2013 14:12:20 -
@@ -1164,6 +1164,15 @@ usbd_new_device(struct device *parent, s
USETW(dev-def_ep_desc.wMaxPacketSize, dd-bMaxPacketSize);
+ /* Re-establish the default pipe with the new max packet size. */
+ usbd_abort_pipe(dev-default_pipe);
+ err = usbd_setup_pipe(dev, 0, dev-def_ep, USBD_DEFAULT_INTERVAL,
+ dev-default_pipe);
+ if (err) {
+ usb_free_device(dev, up);
+ return (err);
+ }
+
err = usbd_reload_device_desc(dev