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

Reply via email to