On Mon, Apr 13, 2020 at 01:20:27PM -0600, Theo de Raadt wrote:
> Then next step is to figure out why the sqtd is incoherent.
Ok :) If someone has spare time to help me more on this I'm all ears.
Maybe this crash output makes it more clear:
XXX S01: ehci_idone: actlen=0, sqtd_len=8, ehci_qtd_len=16000, status=0x3e808d00
XXX S02: ehci_idone: actlen=4294951304, sqtd_len=8, ehci_qtd_len=16000,
status=0x3e808d00
panic: _dmamap_sync: ran off map!
Above output with below changes on top of CVS as of today:
Index: sys/dev/usb/ehci.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ehci.c,v
retrieving revision 1.210
diff -u -p -u -r1.210 ehci.c
--- sys/dev/usb/ehci.c 3 Apr 2020 20:11:47 -0000 1.210
+++ sys/dev/usb/ehci.c 13 Apr 2020 19:14:44 -0000
@@ -869,7 +869,8 @@ ehci_idone(struct usbd_xfer *xfer)
struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
struct ehci_soft_qtd *sqtd;
u_int32_t status = 0, nstatus = 0;
- int actlen, cerr;
+ u_int32_t actlen, sqtd_len, ehci_qtd_len;
+ int cerr;
#ifdef DIAGNOSTIC
{
@@ -899,8 +900,19 @@ ehci_idone(struct usbd_xfer *xfer)
if (sqtd->qtd.qtd_next == htole32(EHCI_LINK_TERMINATE) &&
EHCI_QTD_GET_BYTES(status) == 0)
status &= ~EHCI_QTD_HALTED;
- if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP)
- actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);
+ if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP) {
+ sqtd_len = sqtd->len;
+ ehci_qtd_len = EHCI_QTD_GET_BYTES(status);
+ if (ehci_qtd_len > sqtd_len) {
+ printf("XXX S01 %s: actlen=%u, sqtd_len=%u,
ehci_qtd_len=%u, status=0x%x\n",
+ __func__, actlen, sqtd_len,
ehci_qtd_len, status);
+ }
+ actlen += sqtd_len - ehci_qtd_len;
+ if (ehci_qtd_len > sqtd_len) {
+ printf("XXX S02 %s: actlen=%u, sqtd_len=%u,
ehci_qtd_len=%u, status=0x%x\n",
+ __func__, actlen, sqtd_len,
ehci_qtd_len, status);
+ }
+ }
}
cerr = EHCI_QTD_GET_CERR(status);
--
Regards,
Mikolaj