NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/22646 (Panic in ohci_add_done())



On 04/24/16 10:45, Andreas Gustafsson wrote:

  The file usbhist.txt is too large to include here, but you can
  download it from
http://www.gson.org/netbsd/bugs/22646/usbhist.txt

it's looping around a weird done list.

Can you increase USBHIST_SIZE and set usbdebug to 5 with the attached patch applied?

Full dmesg showing the bus with the camera (and other devices) as well please.

Thanks,
NIck
Index: sys/dev/usb/ohci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ohci.c,v
retrieving revision 1.254.2.72
diff -u -p -r1.254.2.72 ohci.c
--- sys/dev/usb/ohci.c	16 Apr 2016 16:02:42 -0000	1.254.2.72
+++ sys/dev/usb/ohci.c	24 Apr 2016 12:05:06 -0000
@@ -1381,6 +1381,11 @@ ohci_softintr(void *v)
 	int len, cc;
 	int i, j, actlen, iframes, uedir;
 	ohci_physaddr_t done;
+#ifdef OHCI_DEBUG
+	extern int usbdebug;
+	ohci_physaddr_t seen[2] = {0, 0};
+	int s = 0;
+#endif
 
 	KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 
@@ -1402,22 +1407,38 @@ ohci_softintr(void *v)
 	for (sdone = NULL, sidone = NULL; done != 0; ) {
 		std = ohci_hash_find_td(sc, done);
 		if (std != NULL) {
+			seen[(s++) & 1] = done;
 			usb_syncmem(&std->dma, std->offs, sizeof(std->td),
 			    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
 			std->dnext = sdone;
 			done = O32TOH(std->td.td_nexttd);
 			sdone = std;
 			DPRINTFN(10, "add TD %p", std, 0, 0, 0);
+#ifdef OHCI_DEBUG
+			if (done == seen[0] || done == seen[1]) {
+				usbdebug = 0;
+				ohcidebug = 0;
+				break;
+			}
+#endif
 			continue;
 		}
 		sitd = ohci_hash_find_itd(sc, done);
 		if (sitd != NULL) {
+			seen[(s++) & 1] = done;
 			usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd),
 			    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
 			sitd->dnext = sidone;
 			done = O32TOH(sitd->itd.itd_nextitd);
 			sidone = sitd;
 			DPRINTFN(5, "add ITD %p", sitd, 0, 0, 0);
+#ifdef OHCI_DEBUG
+			if (done == seen[0] || done == seen[1]) {
+				usbdebug = 0;
+				ohcidebug = 0;
+				break;
+			}
+#endif
 			continue;
 		}
 		DPRINTFN(10, "addr %p not found", done, 0, 0, 0);


Home | Main Index | Thread Index | Old Index