static void uhso_free_softc(struct uhso_softc *sc) { if (ucom_unref(&sc->sc_super_ucom)) { mtx_destroy(&sc->sc_mtx); device_free_softc(sc); } }
static void uhso_free_softc(struct uhso_softc *sc) { if (ucom_unref(&sc->sc_super_ucom)) { free(sc->sc_tty, M_USBDEV); free(sc->sc_ucom, M_USBDEV); mtx_destroy(&sc->sc_mtx); device_free_softc(sc); } }
static void ucom_free(void *xsc) { struct ucom_softc *sc = xsc; if (sc->sc_callback->ucom_free != NULL) sc->sc_callback->ucom_free(sc); else ucom_unref(sc->sc_super); mtx_lock(&ucom_mtx); ucom_close_refs--; mtx_unlock(&ucom_mtx); }
/* set RTS in async fashion */ if (sc->sc_flag & UCOM_FLAG_RTS_IFLOW) ucom_rts(sc, 1); DPRINTF("tp=%p, lost %d " "chars\n", tp, res.length - cnt); break; } } } ttydisc_rint_done(tp); #endif } #if 0 /* XXX */ static void ucom_free(void *xsc) { struct ucom_softc *sc = xsc; if (sc->sc_callback->ucom_free != NULL) sc->sc_callback->ucom_free(sc); else ucom_unref(sc->sc_super); lockmgr(&ucom_lock, LK_EXCLUSIVE); ucom_close_refs--; lockmgr(&ucom_lock, LK_RELEASE); }
static void ucom_detach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc) { struct tty *tp = sc->sc_tty; DPRINTF("sc = %p, tp = %p\n", sc, sc->sc_tty); if (sc->sc_flag & UCOM_FLAG_CONSOLE) { UCOM_MTX_LOCK(ucom_cons_softc); ucom_close(ucom_cons_softc); sc->sc_flag &= ~UCOM_FLAG_CONSOLE; UCOM_MTX_UNLOCK(ucom_cons_softc); ucom_cons_softc = NULL; } /* the config thread has been stopped when we get here */ UCOM_MTX_LOCK(sc); sc->sc_flag |= UCOM_FLAG_GONE; sc->sc_flag &= ~(UCOM_FLAG_HL_READY | UCOM_FLAG_LL_READY); UCOM_MTX_UNLOCK(sc); if (tp) { lockmgr(&ucom_lock, LK_EXCLUSIVE); ucom_close_refs++; lockmgr(&ucom_lock, LK_RELEASE); /* tty_lock(tp); */ ucom_close(sc); /* close, if any */ /*tty_rel_gone(tp); */ UCOM_MTX_LOCK(sc); /* * make sure that read and write transfers are stopped */ if (sc->sc_callback->ucom_stop_read) { (sc->sc_callback->ucom_stop_read) (sc); } if (sc->sc_callback->ucom_stop_write) { (sc->sc_callback->ucom_stop_write) (sc); } UCOM_MTX_UNLOCK(sc); } ucom_unref(ssc); }
/* * 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_flag & UCOM_FLAG_ATTACHED)) return; /* not initialized */ if (ssc->sc_sysctl_ttyname != NULL) { sysctl_remove_oid(ssc->sc_sysctl_ttyname, 1, 0); ssc->sc_sysctl_ttyname = NULL; } if (ssc->sc_sysctl_ttyports != NULL) { sysctl_remove_oid(ssc->sc_sysctl_ttyports, 1, 0); ssc->sc_sysctl_ttyports = NULL; } usb_proc_drain(&ssc->sc_tq); for (subunit = 0; subunit < ssc->sc_subunits; subunit++) { if (sc[subunit].sc_flag & UCOM_FLAG_ATTACHED) { ucom_detach_tty(ssc, &sc[subunit]); /* avoid duplicate detach */ sc[subunit].sc_flag &= ~UCOM_FLAG_ATTACHED; } } usb_proc_free(&ssc->sc_tq); 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; }