changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: usbxhci: fix mysterious ENABLESLOT failures (update to XHCI spec revision 1.2 (2019))

changeset 7301: e24206b69d32
parent 7300: 6228acd5dfd1
child 7302: db53a4707905
child 7304: 077f4f4547a6
author: cinap_lenrek@felloff.net
date: Tue, 02 Jul 2019 05:34:13 +0200
files: sys/src/9/pc/usbxhci.c
description: usbxhci: fix mysterious ENABLESLOT failures (update to XHCI spec revision 1.2 (2019))

Ori Bernstein had Sunrise Point-H USB 3.0 xHCI Controller that would mysteriously
crash on the 5th ENABLESLOT command. This was reproducable by even just allocating
slots in a loop right after init.

It turns out, the 1.2 spec extended the Max Scratchpad Buffers in HCSPARAMS2 so our
driver would not allocate enougth scratchpad buffers and controller firmware would
crash once it went beyond our allocated scratchpad buffer array.

This change also fixes:

- ignore bits 16:31 in PAGESIZE register
- preserve bits 10:31 in the CONFIG register
- handle ADDESSDEV command failure (so it can be retried)
     1.1--- a/sys/src/9/pc/usbxhci.c
     1.2+++ b/sys/src/9/pc/usbxhci.c
     1.3@@ -483,9 +483,9 @@ init(Hci *hp)
     1.4 		ctlr->setrptr = setrptr64;
     1.5 	else
     1.6 		ctlr->setrptr = setrptr32;
     1.7-	ctlr->pagesize = ctlr->opr[PAGESIZE]<<12;
     1.8+	ctlr->pagesize = (ctlr->opr[PAGESIZE] & 0xFFFF) << 12;
     1.9 
    1.10-	ctlr->nscratch = (ctlr->mmio[HCSPARAMS2] >> 27) & 0x1F;
    1.11+	ctlr->nscratch = (ctlr->mmio[HCSPARAMS2] >> 27) & 0x1F | (ctlr->mmio[HCSPARAMS2] >> 16) & 0x3E0;
    1.12 	ctlr->nintrs = (ctlr->mmio[HCSPARAMS1] >> 8) & 0x7FF;
    1.13 	ctlr->nslots = (ctlr->mmio[HCSPARAMS1] >> 0) & 0xFF;
    1.14 
    1.15@@ -533,7 +533,7 @@ init(Hci *hp)
    1.16 	}
    1.17 	for(i=1; i<=ctlr->nslots; i++)
    1.18 		ctlr->dcba[i] = 0;
    1.19-	ctlr->opr[CONFIG] = ctlr->nslots;	/* MaxSlotsEn */
    1.20+	ctlr->opr[CONFIG] = (ctlr->opr[CONFIG] & 0xFFFFFC00) | ctlr->nslots;	/* MaxSlotsEn */
    1.21 	ctlr->setrptr(&ctlr->opr[DCBAAP], PADDR(ctlr->dcba));
    1.22 
    1.23 	initring(ctlr->cr, 8);		/* 256 entries */
    1.24@@ -970,9 +970,6 @@ allocslot(Ctlr *ctlr, Udev *dev)
    1.25 	ctlr->slot[slot->id] = slot;
    1.26 	qunlock(&ctlr->slotlock);
    1.27 
    1.28-	dev->aux = slot;
    1.29-	dev->free = freeslot;
    1.30-
    1.31 	return slot;
    1.32 }
    1.33 
    1.34@@ -1198,6 +1195,10 @@ epopen(Ep *ep)
    1.35 		error(Egreg);
    1.36 
    1.37 	slot = allocslot(ctlr, dev);
    1.38+	if(waserror()){
    1.39+		freeslot(slot);
    1.40+		nexterror();
    1.41+	}
    1.42 
    1.43 	/* allocate control ep 0 ring */
    1.44 	ring = initring(io[OWRITE].ring = &slot->epr[0], 4);
    1.45@@ -1253,7 +1254,13 @@ epopen(Ep *ep)
    1.46 
    1.47 	/* (output) slot context */
    1.48 	w = slot->obase;
    1.49-	ep->dev->addr = w[3] & 0xFF;
    1.50+
    1.51+	dev->addr = w[3] & 0xFF;
    1.52+
    1.53+	dev->aux = slot;
    1.54+	dev->free = freeslot;
    1.55+
    1.56+	poperror();
    1.57 	poperror();
    1.58 }
    1.59