shithub: riscv

Download patch

ref: 83ab780783623cfa22febc82a4c7e1725db94f48
parent: 8c95a221b041848a479cb2f79d5bb7be74022446
author: mischief <mischief@offblast.org>
date: Wed Apr 17 22:48:35 EDT 2019

nusb/usbd: stop sending port enable commands

from what i can tell, sending port enable is a spec violation.

this fixes a hang during hub enumeration in the ASMedia
xhci controller when i plug in my IBM UltraNav SK-8845.

also, send unsuspend when port is suspended instead of enable.

from the USB 2 specification:

11.24.2.7.1.2 PORT_ENABLE
...
This bit may be set only as a result of a SetPortFeature(PORT_ENABLE).
...
The hub response to a SetPortFeature(PORT_ENABLE) request is not specified.

--- a/sys/src/cmd/nusb/usbd/dat.h
+++ b/sys/src/cmd/nusb/usbd/dat.h
@@ -55,7 +55,6 @@
 
 	/* Delays, timeouts (ms) */
 	Spawndelay	= 250,		/* how often may we re-spawn a driver */
-	Connectdelay	= 500,		/* how much to wait after a connect */
 	Resetdelay	= 20,		/* how much to wait after a reset */
 	Enabledelay	= 20,		/* how much to wait after an enable */
 	Powerdelay	= 100,		/* after powering up ports */
--- a/sys/src/cmd/nusb/usbd/hub.c
+++ b/sys/src/cmd/nusb/usbd/hub.c
@@ -362,7 +362,7 @@
 	pp->state = Pattached;
 	dprint(2, "%s: %s: port %d attach sts %#ux\n", argv0, d->dir, p, sts);
 	if(h->dev->isusb3){
-		sleep(Connectdelay);
+		sleep(Enabledelay);
 		sts = portstatus(h, p);
 		if(sts == -1)
 			goto Fail;
@@ -372,9 +372,6 @@
 		}
 		sp = "super";
 	} else {
-		sleep(Connectdelay);
-		if(hubfeature(h, p, Fportenable, 1) < 0)
-			dprint(2, "%s: %s: port %d: enable: %r\n", argv0, d->dir, p);
 		sleep(Enabledelay);
 		if(hubfeature(h, p, Fportreset, 1) < 0){
 			dprint(2, "%s: %s: port %d: reset: %r\n", argv0, d->dir, p);
@@ -558,12 +555,7 @@
 		goto Fail;
 	if((sts & PSenable) == 0){
 		dprint(2, "%s: %s: port %d: not enabled?\n", argv0, d->dir, p);
-		if(h->dev->isusb3)
-			goto Fail;
-		hubfeature(h, p, Fportenable, 1);
-		sts = portstatus(h, p);
-		if((sts & PSenable) == 0)
-			goto Fail;
+		goto Fail;
 	}
 	nd = pp->dev;
 	opendevdata(nd, ORDWR);
@@ -635,11 +627,11 @@
 	onhubs = nhubs;
 	if(!h->dev->isusb3){
 		if((sts & PSsuspend) != 0){
-			if(hubfeature(h, p, Fportenable, 1) < 0)
-				dprint(2, "%s: %s: port %d: enable: %r\n", argv0, d->dir, p);
+			if(hubfeature(h, p, Fportsuspend, 0) < 0)
+				dprint(2, "%s: %s: port %d: unsuspend: %r\n", argv0, d->dir, p);
 			sleep(Enabledelay);
 			sts = portstatus(h, p);
-			fprint(2, "%s: %s: port %d: resumed (sts %#ux)\n", argv0, d->dir, p, sts);
+			fprint(2, "%s: %s: port %d: unsuspended (sts %#ux)\n", argv0, d->dir, p, sts);
 		}
 	}
 	if((pp->sts & PSpresent) == 0 && (sts & PSpresent) != 0){