From a0da5b973ffa098e428c574104e270b600770f9a Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 19 Apr 2019 23:39:47 +0200 Subject: [PATCH] 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. --- sys/src/9/pc/usbxhci.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/sys/src/9/pc/usbxhci.c b/sys/src/9/pc/usbxhci.c index 653fdb0ca..9c9ad60eb 100644 --- a/sys/src/9/pc/usbxhci.c +++ b/sys/src/9/pc/usbxhci.c @@ -753,14 +753,23 @@ waittd(Ctlr *ctlr, Wait *w, int tmout) *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);