ref: a0da5b973ffa098e428c574104e270b600770f9a
parent: 6bceabbc79b9c60a18dae90b1618eddbf7737275
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);