On Tue, Apr 14, 2020 at 11:06:00AM +0200, Patrick Wildt wrote: > On Mon, Apr 13, 2020 at 09:36:04PM +0200, Mark Kettenis wrote: > > Can you print the status (full 32 bits) of that particular QTD? > > Yeah, I wish I could see the status field for each sqtd in that > chain.
XXX #1# ehci_idone: len=4 actlen=4294951308, xf_actlen=0, status=0x8d00, sqtd_count=3 XXX #2# ehci_idone: x_actlen=4294951304, sqtd_len=8, ehci_qtd_len=16000, status=0xbe808d00, qtd_status=0xbe808d00, sqtd_count=1 XXX #2# ehci_idone: x_actlen=4294951308, sqtd_len=4, ehci_qtd_len=0, status=0xc00, qtd_status=0xc00, sqtd_count=2 XXX #2# ehci_idone: x_actlen=4294951308, sqtd_len=0, ehci_qtd_len=0, status=0x8d00, qtd_status=0x8d00, sqtd_count=3 panic: _dmamap_sync: ran off map! Above are my debug lines in dmesg generated just before panic. The code which prints those lines is below. It's similar for-loop to what is currently in CVS in ehci_idone() function. I'm doing this for-loop twice. First version of for-loop is executed as is in CVS and record condition that panic will happen, then below for-loop is executed again with more debug output, otherwise printf() will slow the code path so mutch that I will not be able to trigger error condition. With below code (lines from 1 to 29) I already know panic condition is met and I'm executing code with printf()s added. sqtd_count=3 means that for-loop from line 6 to 28 was executed 3 times. XXX #1# ehci_idone: len=4 actlen=4294951308, xf_actlen=0, status=0x8d00, sqtd_count=3 Above message is from line 2 of the code listed below. Then we enter the for-loop at line 6, which iterates 3 times. Each iteration gives following results: XXX #2# ehci_idone: x_actlen=4294951304, sqtd_len=8, ehci_qtd_len=16000, status=0xbe808d00, qtd_status=0xbe808d00, sqtd_count=1 XXX #2# ehci_idone: x_actlen=4294951308, sqtd_len=4, ehci_qtd_len=0, status=0xc00, qtd_status=0xc00, sqtd_count=2 XXX #2# ehci_idone: x_actlen=4294951308, sqtd_len=0, ehci_qtd_len=0, status=0x8d00, qtd_status=0x8d00, sqtd_count=3 then code proceeds and triggers panic. 1 if (xfer->length < actlen) { 2 printf("XXX #1# ehci_idone: len=%u, actlen=%u, xf_actlen=%u, " 3 "status=0x%x, sqtd_count=%d\n", xfer->length, actlen, xfer->actlen, status, sqtd_count); 4 x_actlen = 0; 5 sqtd_count = 0; 6 for (sqtd = ex->sqtdstart; sqtd != NULL; sqtd = sqtd->nextqtd) { 7 sqtd_count++; 8 usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), 9 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 10 nstatus = letoh32(sqtd->qtd.qtd_status); 11 qtd_status = nstatus; 12 if (nstatus & EHCI_QTD_ACTIVE) 13 break; 14 15 status = nstatus; 16 /* halt is ok if descriptor is last, and complete */ 17 if (sqtd->qtd.qtd_next == htole32(EHCI_LINK_TERMINATE) && 18 EHCI_QTD_GET_BYTES(status) == 0) 19 status &= ~EHCI_QTD_HALTED; 20 if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP) { 21 sqtd_len = sqtd->len; 22 ehci_qtd_len = EHCI_QTD_GET_BYTES(status); 23 x_actlen += sqtd_len - ehci_qtd_len; 24 printf("XXX #2# ehci_idone: x_actlen=%u, sqtd_len=%u, ehci_qtd_len=%u, " 25 "status=0x%x, qtd_status=0x%x, sqtd_count=%d\n", 26 x_actlen, sqtd_len, ehci_qtd_len, status, qtd_status, sqtd_count); 27 } 28 } 29 } I can provide full patch if someone is interested what exactly I am doing. -- Regards, Mikolaj