diff --git a/sys/dev/usb/net/if_usie.c b/sys/dev/usb/net/if_usie.c index 8b49d66fa130..cdbdd6b9c4e3 100644 --- a/sys/dev/usb/net/if_usie.c +++ b/sys/dev/usb/net/if_usie.c @@ -95,7 +95,7 @@ static const STRUCT_USB_HOST_ID usie_devs[] = { 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 diff --git a/sys/dev/usb/net/uhso.c b/sys/dev/usb/net/uhso.c index 073f6f6dcc33..979c1185ead8 100644 --- a/sys/dev/usb/net/uhso.c +++ b/sys/dev/usb/net/uhso.c @@ -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 diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 50af2d563aa4..eb6c4d03e47f 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -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 diff --git a/sys/dev/usb/serial/uark.c b/sys/dev/usb/serial/uark.c index eef7ac2b6c21..f0737f2abfef 100644 --- a/sys/dev/usb/serial/uark.c +++ b/sys/dev/usb/serial/uark.c @@ -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 diff --git a/sys/dev/usb/serial/ubsa.c b/sys/dev/usb/serial/ubsa.c index f434f48fe1d2..0951626de1cf 100644 --- a/sys/dev/usb/serial/ubsa.c +++ b/sys/dev/usb/serial/ubsa.c @@ -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 diff --git a/sys/dev/usb/serial/ubser.c b/sys/dev/usb/serial/ubser.c index 9577a594c47a..dae35ab7327e 100644 --- a/sys/dev/usb/serial/ubser.c +++ b/sys/dev/usb/serial/ubser.c @@ -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 diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c index e62a13c96aba..cdddfb024053 100644 --- a/sys/dev/usb/serial/uchcom.c +++ b/sys/dev/usb/serial/uchcom.c @@ -235,7 +235,7 @@ static void uchcom_poll(struct ucom_softc *ucom); 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 }; diff --git a/sys/dev/usb/serial/ucycom.c b/sys/dev/usb/serial/ucycom.c index 80aa57ed8758..7536a025270c 100644 --- a/sys/dev/usb/serial/ucycom.c +++ b/sys/dev/usb/serial/ucycom.c @@ -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 diff --git a/sys/dev/usb/serial/ufoma.c b/sys/dev/usb/serial/ufoma.c index 0e9adf517297..d929f8630ef0 100644 --- a/sys/dev/usb/serial/ufoma.c +++ b/sys/dev/usb/serial/ufoma.c @@ -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 * diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c index 7ffd4f28373a..0a7f0a21b790 100644 --- a/sys/dev/usb/serial/uftdi.c +++ b/sys/dev/usb/serial/uftdi.c @@ -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 diff --git a/sys/dev/usb/serial/ugensa.c b/sys/dev/usb/serial/ugensa.c index 201a75e52471..5d6785d24633 100644 --- a/sys/dev/usb/serial/ugensa.c +++ b/sys/dev/usb/serial/ugensa.c @@ -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 diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c index 31d2595f2565..f9e54f8c9512 100644 --- a/sys/dev/usb/serial/uipaq.c +++ b/sys/dev/usb/serial/uipaq.c @@ -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 diff --git a/sys/dev/usb/serial/umcs.c b/sys/dev/usb/serial/umcs.c index 038db292b483..2e09ba6fbb47 100644 --- a/sys/dev/usb/serial/umcs.c +++ b/sys/dev/usb/serial/umcs.c @@ -176,7 +176,7 @@ static void umcs7840_poll(struct ucom_softc *ucom); 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 diff --git a/sys/dev/usb/serial/umct.c b/sys/dev/usb/serial/umct.c index e24fbc86ea9d..d8fad9824c4b 100644 --- a/sys/dev/usb/serial/umct.c +++ b/sys/dev/usb/serial/umct.c @@ -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 diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c index 72e60a91ae02..d0dc364814fe 100644 --- a/sys/dev/usb/serial/umodem.c +++ b/sys/dev/usb/serial/umodem.c @@ -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 diff --git a/sys/dev/usb/serial/umoscom.c b/sys/dev/usb/serial/umoscom.c index bec0c45defa5..c51627d0af54 100644 --- a/sys/dev/usb/serial/umoscom.c +++ b/sys/dev/usb/serial/umoscom.c @@ -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 diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c index 11d681050d7b..4549bad4da4d 100644 --- a/sys/dev/usb/serial/uplcom.c +++ b/sys/dev/usb/serial/uplcom.c @@ -193,7 +193,7 @@ static void uplcom_poll(struct ucom_softc *ucom); 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 diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c index 78ab671328dc..c3161d2a9e9b 100644 --- a/sys/dev/usb/serial/usb_serial.c +++ b/sys/dev/usb/serial/usb_serial.c @@ -284,11 +284,14 @@ ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc, 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, struct ucom_softc *sc, } /* - * 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, struct ucom_softc *sc) } 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); } @@ -1512,6 +1518,24 @@ ucom_ref(struct ucom_super_softc *ssc) mtx_unlock(&ucom_mtx); } +/*------------------------------------------------------------------------* + * ucom_free_unit + * + * This function will free the super UCOM's allocated unit + * number. This function can be called on a zero-initialized + * structure. This function can be called multiple times. + *------------------------------------------------------------------------*/ +static void +ucom_free_unit(struct ucom_super_softc *ssc) +{ + if (!(ssc->sc_flag & UCOM_FLAG_FREE_UNIT)) + return; + + ucom_unit_free(ssc->sc_unit); + + ssc->sc_flag &= ~UCOM_FLAG_FREE_UNIT; +} + /*------------------------------------------------------------------------* * ucom_unref * @@ -1525,21 +1549,15 @@ int ucom_unref(struct ucom_super_softc *ssc) { int retval; - int free_unit; mtx_lock(&ucom_mtx); retval = (ssc->sc_refs < 2); - free_unit = (ssc->sc_refs == 1); ssc->sc_refs--; mtx_unlock(&ucom_mtx); - /* - * This function might be called when the "ssc" is only zero - * initialized and in that case the unit number should not be - * freed. - */ - if (free_unit) - ucom_unit_free(ssc->sc_unit); + if (retval) + ucom_free_unit(ssc); + return (retval); } diff --git a/sys/dev/usb/serial/usb_serial.h b/sys/dev/usb/serial/usb_serial.h index 4cacd9c4a655..7d72adfe944a 100644 --- a/sys/dev/usb/serial/usb_serial.h +++ b/sys/dev/usb/serial/usb_serial.h @@ -137,7 +137,7 @@ struct ucom_super_softc { int sc_unit; int sc_subunits; int sc_refs; - int sc_wait_refs; + int sc_flag; /* see UCOM_FLAG_XXX */ struct sysctl_oid *sc_sysctl_ttyname; struct sysctl_oid *sc_sysctl_ttyports; char sc_ttyname[16]; @@ -178,6 +178,8 @@ struct ucom_softc { #define UCOM_FLAG_LL_READY 0x20 /* set if low layer is ready */ #define UCOM_FLAG_HL_READY 0x40 /* set if high layer is ready */ #define UCOM_FLAG_CONSOLE 0x80 /* set if device is a console */ +#define UCOM_FLAG_WAIT_REFS 0x0100 /* set if we must wait for refs */ +#define UCOM_FLAG_FREE_UNIT 0x0200 /* set if we must free the unit */ uint8_t sc_lsr; uint8_t sc_msr; uint8_t sc_mcr; diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c index e2003ede2e73..d6fa4ecd45ca 100644 --- a/sys/dev/usb/serial/uslcom.c +++ b/sys/dev/usb/serial/uslcom.c @@ -146,7 +146,7 @@ struct uslcom_softc { static device_probe_t uslcom_probe; static device_attach_t uslcom_attach; static device_detach_t uslcom_detach; -static device_free_softc_t uslcom_free_softc; +static void uslcom_free_softc(struct uslcom_softc *); static usb_callback_t uslcom_write_callback; static usb_callback_t uslcom_read_callback; @@ -331,7 +331,6 @@ static device_method_t uslcom_methods[] = { DEVMETHOD(device_probe, uslcom_probe), DEVMETHOD(device_attach, uslcom_attach), DEVMETHOD(device_detach, uslcom_detach), - DEVMETHOD(device_free_softc, uslcom_free_softc), DEVMETHOD_END }; @@ -435,27 +434,28 @@ uslcom_detach(device_t dev) usb_callout_drain(&sc->sc_watchdog); + device_claim_softc(dev); + + uslcom_free_softc(sc); + return (0); } UCOM_UNLOAD_DRAIN(uslcom); static void -uslcom_free_softc(device_t dev, void *arg) +uslcom_free_softc(struct uslcom_softc *sc) { - struct uslcom_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 uslcom_free(struct ucom_softc *ucom) { - uslcom_free_softc(NULL, ucom->sc_parent); + uslcom_free_softc(ucom->sc_parent); } static void diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c index 4f3426bb4022..793e8052fa46 100644 --- a/sys/dev/usb/serial/uvisor.c +++ b/sys/dev/usb/serial/uvisor.c @@ -189,7 +189,7 @@ struct uvisor_softc { static device_probe_t uvisor_probe; static device_attach_t uvisor_attach; static device_detach_t uvisor_detach; -static device_free_softc_t uvisor_free_softc; +static void uvisor_free_softc(struct uvisor_softc *); static usb_callback_t uvisor_write_callback; static usb_callback_t uvisor_read_callback; @@ -240,7 +240,6 @@ static device_method_t uvisor_methods[] = { DEVMETHOD(device_probe, uvisor_probe), DEVMETHOD(device_attach, uvisor_attach), DEVMETHOD(device_detach, uvisor_detach), - DEVMETHOD(device_free_softc, uvisor_free_softc), DEVMETHOD_END }; @@ -371,27 +370,28 @@ uvisor_detach(device_t dev) ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UVISOR_N_TRANSFER); + device_claim_softc(dev); + + uvisor_free_softc(sc); + return (0); } UCOM_UNLOAD_DRAIN(uvisor); static void -uvisor_free_softc(device_t dev, void *arg) +uvisor_free_softc(struct uvisor_softc *sc) { - struct uvisor_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 uvisor_free(struct ucom_softc *ucom) { - uvisor_free_softc(NULL, ucom->sc_parent); + uvisor_free_softc(ucom->sc_parent); } static usb_error_t diff --git a/sys/dev/usb/serial/uvscom.c b/sys/dev/usb/serial/uvscom.c index bb91c40b39f8..b4aa3701d92c 100644 --- a/sys/dev/usb/serial/uvscom.c +++ b/sys/dev/usb/serial/uvscom.c @@ -163,7 +163,7 @@ struct uvscom_softc { static device_probe_t uvscom_probe; static device_attach_t uvscom_attach; static device_detach_t uvscom_detach; -static device_free_softc_t uvscom_free_softc; +static void uvscom_free_softc(struct uvscom_softc *); static usb_callback_t uvscom_write_callback; static usb_callback_t uvscom_read_callback; @@ -253,7 +253,6 @@ static device_method_t uvscom_methods[] = { DEVMETHOD(device_probe, uvscom_probe), DEVMETHOD(device_attach, uvscom_attach), DEVMETHOD(device_detach, uvscom_detach), - DEVMETHOD(device_free_softc, uvscom_free_softc), DEVMETHOD_END }; @@ -354,27 +353,28 @@ uvscom_detach(device_t dev) ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UVSCOM_N_TRANSFER); + device_claim_softc(dev); + + uvscom_free_softc(sc); + return (0); } UCOM_UNLOAD_DRAIN(uvscom); static void -uvscom_free_softc(device_t dev, void *arg) +uvscom_free_softc(struct uvscom_softc *sc) { - struct uvscom_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 uvscom_free(struct ucom_softc *ucom) { - uvscom_free_softc(NULL, ucom->sc_parent); + uvscom_free_softc(ucom->sc_parent); } static void diff --git a/sys/kern/device_if.m b/sys/kern/device_if.m index edec42bb2981..eb720eb69dca 100644 --- a/sys/kern/device_if.m +++ b/sys/kern/device_if.m @@ -316,14 +316,3 @@ METHOD int resume { METHOD int quiesce { device_t dev; } DEFAULT null_quiesce; - -/** - * @brief Free the device softc - * - * @param _dev device pointer - * @param _softc pointer to softc - */ -METHOD void free_softc { - device_t _dev; - void *_softc; -} DEFAULT device_free_softc; diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 1356684a56af..fa19cfd301a8 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -2406,8 +2406,8 @@ device_get_softc(device_t dev) void device_set_softc(device_t dev, void *softc) { - if (dev->softc != NULL && !(dev->flags & DF_EXTERNALSOFTC)) - DEVICE_FREE_SOFTC(dev, dev->softc); + if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) + free(dev->softc, M_BUS_SC); dev->softc = softc; if (dev->softc) dev->flags |= DF_EXTERNALSOFTC; @@ -2415,6 +2415,35 @@ device_set_softc(device_t dev, void *softc) dev->flags &= ~DF_EXTERNALSOFTC; } +/** + * @brief Free claimed softc + * + * Most drivers do not need to use this since the softc is freed + * automatically when the driver is detached. + */ +void +device_free_softc(void *softc) +{ + free(softc, M_BUS_SC); +} + +/** + * @brief Claim softc + * + * This function can be used to let the driver free the automatically + * allocated softc using "device_free_softc()". This function is + * useful when the driver is refcounting the softc and the softc + * cannot be freed when the "device_detach" method is called. + */ +void +device_claim_softc(device_t dev) +{ + if (dev->softc) + dev->flags |= DF_EXTERNALSOFTC; + else + dev->flags &= ~DF_EXTERNALSOFTC; +} + /** * @brief Get the device's ivars field * @@ -2604,8 +2633,8 @@ device_set_driver(device_t dev, driver_t *driver) if (dev->driver == driver) return (0); - if (dev->softc != NULL && !(dev->flags & DF_EXTERNALSOFTC)) { - DEVICE_FREE_SOFTC(dev, dev->softc); + if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) { + free(dev->softc, M_BUS_SC); dev->softc = NULL; } device_set_desc(dev, NULL); @@ -4797,13 +4826,3 @@ bus_free_resource(device_t dev, int type, struct resource *r) return (0); return (bus_release_resource(dev, type, rman_get_rid(r), r)); } - -/* - * The "dev" argument passed to "device_free_softc()" is allowed to be - * NULL, if the device freeing the soft is not available. - */ -void -device_free_softc(device_t dev, void *softc) -{ - free(softc, M_BUS_SC); -} diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 941819aba17c..db6d3cf39b20 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -464,11 +464,12 @@ int device_set_devclass(device_t dev, const char *classname); int device_set_driver(device_t dev, driver_t *driver); void device_set_flags(device_t dev, u_int32_t flags); void device_set_softc(device_t dev, void *softc); +void device_free_softc(void *softc); +void device_claim_softc(device_t dev); int device_set_unit(device_t dev, int unit); /* XXX DONT USE XXX */ int device_shutdown(device_t dev); void device_unbusy(device_t dev); void device_verbose(device_t dev); -void device_free_softc(device_t dev, void *softc); /* * Access functions for devclass.