Author: jh
Date: Tue Nov  3 19:05:05 2009
New Revision: 198857
URL: http://svn.freebsd.org/changeset/base/198857

Log:
  fdc(4) module unload fixes:
  
  - Tear down the interrupt handler before killing the worker thread.
  - Do geom withering as GEOM event to avoid acquiring the GEOM topology
    lock under Giant.
  
  PR:           kern/104079
  Reviewed by:  joerg
  Approved by:  trasz (mentor)

Modified:
  head/sys/dev/fdc/fdc.c

Modified: head/sys/dev/fdc/fdc.c
==============================================================================
--- head/sys/dev/fdc/fdc.c      Tue Nov  3 18:40:42 2009        (r198856)
+++ head/sys/dev/fdc/fdc.c      Tue Nov  3 19:05:05 2009        (r198857)
@@ -1734,6 +1734,10 @@ fdc_detach(device_t dev)
        if ((error = bus_generic_detach(dev)))
                return (error);
 
+       if (fdc->fdc_intr)
+               bus_teardown_intr(dev, fdc->res_irq, fdc->fdc_intr);
+       fdc->fdc_intr = NULL;
+
        /* kill worker thread */
        mtx_lock(&fdc->fdc_mtx);
        fdc->flags |= FDC_KTHREAD_EXIT;
@@ -2031,15 +2035,22 @@ fd_attach(device_t dev)
        return (0);
 }
 
+static void
+fd_detach_geom(void *arg, int flag)
+{
+       struct  fd_data *fd = arg;
+
+       g_topology_assert();
+       g_wither_geom(fd->fd_geom, ENXIO);
+}
+
 static int
 fd_detach(device_t dev)
 {
        struct  fd_data *fd;
 
        fd = device_get_softc(dev);
-       g_topology_lock();
-       g_wither_geom(fd->fd_geom, ENXIO);
-       g_topology_unlock();
+       g_waitfor_event(fd_detach_geom, fd, M_WAITOK, NULL);
        while (device_get_state(dev) == DS_BUSY)
                tsleep(fd, PZERO, "fdd", hz/10);
        callout_drain(&fd->toffhandle);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to