tech-kern archive

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

backporting if_aue fix to netbsd-4



Hello,

this weekend, cube@ noticed a hangup problem I had unplugging my 
if_aue dongle, and fixed it (if_aue.c 1.107, if_auereg.h 1.19).

I ported it back to the lockmgr world, and I think it even works, but
I'd like somebody familiar with our locking systems to look at the 
changes before I request a pullup...

Regards,
        -is


Index: sys/dev/usb/if_aue.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_aue.c,v
retrieving revision 1.99
diff -u -r1.99 if_aue.c
--- sys/dev/usb/if_aue.c        16 Nov 2006 01:33:26 -0000      1.99
+++ sys/dev/usb/if_aue.c        14 Jan 2008 12:18:25 -0000
@@ -142,6 +142,7 @@
 #include <dev/usb/usbdevs.h>
 
 #if defined(__NetBSD__)
+#include <sys/proc.h>  /* tsleep */
 #include <sys/workqueue.h>
 #endif
 
@@ -763,6 +764,10 @@
                USB_ATTACH_ERROR_RETURN;
        }
 #if defined(__NetBSD__)
+       sc->wqsem = 0;
+       lockinit(&sc->wqlock, PZERO, "auewkq", 0, 0);
+       /* cv_init(... "auewk") */
+
        err = workqueue_create(&sc->wqp, USBDEVNAME(sc->aue_dev),
                aue_multiwork, sc, 0, IPL_NET, 0);
 
@@ -886,6 +891,12 @@
                return (0);
        }
 
+       lockmgr(&sc->wqlock,LK_EXCLUSIVE,0);
+       while (sc->wqsem != 0)
+               tsleep(&sc->wqsem, PZERO, "wqsem", 0);
+       lockmgr(&sc->wqlock,LK_RELEASE,0);
+       workqueue_destroy(sc->wqp);
+
        usb_uncallout(sc->aue_stat_ch, aue_tick, sc);
        /*
         * Remove any pending tasks.  They cannot be executing because they run
@@ -1621,8 +1632,11 @@
                if (error == ENETRESET) {
                        if (ifp->if_flags & IFF_RUNNING) {
 #if defined(__NetBSD__)
-                               workqueue_enqueue(sc->wqp,&sc->wk);
-                               /* XXX */
+                               lockmgr(&sc->wqlock,LK_EXCLUSIVE,0);
+                               if (sc->wqsem == 0)
+                                       workqueue_enqueue(sc->wqp,&sc->wk);
+                                       /* XXX */
+                               lockmgr(&sc->wqlock,LK_RELEASE,0);
 #else
                                aue_init(sc);
                                aue_setmulti(sc);
@@ -1773,5 +1787,10 @@
        aue_init(sc);
        /* XXX called by aue_init, but rc ifconfig hangs without it: */
        aue_setmulti(sc);
+
+       lockmgr(&sc->wqlock,LK_EXCLUSIVE,0);
+       sc->wqsem = 0;
+       wakeup(&sc->wqsem);
+       lockmgr(&sc->wqlock,LK_RELEASE,0);
 }
 #endif
Index: sys/dev/usb/if_auereg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_auereg.h,v
retrieving revision 1.17
diff -u -r1.17 if_auereg.h
--- sys/dev/usb/if_auereg.h     15 Sep 2006 10:47:34 -0000      1.17
+++ sys/dev/usb/if_auereg.h     14 Jan 2008 12:18:25 -0000
@@ -239,6 +239,8 @@
 #endif
        struct workqueue        *wqp;
        struct work             wk;
+       struct lock             wqlock;
+       int                     wqsem;
 #define GET_IFP(sc) (&(sc)->aue_ec.ec_if)
 #define GET_MII(sc) (&(sc)->aue_mii)
 #elif defined(__OpenBSD__)



Home | Main Index | Thread Index | Old Index