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.
front
mischief 2019-04-18 02:48:35 -07:00
parent 8c95a221b0
commit 83ab780783
2 changed files with 5 additions and 14 deletions

View File

@ -55,7 +55,6 @@ enum
/* 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 */

View File

@ -362,7 +362,7 @@ portattach(Hub *h, int p, u32int sts)
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 @@ portattach(Hub *h, int p, u32int sts)
}
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 @@ portreset(Hub *h, int p)
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 @@ enumhub(Hub *h, int p)
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){