summaryrefslogtreecommitdiff
path: root/sys/dev/usb/serial/ufoma.c
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2012-08-10 15:29:41 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2012-08-10 15:29:41 +0000
commit5805d1782dc26efb42fa24df0dbada6dbe1dd566 (patch)
tree49b87629c9a67f08dce84f6b5c6c4b928b728c75 /sys/dev/usb/serial/ufoma.c
parent8f42c748449cace077ee64f5e4a6baa68f723437 (diff)
Notes
Diffstat (limited to 'sys/dev/usb/serial/ufoma.c')
-rw-r--r--sys/dev/usb/serial/ufoma.c28
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)