Author: hselasky
Date: Wed Aug 15 15:42:57 2012
New Revision: 239299
URL: http://svn.freebsd.org/changeset/base/239299

Log:
  Revert r239178 and implement two new functions, namely
  "device_free_softc()" and "device_claim_softc()",
  to allow USB serial drivers refcounting the softc.
  These functions are used to grab the softc from
  auto-free and to free the softc back to the correct
  malloc type, respectivly.
  
  Discussed with:       jhb
  MFC after:    2 weeks

Modified:
  head/sys/dev/usb/net/if_usie.c
  head/sys/dev/usb/net/uhso.c
  head/sys/dev/usb/serial/u3g.c
  head/sys/dev/usb/serial/uark.c
  head/sys/dev/usb/serial/ubsa.c
  head/sys/dev/usb/serial/ubser.c
  head/sys/dev/usb/serial/uchcom.c
  head/sys/dev/usb/serial/ucycom.c
  head/sys/dev/usb/serial/ufoma.c
  head/sys/dev/usb/serial/uftdi.c
  head/sys/dev/usb/serial/ugensa.c
  head/sys/dev/usb/serial/uipaq.c
  head/sys/dev/usb/serial/umcs.c
  head/sys/dev/usb/serial/umct.c
  head/sys/dev/usb/serial/umodem.c
  head/sys/dev/usb/serial/umoscom.c
  head/sys/dev/usb/serial/uplcom.c
  head/sys/dev/usb/serial/usb_serial.c
  head/sys/dev/usb/serial/usb_serial.h
  head/sys/dev/usb/serial/uslcom.c
  head/sys/dev/usb/serial/uvisor.c
  head/sys/dev/usb/serial/uvscom.c
  head/sys/kern/device_if.m
  head/sys/kern/subr_bus.c
  head/sys/sys/bus.h

Modified: head/sys/dev/usb/net/if_usie.c
==============================================================================
--- head/sys/dev/usb/net/if_usie.c      Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/net/if_usie.c      Wed Aug 15 15:42:57 2012        
(r239299)
@@ -95,7 +95,7 @@ static const STRUCT_USB_HOST_ID usie_dev
 static device_probe_t usie_probe;
 static device_attach_t usie_attach;
 static device_detach_t usie_detach;
-static device_free_softc_t usie_free_softc;
+static void usie_free_softc(struct usie_softc *);
 
 static void usie_free(struct ucom_softc *);
 static void usie_uc_update_line_state(struct ucom_softc *, uint8_t);
@@ -191,7 +191,6 @@ static device_method_t usie_methods[] = 
        DEVMETHOD(device_probe, usie_probe),
        DEVMETHOD(device_attach, usie_attach),
        DEVMETHOD(device_detach, usie_detach),
-       DEVMETHOD(device_free_softc, usie_free_softc),
        DEVMETHOD_END
 };
 
@@ -488,27 +487,28 @@ usie_detach(device_t self)
                usbd_transfer_unsetup(sc->sc_uc_xfer[x], USIE_UC_N_XFER);
 
 
+       device_claim_softc(self);
+
+       usie_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(usie);
 
 static void
-usie_free_softc(device_t dev, void *arg)
+usie_free_softc(struct usie_softc *sc)
 {
-       struct usie_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 usie_free(struct ucom_softc *ucom)
 {
-       usie_free_softc(NULL, ucom->sc_parent);
+       usie_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/net/uhso.c
==============================================================================
--- head/sys/dev/usb/net/uhso.c Wed Aug 15 15:35:20 2012        (r239298)
+++ head/sys/dev/usb/net/uhso.c Wed Aug 15 15:42:57 2012        (r239299)
@@ -474,13 +474,12 @@ static void uhso_if_rxflush(void *);
 static device_probe_t uhso_probe;
 static device_attach_t uhso_attach;
 static device_detach_t uhso_detach;
-static device_free_softc_t uhso_free_softc;
+static void uhso_free_softc(struct uhso_softc *);
 
 static device_method_t uhso_methods[] = {
        DEVMETHOD(device_probe,         uhso_probe),
        DEVMETHOD(device_attach,        uhso_attach),
        DEVMETHOD(device_detach,        uhso_detach),
-       DEVMETHOD(device_free_softc,    uhso_free_softc),
        { 0, 0 }
 };
 
@@ -697,27 +696,28 @@ uhso_detach(device_t self)
                usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX);
        }
 
