ref: 6fac5224928a900b86a8c81c6df68dac4336c97c
parent: a208683bda8f06559d849bebcb44db1bb259fff2
	author: cinap_lenrek <cinap_lenrek@felloff.net>
	date: Fri Apr 19 19:39:47 EDT 2019
	
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.
--- a/sys/src/9/pc/usbxhci.c
+++ b/sys/src/9/pc/usbxhci.c
@@ -753,14 +753,23 @@
*r->doorbell = r->id;
 	while(waserror()){-		if(!r->stopped) {- if(r == ctlr->cr)
- ctlr->opr[CRCR] |= CA;
- else
- ctlrcmd(ctlr, CR_STOPEP | (r->id<<16) | (r->slot->id<<24), 0, 0, nil);
- r->stopped = 1;
+		if(r->stopped) {+ ctlr->er->stopped = 1;
+ wakeup(&ctlr->recover);
+
+ /* wait for rescue */
+ tmout = 0;
+ continue;
}
- tmout = 0;
+
+ if(r == ctlr->cr)
+ ctlr->opr[CRCR] |= CA;
+ else
+ ctlrcmd(ctlr, CR_STOPEP | (r->id<<16) | (r->slot->id<<24), 0, 0, nil);
+ r->stopped = 1;
+
+ /* time to abort the transaction */
+ tmout = 5000;
}
 	if(tmout > 0){tsleep(&up->sleep, waitdone, w, tmout);
--
⑨