changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: usbxhci: make stuck usb transactions interruptable.

changeset 7173: 0f6e130b3c07
parent 7172: fa96f026264b
child 7174: 3839b70da66a
author: cinap_lenrek@felloff.net
date: Fri, 19 Apr 2019 23:39:47 +0200
files: sys/src/9/pc/usbxhci.c
description: usbxhci: make stuck usb transactions interruptable.

some control transactions can confuse the xhci controller so
much that it even fails to respond to command abort or STOPEP
control command. with no way for us to abort the transaction
but a full controller reset.

we give the controller 5 seconds to abort our initial
transaction and if that fails we wake the recover process
to reset the controller.

thanks mischief for testing.
     1.1--- a/sys/src/9/pc/usbxhci.c
     1.2+++ b/sys/src/9/pc/usbxhci.c
     1.3@@ -753,14 +753,23 @@ waittd(Ctlr *ctlr, Wait *w, int tmout)
     1.4 	*r->doorbell = r->id;
     1.5 
     1.6 	while(waserror()){
     1.7-		if(!r->stopped) {
     1.8-			if(r == ctlr->cr)
     1.9-				ctlr->opr[CRCR] |= CA;
    1.10-			else
    1.11-				ctlrcmd(ctlr, CR_STOPEP | (r->id<<16) | (r->slot->id<<24), 0, 0, nil);
    1.12-			r->stopped = 1;
    1.13+		if(r->stopped) {
    1.14+			ctlr->er->stopped = 1;
    1.15+			wakeup(&ctlr->recover);
    1.16+
    1.17+			/* wait for rescue */
    1.18+			tmout = 0;
    1.19+			continue;
    1.20 		}
    1.21-		tmout = 0;
    1.22+
    1.23+		if(r == ctlr->cr)
    1.24+			ctlr->opr[CRCR] |= CA;
    1.25+		else
    1.26+			ctlrcmd(ctlr, CR_STOPEP | (r->id<<16) | (r->slot->id<<24), 0, 0, nil);
    1.27+		r->stopped = 1;
    1.28+
    1.29+		/* time to abort the transaction */
    1.30+		tmout = 5000;
    1.31 	}
    1.32 	if(tmout > 0){
    1.33 		tsleep(&up->sleep, waitdone, w, tmout);