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
This commit is contained in:
parent
0f8b6a08b6
commit
2e74f8d2a5
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 *
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user