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.
This commit is contained in:
parent
6bceabbc79
commit
a0da5b973f
1 changed files with 16 additions and 7 deletions
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue