changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: usbxhci: fix endpoint stall recovery, handle Ep.clrhalt flag

changeset 7397: b16cb389c7ce
parent 7396: 8eff72134197
child 7399: f54a1306f589
child 7400: 561b0ec255dc
author: cinap_lenrek@felloff.net
date: Sun, 22 Sep 2019 18:51:41 +0200
files: sys/src/9/port/usbxhci.c
description: usbxhci: fix endpoint stall recovery, handle Ep.clrhalt flag

after issuing CR_RESETEP command, we have to invalidate
the endpoints output context buffer so that the halted/error
status reflects the new state. not doing so resulted in
the halted state to be stuck and we continued issuing
endpoint reset commands when we where already recovered.

handle the devusb Ep.clrhalt flag from devusb that userspace
uses to force a endpoint reset on the next transaction.
     1.1--- a/sys/src/9/port/usbxhci.c
     1.2+++ b/sys/src/9/port/usbxhci.c
     1.3@@ -1368,20 +1368,26 @@ isowrite(Ep *ep, uchar *p, long n)
     1.4 }
     1.5 
     1.6 static char*
     1.7-unstall(Ring *r)
     1.8+unstall(Ep *ep, Ring *r)
     1.9 {
    1.10 	char *err;
    1.11 
    1.12 	switch(r->ctx[0]&7){
    1.13 	case 2:	/* halted */
    1.14 	case 4:	/* error */
    1.15-		r->stopped = 1;
    1.16+		ep->clrhalt = 1;
    1.17+	}
    1.18+	if(ep->clrhalt){
    1.19+		ep->clrhalt = 0;
    1.20 		err = ctlrcmd(r->slot->ctlr, CR_RESETEP | (r->id<<16) | (r->slot->id<<24), 0, 0, nil);
    1.21+		dmaflush(0, r->ctx, 8*4 << r->slot->ctlr->csz);
    1.22 		if(err != nil)
    1.23 			return err;
    1.24+		r->stopped = 1;
    1.25 	}
    1.26 	if(r->stopped){
    1.27 		err = ctlrcmd(r->slot->ctlr, CR_SETTRDQP | (r->id<<16) | (r->slot->id<<24), 0, resetring(r), nil);
    1.28+		dmaflush(0, r->ctx, 8*4 << r->slot->ctlr->csz);
    1.29 		if(err != nil)
    1.30 			return err;
    1.31 		r->stopped = 0;
    1.32@@ -1444,7 +1450,7 @@ epread(Ep *ep, void *va, long n)
    1.33 		nexterror();
    1.34 	}
    1.35 
    1.36-	if((err = unstall(io->ring)) != nil)
    1.37+	if((err = unstall(ep, io->ring)) != nil)
    1.38 		error(err);
    1.39 
    1.40 	dmaflush(1, p, n);
    1.41@@ -1517,7 +1523,7 @@ epwrite(Ep *ep, void *va, long n)
    1.42 				io->b->wp += len;
    1.43 			}
    1.44 		}
    1.45-		if((err = unstall(ring)) != nil)
    1.46+		if((err = unstall(ep, ring)) != nil)
    1.47 			error(err);
    1.48 
    1.49 		if((ring->ctx[1]>>16) != ep->maxpkt){
    1.50@@ -1596,7 +1602,7 @@ epwrite(Ep *ep, void *va, long n)
    1.51 		nexterror();
    1.52 	}
    1.53 
    1.54-	if((err = unstall(io->ring)) != nil)
    1.55+	if((err = unstall(ep, io->ring)) != nil)
    1.56 		error(err);
    1.57 
    1.58 	dmaflush(1, p, n);