:...
:> just tried booting 1.4 (snaphot) in vmware.  it works normally, but if I 
:> have my usb stick passed through to dragonfly, it panics like below (I 
:> think that's the same panic sascha is seeing).
:> 
:> A little bit playing with ddb showed that pipe->queue is empty.
:
:Dump is in ~swildner/crash on leaf.
:
:Sascha

    There is some sort of recursion happening but I'm not sure whether
    the recursion is valid or whether it is itself a bug.  The crash is
    occuring while usb_transfer_complete() is operating on the wrong 'xfer'
    structure.

    I'm going to make a semi-wild guess.  Look at the LIST_FOREACH() on
    line 1274 in /usr/src/sys/bus/usb/uhci.c ... I think the 'ii' structure
    could be getting ripped out from under the list scanner.

    I've included a bad hack for you to try to see if it solves the problem.

                                        -Matt
                                        Matthew Dillon 
                                        <[EMAIL PROTECTED]>

Index: bus/usb/uhci.c
===================================================================
RCS file: /cvs/src/sys/bus/usb/uhci.c,v
retrieving revision 1.13
diff -u -r1.13 uhci.c
--- bus/usb/uhci.c      29 Apr 2006 22:05:21 -0000      1.13
+++ bus/usb/uhci.c      27 Jun 2006 21:14:27 -0000
@@ -386,6 +386,7 @@
        LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ii), list)
 #define uhci_del_intr_info(ii) \
        do { \
+               ++ii->sc->sc_intrhead_deletion_counter; \
                LIST_REMOVE((ii), list); \
                (ii)->list.le_prev = NULL; \
        } while (0)
@@ -1254,6 +1255,7 @@
 {
        uhci_softc_t *sc = v;
        uhci_intr_info_t *ii;
+       int last_deletion_counter;
 
        DPRINTFN(10,("%s: uhci_softintr (%d)\n", USBDEVNAME(sc->sc_bus.bdev),
                     sc->sc_bus.intr_context));
@@ -1270,9 +1272,17 @@
         * output on a slow console).
         * We scan all interrupt descriptors to see if any have
         * completed.
+        *
+        * XXX horrible hack - use a counter to detect if  the list is
+        * modified out from under us and rescan if it is.
         */
-       LIST_FOREACH(ii, &sc->sc_intrhead, list)
+again:
+       last_deletion_counter = sc->sc_intrhead_deletion_counter;
+       LIST_FOREACH(ii, &sc->sc_intrhead, list) {
                uhci_check_intr(sc, ii);
+               if (sc->sc_intrhead_deletion_counter != last_deletion_counter)
+                       goto again;
+       }
 
 #ifdef USB_USE_SOFTINTR
        if (sc->sc_softwake) {
Index: bus/usb/uhcivar.h
===================================================================
RCS file: /cvs/src/sys/bus/usb/uhcivar.h,v
retrieving revision 1.4
diff -u -r1.4 uhcivar.h
--- bus/usb/uhcivar.h   11 Feb 2004 15:17:26 -0000      1.4
+++ bus/usb/uhcivar.h   27 Jun 2006 21:10:30 -0000
@@ -179,6 +179,7 @@
        char sc_dying;
 
        LIST_HEAD(, uhci_intr_info) sc_intrhead;
+       int  sc_intrhead_deletion_counter;
 
        /* Info for the root hub interrupt channel. */
        int sc_ival;                    /* time between root hub intrs */

Reply via email to