diff options
author | Hans Petter Selasky <hselasky@FreeBSD.org> | 2012-08-10 15:29:41 +0000 |
---|---|---|
committer | Hans Petter Selasky <hselasky@FreeBSD.org> | 2012-08-10 15:29:41 +0000 |
commit | 5805d1782dc26efb42fa24df0dbada6dbe1dd566 (patch) | |
tree | 49b87629c9a67f08dce84f6b5c6c4b928b728c75 /sys/dev/usb/serial/ufoma.c | |
parent | 8f42c748449cace077ee64f5e4a6baa68f723437 (diff) |
Notes
Diffstat (limited to 'sys/dev/usb/serial/ufoma.c')
-rw-r--r-- | sys/dev/usb/serial/ufoma.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/sys/dev/usb/serial/ufoma.c b/sys/dev/usb/serial/ufoma.c index 2f5e756db9be1..5edfef8de1b60 100644 --- a/sys/dev/usb/serial/ufoma.c +++ b/sys/dev/usb/serial/ufoma.c @@ -203,6 +203,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 usb_callback_t ufoma_ctrl_read_callback; static usb_callback_t ufoma_ctrl_write_callback; @@ -214,6 +215,7 @@ static void *ufoma_get_intconf(struct usb_config_descriptor *, struct usb_interface_descriptor *, uint8_t, uint8_t); static void ufoma_cfg_link_state(struct ufoma_softc *); static void ufoma_cfg_activate_state(struct ufoma_softc *, uint16_t); +static void ufoma_free(struct ucom_softc *); static void ufoma_cfg_open(struct ucom_softc *); static void ufoma_cfg_close(struct ucom_softc *); static void ufoma_cfg_set_break(struct ucom_softc *, uint8_t); @@ -304,6 +306,7 @@ static const struct ucom_callback ufoma_callback = { .ucom_start_write = &ufoma_start_write, .ucom_stop_write = &ufoma_stop_write, .ucom_poll = &ufoma_poll, + .ucom_free = &ufoma_free, }; static device_method_t ufoma_methods[] = { @@ -311,7 +314,8 @@ static device_method_t ufoma_methods[] = { DEVMETHOD(device_probe, ufoma_probe), DEVMETHOD(device_attach, ufoma_attach), DEVMETHOD(device_detach, ufoma_detach), - {0, 0} + DEVMETHOD(device_free_softc, ufoma_free_softc), + DEVMETHOD_END }; static devclass_t ufoma_devclass; @@ -385,6 +389,7 @@ ufoma_attach(device_t dev) sc->sc_unit = device_get_unit(dev); mtx_init(&sc->sc_mtx, "ufoma", NULL, MTX_DEF); + ucom_ref(&sc->sc_super_ucom); cv_init(&sc->sc_cv, "CWAIT"); device_set_usb_desc(dev); @@ -495,12 +500,31 @@ ufoma_detach(device_t dev) if (sc->sc_modetable) { free(sc->sc_modetable, M_USBDEV); } - mtx_destroy(&sc->sc_mtx); cv_destroy(&sc->sc_cv); return (0); } +UCOM_UNLOAD_DRAIN(ufoma); + +static void +ufoma_free_softc(device_t dev, void *arg) +{ + 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); + } +} + +static void +ufoma_free(struct ucom_softc *ucom) +{ + ufoma_free_softc(NULL, ucom->sc_parent); +} + static void * ufoma_get_intconf(struct usb_config_descriptor *cd, struct usb_interface_descriptor *id, uint8_t type, uint8_t subtype) |