+       device_claim_softc(self);
+
+       uhso_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(uhso);
 
 static void
-uhso_free_softc(device_t dev, void *arg)
+uhso_free_softc(struct uhso_softc *sc)
 {
-       struct uhso_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 uhso_free(struct ucom_softc *ucom)
 {
-       uhso_free_softc(NULL, ucom->sc_parent);
+       uhso_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/u3g.c
==============================================================================
--- head/sys/dev/usb/serial/u3g.c       Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/u3g.c       Wed Aug 15 15:42:57 2012        
(r239299)
@@ -118,7 +118,7 @@ struct u3g_softc {
 static device_probe_t u3g_probe;
 static device_attach_t u3g_attach;
 static device_detach_t u3g_detach;
-static device_free_softc_t u3g_free_softc;
+static void u3g_free_softc(struct u3g_softc *);
 
 static usb_callback_t u3g_write_callback;
 static usb_callback_t u3g_read_callback;
@@ -169,7 +169,6 @@ static device_method_t u3g_methods[] = {
        DEVMETHOD(device_probe, u3g_probe),
        DEVMETHOD(device_attach, u3g_attach),
        DEVMETHOD(device_detach, u3g_detach),
-       DEVMETHOD(device_free_softc, u3g_free_softc),
        DEVMETHOD_END
 };
 
@@ -898,27 +897,28 @@ u3g_detach(device_t dev)
        for (subunit = 0; subunit != U3G_MAXPORTS; subunit++)
                usbd_transfer_unsetup(sc->sc_xfer[subunit], U3G_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       u3g_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(u3g);
 
 static void
-u3g_free_softc(device_t dev, void *arg)
+u3g_free_softc(struct u3g_softc *sc)
 {
-       struct u3g_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 u3g_free(struct ucom_softc *ucom)
 {
-       u3g_free_softc(NULL, ucom->sc_parent);
+       u3g_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/uark.c
==============================================================================
--- head/sys/dev/usb/serial/uark.c      Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/uark.c      Wed Aug 15 15:42:57 2012        
(r239299)
@@ -99,7 +99,7 @@ struct uark_softc {
 static device_probe_t uark_probe;
 static device_attach_t uark_attach;
 static device_detach_t uark_detach;
-static device_free_softc_t uark_free_softc;
+static void uark_free_softc(struct uark_softc *);
 
 static usb_callback_t uark_bulk_write_callback;
 static usb_callback_t uark_bulk_read_callback;
@@ -157,7 +157,6 @@ static device_method_t uark_methods[] = 
        DEVMETHOD(device_probe, uark_probe),
        DEVMETHOD(device_attach, uark_attach),
        DEVMETHOD(device_detach, uark_detach),
-       DEVMETHOD(device_free_softc, uark_free_softc),
        DEVMETHOD_END
 };
 
@@ -248,27 +247,28 @@ uark_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UARK_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       uark_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(uark);
 
 static void
-uark_free_softc(device_t dev, void *arg)
+uark_free_softc(struct uark_softc *sc)
 {
-       struct uark_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 uark_free(struct ucom_softc *ucom)
 {
-       uark_free_softc(NULL, ucom->sc_parent);
+       uark_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/ubsa.c
==============================================================================
--- head/sys/dev/usb/serial/ubsa.c      Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/ubsa.c      Wed Aug 15 15:42:57 2012        
(r239299)
@@ -176,7 +176,7 @@ struct ubsa_softc {
 static device_probe_t ubsa_probe;
 static device_attach_t ubsa_attach;
 static device_detach_t ubsa_detach;
-static device_free_softc_t ubsa_free_softc;
+static void ubsa_free_softc(struct ubsa_softc *);
 
 static usb_callback_t ubsa_write_callback;
 static usb_callback_t ubsa_read_callback;
@@ -265,7 +265,6 @@ static device_method_t ubsa_methods[] = 
        DEVMETHOD(device_probe, ubsa_probe),
        DEVMETHOD(device_attach, ubsa_attach),
        DEVMETHOD(device_detach, ubsa_detach),
-       DEVMETHOD(device_free_softc, ubsa_free_softc),
        DEVMETHOD_END
 };
 
@@ -354,27 +353,28 @@ ubsa_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UBSA_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       ubsa_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(ubsa);
 
 static void
-ubsa_free_softc(device_t dev, void *arg)
+ubsa_free_softc(struct ubsa_softc *sc)
 {
-       struct ubsa_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 ubsa_free(struct ucom_softc *ucom)
 {
-       ubsa_free_softc(NULL, ucom->sc_parent);
+       ubsa_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/ubser.c
==============================================================================
--- head/sys/dev/usb/serial/ubser.c     Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/ubser.c     Wed Aug 15 15:42:57 2012        
(r239299)
@@ -148,7 +148,7 @@ struct ubser_softc {
 static device_probe_t ubser_probe;
 static device_attach_t ubser_attach;
 static device_detach_t ubser_detach;
-static device_free_softc_t ubser_free_softc;
+static void ubser_free_softc(struct ubser_softc *);
 
 static usb_callback_t ubser_write_callback;
 static usb_callback_t ubser_read_callback;
@@ -201,7 +201,6 @@ static device_method_t ubser_methods[] =
        DEVMETHOD(device_probe, ubser_probe),
        DEVMETHOD(device_attach, ubser_attach),
        DEVMETHOD(device_detach, ubser_detach),
-       DEVMETHOD(device_free_softc, ubser_free_softc),
        DEVMETHOD_END
 };
 
@@ -321,27 +320,28 @@ ubser_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UBSER_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       ubser_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(ubser);
 
 static void
-ubser_free_softc(device_t dev, void *arg)
+ubser_free_softc(struct ubser_softc *sc)
 {
-       struct ubser_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 ubser_free(struct ucom_softc *ucom)
 {
-       ubser_free_softc(NULL, ucom->sc_parent);
+       ubser_free_softc(ucom->sc_parent);
 }
 
 static int

Modified: head/sys/dev/usb/serial/uchcom.c
==============================================================================
--- head/sys/dev/usb/serial/uchcom.c    Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/uchcom.c    Wed Aug 15 15:42:57 2012        
(r239299)
@@ -235,7 +235,7 @@ static void uchcom_poll(struct ucom_soft
 static device_probe_t uchcom_probe;
 static device_attach_t uchcom_attach;
 static device_detach_t uchcom_detach;
-static device_free_softc_t uchcom_free_softc;
+static void uchcom_free_softc(struct uchcom_softc *);
 
 static usb_callback_t uchcom_intr_callback;
 static usb_callback_t uchcom_write_callback;
@@ -376,27 +376,28 @@ uchcom_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UCHCOM_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       uchcom_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(uchcom);
 
 static void
-uchcom_free_softc(device_t dev, void *arg)
+uchcom_free_softc(struct uchcom_softc *sc)
 {
-       struct uchcom_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 uchcom_free(struct ucom_softc *ucom)
 {
-       uchcom_free_softc(NULL, ucom->sc_parent);
+       uchcom_free_softc(ucom->sc_parent);
 }
 
 /* ----------------------------------------------------------------------
@@ -864,7 +865,6 @@ static device_method_t uchcom_methods[] 
        DEVMETHOD(device_probe, uchcom_probe),
        DEVMETHOD(device_attach, uchcom_attach),
        DEVMETHOD(device_detach, uchcom_detach),
-       DEVMETHOD(device_free_softc, uchcom_free_softc),
        DEVMETHOD_END
 };
 

Modified: head/sys/dev/usb/serial/ucycom.c
==============================================================================
--- head/sys/dev/usb/serial/ucycom.c    Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/ucycom.c    Wed Aug 15 15:42:57 2012        
(r239299)
@@ -110,7 +110,7 @@ struct ucycom_softc {
 static device_probe_t ucycom_probe;
 static device_attach_t ucycom_attach;
 static device_detach_t ucycom_detach;
-static device_free_softc_t ucycom_free_softc;
+static void ucycom_free_softc(struct ucycom_softc *);
 
 static usb_callback_t ucycom_ctrl_write_callback;
 static usb_callback_t ucycom_intr_read_callback;
@@ -163,7 +163,6 @@ static device_method_t ucycom_methods[] 
        DEVMETHOD(device_probe, ucycom_probe),
        DEVMETHOD(device_attach, ucycom_attach),
        DEVMETHOD(device_detach, ucycom_detach),
-       DEVMETHOD(device_free_softc, ucycom_free_softc),
        DEVMETHOD_END
 };
 
@@ -299,27 +298,28 @@ ucycom_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UCYCOM_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       ucycom_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(ucycom);
 
 static void
-ucycom_free_softc(device_t dev, void *arg)
+ucycom_free_softc(struct ucycom_softc *sc)
 {
-       struct ucycom_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 ucycom_free(struct ucom_softc *ucom)
 {
-       ucycom_free_softc(NULL, ucom->sc_parent);
+       ucycom_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/ufoma.c
==============================================================================
--- head/sys/dev/usb/serial/ufoma.c     Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/ufoma.c     Wed Aug 15 15:42:57 2012        
(r239299)
@@ -202,7 +202,7 @@ struct ufoma_softc {
 static device_probe_t ufoma_probe;
 static device_attach_t ufoma_attach;
 static device_detach_t ufoma_detach;
-static device_free_softc_t ufoma_free_softc;
+static void ufoma_free_softc(struct ufoma_softc *);
 
 static usb_callback_t ufoma_ctrl_read_callback;
 static usb_callback_t ufoma_ctrl_write_callback;
@@ -313,7 +313,6 @@ static device_method_t ufoma_methods[] =
        DEVMETHOD(device_probe, ufoma_probe),
        DEVMETHOD(device_attach, ufoma_attach),
        DEVMETHOD(device_detach, ufoma_detach),
-       DEVMETHOD(device_free_softc, ufoma_free_softc),
        DEVMETHOD_END
 };
 
@@ -498,27 +497,28 @@ ufoma_detach(device_t dev)
        }
        cv_destroy(&sc->sc_cv);
 
+       device_claim_softc(dev);
+
+       ufoma_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(ufoma);
 
 static void
-ufoma_free_softc(device_t dev, void *arg)
+ufoma_free_softc(struct ufoma_softc *sc)
 {
-       struct ufoma_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 ufoma_free(struct ucom_softc *ucom)
 {
-       ufoma_free_softc(NULL, ucom->sc_parent);
+       ufoma_free_softc(ucom->sc_parent);
 }
 
 static void *

Modified: head/sys/dev/usb/serial/uftdi.c
==============================================================================
--- head/sys/dev/usb/serial/uftdi.c     Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/uftdi.c     Wed Aug 15 15:42:57 2012        
(r239299)
@@ -125,7 +125,7 @@ struct uftdi_param_config {
 static device_probe_t uftdi_probe;
 static device_attach_t uftdi_attach;
 static device_detach_t uftdi_detach;
-static device_free_softc_t uftdi_free_softc;
+static void uftdi_free_softc(struct uftdi_softc *);
 
 static usb_callback_t uftdi_write_callback;
 static usb_callback_t uftdi_read_callback;
@@ -190,7 +190,6 @@ static device_method_t uftdi_methods[] =
        DEVMETHOD(device_probe, uftdi_probe),
        DEVMETHOD(device_attach, uftdi_attach),
        DEVMETHOD(device_detach, uftdi_detach),
-       DEVMETHOD(device_free_softc, uftdi_free_softc),
        DEVMETHOD_END
 };
 
@@ -960,27 +959,28 @@ uftdi_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UFTDI_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       uftdi_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(uftdi);
 
 static void
-uftdi_free_softc(device_t dev, void *arg)
+uftdi_free_softc(struct uftdi_softc *sc)
 {
-       struct uftdi_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 uftdi_free(struct ucom_softc *ucom)
 {
-       uftdi_free_softc(NULL, ucom->sc_parent);
+       uftdi_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/ugensa.c
==============================================================================
--- head/sys/dev/usb/serial/ugensa.c    Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/ugensa.c    Wed Aug 15 15:42:57 2012        
(r239299)
@@ -94,7 +94,7 @@ struct ugensa_softc {
 static device_probe_t ugensa_probe;
 static device_attach_t ugensa_attach;
 static device_detach_t ugensa_detach;
-static device_free_softc_t ugensa_free_softc;
+static void ugensa_free_softc(struct ugensa_softc *);
 
 static usb_callback_t ugensa_bulk_write_callback;
 static usb_callback_t ugensa_bulk_read_callback;
@@ -141,7 +141,6 @@ static device_method_t ugensa_methods[] 
        DEVMETHOD(device_probe, ugensa_probe),
        DEVMETHOD(device_attach, ugensa_attach),
        DEVMETHOD(device_detach, ugensa_detach),
-       DEVMETHOD(device_free_softc, ugensa_free_softc),
        DEVMETHOD_END
 };
 
@@ -272,27 +271,28 @@ ugensa_detach(device_t dev)
                usbd_transfer_unsetup(sc->sc_sub[x].sc_xfer, UGENSA_N_TRANSFER);
        }
 
+       device_claim_softc(dev);
+
+       ugensa_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(ugensa);
 
 static void
-ugensa_free_softc(device_t dev, void *arg)
+ugensa_free_softc(struct ugensa_softc *sc)
 {
-       struct ugensa_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 ugensa_free(struct ucom_softc *ucom)
 {
-       ugensa_free_softc(NULL, ucom->sc_parent);
+       ugensa_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/uipaq.c
==============================================================================
--- head/sys/dev/usb/serial/uipaq.c     Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/uipaq.c     Wed Aug 15 15:42:57 2012        
(r239299)
@@ -103,7 +103,7 @@ struct uipaq_softc {
 static device_probe_t uipaq_probe;
 static device_attach_t uipaq_attach;
 static device_detach_t uipaq_detach;
-static device_free_softc_t uipaq_free_softc;
+static void uipaq_free_softc(struct uipaq_softc *);
 
 static usb_callback_t uipaq_write_callback;
 static usb_callback_t uipaq_read_callback;
@@ -1073,7 +1073,6 @@ static device_method_t uipaq_methods[] =
        DEVMETHOD(device_probe, uipaq_probe),
        DEVMETHOD(device_attach, uipaq_attach),
        DEVMETHOD(device_detach, uipaq_detach),
-       DEVMETHOD(device_free_softc, uipaq_free_softc),
        DEVMETHOD_END
 };
 
@@ -1182,27 +1181,28 @@ uipaq_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UIPAQ_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       uipaq_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(uipaq);
 
 static void
-uipaq_free_softc(device_t dev, void *arg)
+uipaq_free_softc(struct uipaq_softc *sc)
 {
-       struct uipaq_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 uipaq_free(struct ucom_softc *ucom)
 {
-       uipaq_free_softc(NULL, ucom->sc_parent);
+       uipaq_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/umcs.c
==============================================================================
--- head/sys/dev/usb/serial/umcs.c      Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/umcs.c      Wed Aug 15 15:42:57 2012        
(r239299)
@@ -176,7 +176,7 @@ static void umcs7840_poll(struct ucom_so
 static device_probe_t umcs7840_probe;
 static device_attach_t umcs7840_attach;
 static device_detach_t umcs7840_detach;
-static device_free_softc_t umcs7840_free_softc;
+static void umcs7840_free_softc(struct umcs7840_softc *);
 
 static usb_callback_t umcs7840_intr_callback;
 static usb_callback_t umcs7840_read_callback1;
@@ -265,7 +265,6 @@ static device_method_t umcs7840_methods[
        DEVMETHOD(device_probe, umcs7840_probe),
        DEVMETHOD(device_attach, umcs7840_attach),
        DEVMETHOD(device_detach, umcs7840_detach),
-       DEVMETHOD(device_free_softc, umcs7840_free_softc),
        DEVMETHOD_END
 };
 
@@ -413,27 +412,28 @@ umcs7840_detach(device_t dev)
                
usbd_transfer_unsetup(sc->sc_ports[sc->sc_ucom[subunit].sc_portno].sc_xfer, 
UMCS7840_N_TRANSFERS);
        usbd_transfer_unsetup(&sc->sc_intr_xfer, 1);
 
+       device_claim_softc(dev);
+
+       umcs7840_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(umcs7840);
 
 static void
-umcs7840_free_softc(device_t dev, void *arg)
+umcs7840_free_softc(struct umcs7840_softc *sc)
 {
-       struct umcs7840_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 umcs7840_free(struct ucom_softc *ucom)
 {
-       umcs7840_free_softc(NULL, ucom->sc_parent);
+       umcs7840_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/umct.c
==============================================================================
--- head/sys/dev/usb/serial/umct.c      Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/umct.c      Wed Aug 15 15:42:57 2012        
(r239299)
@@ -122,7 +122,7 @@ struct umct_softc {
 static device_probe_t umct_probe;
 static device_attach_t umct_attach;
 static device_detach_t umct_detach;
-static device_free_softc_t umct_free_softc;
+static void umct_free_softc(struct umct_softc *);
 
 static usb_callback_t umct_intr_callback;
 static usb_callback_t umct_intr_callback_sub;
@@ -206,7 +206,6 @@ static device_method_t umct_methods[] = 
        DEVMETHOD(device_probe, umct_probe),
        DEVMETHOD(device_attach, umct_attach),
        DEVMETHOD(device_detach, umct_detach),
-       DEVMETHOD(device_free_softc, umct_free_softc),
        DEVMETHOD_END
 };
 
@@ -314,27 +313,28 @@ umct_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UMCT_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       umct_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(umct);
 
 static void
-umct_free_softc(device_t dev, void *arg)
+umct_free_softc(struct umct_softc *sc)
 {
-       struct umct_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 umct_free(struct ucom_softc *ucom)
 {
-       umct_free_softc(NULL, ucom->sc_parent);
+       umct_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/umodem.c
==============================================================================
--- head/sys/dev/usb/serial/umodem.c    Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/umodem.c    Wed Aug 15 15:42:57 2012        
(r239299)
@@ -178,7 +178,7 @@ struct umodem_softc {
 static device_probe_t umodem_probe;
 static device_attach_t umodem_attach;
 static device_detach_t umodem_detach;
-static device_free_softc_t umodem_free_softc;
+static void umodem_free_softc(struct umodem_softc *);
 
 static usb_callback_t umodem_intr_callback;
 static usb_callback_t umodem_write_callback;
@@ -259,7 +259,6 @@ static device_method_t umodem_methods[] 
        DEVMETHOD(device_probe, umodem_probe),
        DEVMETHOD(device_attach, umodem_attach),
        DEVMETHOD(device_detach, umodem_detach),
-       DEVMETHOD(device_free_softc, umodem_free_softc),
        DEVMETHOD_END
 };
 
@@ -881,27 +880,28 @@ umodem_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UMODEM_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       umodem_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(umodem);
 
 static void
-umodem_free_softc(device_t dev, void *arg)
+umodem_free_softc(struct umodem_softc *sc)
 {
-       struct umodem_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 umodem_free(struct ucom_softc *ucom)
 {
-       umodem_free_softc(NULL, ucom->sc_parent);
+       umodem_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/umoscom.c
==============================================================================
--- head/sys/dev/usb/serial/umoscom.c   Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/umoscom.c   Wed Aug 15 15:42:57 2012        
(r239299)
@@ -189,7 +189,7 @@ struct umoscom_softc {
 static device_probe_t umoscom_probe;
 static device_attach_t umoscom_attach;
 static device_detach_t umoscom_detach;
-static device_free_softc_t umoscom_free_softc;
+static void umoscom_free_softc(struct umoscom_softc *);
 
 static usb_callback_t umoscom_write_callback;
 static usb_callback_t umoscom_read_callback;
@@ -267,7 +267,6 @@ static device_method_t umoscom_methods[]
        DEVMETHOD(device_probe, umoscom_probe),
        DEVMETHOD(device_attach, umoscom_attach),
        DEVMETHOD(device_detach, umoscom_detach),
-       DEVMETHOD(device_free_softc, umoscom_free_softc),
        DEVMETHOD_END
 };
 
@@ -360,27 +359,28 @@ umoscom_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UMOSCOM_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       umoscom_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(umoscom);
 
 static void
-umoscom_free_softc(device_t dev, void *arg)
+umoscom_free_softc(struct umoscom_softc *sc)
 {
-       struct umoscom_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 umoscom_free(struct ucom_softc *ucom)
 {
-       umoscom_free_softc(NULL, ucom->sc_parent);
+       umoscom_free_softc(ucom->sc_parent);
 }
 
 static void

Modified: head/sys/dev/usb/serial/uplcom.c
==============================================================================
--- head/sys/dev/usb/serial/uplcom.c    Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/uplcom.c    Wed Aug 15 15:42:57 2012        
(r239299)
@@ -193,7 +193,7 @@ static void uplcom_poll(struct ucom_soft
 static device_probe_t uplcom_probe;
 static device_attach_t uplcom_attach;
 static device_detach_t uplcom_detach;
-static device_free_softc_t uplcom_free_softc;
+static void uplcom_free_softc(struct uplcom_softc *);
 
 static usb_callback_t uplcom_intr_callback;
 static usb_callback_t uplcom_write_callback;
@@ -318,7 +318,6 @@ static device_method_t uplcom_methods[] 
        DEVMETHOD(device_probe, uplcom_probe),
        DEVMETHOD(device_attach, uplcom_attach),
        DEVMETHOD(device_detach, uplcom_detach),
-       DEVMETHOD(device_free_softc, uplcom_free_softc),
        DEVMETHOD_END
 };
 
@@ -471,27 +470,28 @@ uplcom_detach(device_t dev)
        ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
        usbd_transfer_unsetup(sc->sc_xfer, UPLCOM_N_TRANSFER);
 
+       device_claim_softc(dev);
+
+       uplcom_free_softc(sc);
+
        return (0);
 }
 
 UCOM_UNLOAD_DRAIN(uplcom);
 
 static void
-uplcom_free_softc(device_t dev, void *arg)
+uplcom_free_softc(struct uplcom_softc *sc)
 {
-       struct uplcom_softc *sc = arg;
-
        if (ucom_unref(&sc->sc_super_ucom)) {
-               if (mtx_initialized(&sc->sc_mtx))
-                       mtx_destroy(&sc->sc_mtx);
-               device_free_softc(dev, sc);
+               mtx_destroy(&sc->sc_mtx);
+               device_free_softc(sc);
        }
 }
 
 static void
 uplcom_free(struct ucom_softc *ucom)
 {
-       uplcom_free_softc(NULL, ucom->sc_parent);
+       uplcom_free_softc(ucom->sc_parent);
 }
 
 static usb_error_t

Modified: head/sys/dev/usb/serial/usb_serial.c
==============================================================================
--- head/sys/dev/usb/serial/usb_serial.c        Wed Aug 15 15:35:20 2012        
(r239298)
+++ head/sys/dev/usb/serial/usb_serial.c        Wed Aug 15 15:42:57 2012        
(r239299)
@@ -284,11 +284,14 @@ ucom_attach(struct ucom_super_softc *ssc
                return (error);
        }
        ssc->sc_subunits = subunits;
+       ssc->sc_flag = UCOM_FLAG_ATTACHED |
+           UCOM_FLAG_FREE_UNIT;
 
-       if (callback->ucom_free == NULL) {
-               ssc->sc_wait_refs = 1;
-               ucom_ref(ssc);
-       }
+       if (callback->ucom_free == NULL)
+               ssc->sc_flag |= UCOM_FLAG_WAIT_REFS;
+
+       /* increment reference count */
+       ucom_ref(ssc);
 
        for (subunit = 0; subunit < ssc->sc_subunits; subunit++) {
                sc[subunit].sc_subunit = subunit;
@@ -316,15 +319,15 @@ ucom_attach(struct ucom_super_softc *ssc
 }
 
 /*
- * NOTE: the following function will do nothing if
- * the structure pointed to by "ssc" and "sc" is zero.
+ * The following function will do nothing if the structure pointed to
+ * by "ssc" and "sc" is zero or has already been detached.
  */
 void
 ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc)
 {
        int subunit;
 
-       if (ssc->sc_subunits == 0)
+       if (!(ssc->sc_flag & UCOM_FLAG_ATTACHED))
                return;         /* not initialized */
 
        if (ssc->sc_sysctl_ttyname != NULL) {
@@ -350,17 +353,20 @@ ucom_detach(struct ucom_super_softc *ssc
        }
        usb_proc_free(&ssc->sc_tq);
 
-       if (ssc->sc_wait_refs != 0) {
-               ucom_unref(ssc);
+       ucom_unref(ssc);
+
+       if (ssc->sc_flag & UCOM_FLAG_WAIT_REFS)
                ucom_drain(ssc);
-       }
+
+       /* make sure we don't detach twice */
+       ssc->sc_flag &= ~UCOM_FLAG_ATTACHED;
 }
 
 void
 ucom_drain(struct ucom_super_softc *ssc)
 {
        mtx_lock(&ucom_mtx);
-       while (ssc->sc_refs >= 2) {
+       while (ssc->sc_refs > 0) {
                printf("ucom: Waiting for a TTY device to close.\n");
                usb_pause_mtx(&ucom_mtx, hz);
        }
@@ -1513,6 +1519,24 @@ ucom_ref(struct ucom_super_softc *ssc)
 }

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to