static int usie_detach(device_t self) { struct usie_softc *sc = device_get_softc(self); uint8_t x; /* detach ifnet */ if (sc->sc_ifp != NULL) { usie_if_stop(sc); usbd_transfer_unsetup(sc->sc_if_xfer, USIE_IF_N_XFER); bpfdetach(sc->sc_ifp); if_detach(sc->sc_ifp); if_free(sc->sc_ifp); sc->sc_ifp = NULL; } /* detach ucom */ if (sc->sc_nucom > 0) ucom_detach(&sc->sc_super_ucom, sc->sc_ucom); /* stop all USB transfers */ usbd_transfer_unsetup(sc->sc_if_xfer, USIE_IF_N_XFER); for (x = 0; x != USIE_UCOM_MAX; x++) usbd_transfer_unsetup(sc->sc_uc_xfer[x], USIE_UC_N_XFER); mtx_destroy(&sc->sc_mtx); return (0); }
static int moscom_detach(device_t self) { struct moscom_softc *sc = device_get_softc(self); int rv = 0; sc->sc_ucom.sc_dying = 1; rv = ucom_detach(&sc->sc_ucom); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_ucom.sc_udev, sc->sc_ucom.sc_dev); return (rv); }
static int ufoma_detach(device_t self) { struct ufoma_softc *sc = device_get_softc(self); int rv = 0; usbd_free_xfer(sc->sc_msgxf); sc->sc_ucom.sc_dying = 1; usbd_abort_pipe(sc->sc_notify_pipe); usbd_close_pipe(sc->sc_notify_pipe); if(sc->sc_is_ucom) ucom_detach(&sc->sc_ucom); else ttyfree(sc->sc_ucom.sc_tty); free(sc->sc_modetable, M_USBDEV); return rv; }
/* * "N" sub_units are setup at a time. All sub-units will * be given sequential unit numbers. The number of * sub-units can be used to differentiate among * different types of devices. * * The mutex pointed to by "mtx" is applied before all * callbacks are called back. Also "mtx" must be applied * before calling into the ucom-layer! */ int ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc, uint32_t sub_units, void *parent, const struct ucom_callback *callback, struct mtx *mtx) { uint32_t n; uint32_t root_unit; int error = 0; if ((sc == NULL) || (sub_units == 0) || (sub_units > UCOM_SUB_UNIT_MAX) || (callback == NULL)) { return (EINVAL); } /* XXX unit management does not really belong here */ if (ucom_units_alloc(sub_units, &root_unit)) { return (ENOMEM); } error = usb_proc_create(&ssc->sc_tq, mtx, "ucom", USB_PRI_MED); if (error) { ucom_units_free(root_unit, sub_units); return (error); } for (n = 0; n != sub_units; n++, sc++) { sc->sc_unit = root_unit + n; sc->sc_local_unit = n; sc->sc_super = ssc; sc->sc_mtx = mtx; sc->sc_parent = parent; sc->sc_callback = callback; error = ucom_attach_tty(sc, sub_units); if (error) { ucom_detach(ssc, sc - n, n); ucom_units_free(root_unit + n, sub_units - n); return (error); } sc->sc_flag |= UCOM_FLAG_ATTACHED; } return (0); }
static int umodem_detach(device_t self) { struct umodem_softc *sc = device_get_softc(self); int rv = 0; DPRINTF(("umodem_detach: sc=%p\n", sc)); if (sc->sc_notify_pipe != NULL) { usbd_abort_pipe(sc->sc_notify_pipe); usbd_close_pipe(sc->sc_notify_pipe); sc->sc_notify_pipe = NULL; } sc->sc_ucom.sc_dying = 1; rv = ucom_detach(&sc->sc_ucom); return (rv); }
static int uhso_detach(device_t self) { struct uhso_softc *sc = device_get_softc(self); int i; usbd_transfer_unsetup(sc->sc_xfer, 3); usbd_transfer_unsetup(sc->sc_ctrl_xfer, UHSO_CTRL_MAX); if (sc->sc_ttys > 0) { ucom_detach(&sc->sc_super_ucom, sc->sc_ucom); for (i = 0; i < sc->sc_ttys; i++) { if (sc->sc_tty[i].ht_muxport != -1) { usbd_transfer_unsetup(sc->sc_tty[i].ht_xfer, UHSO_CTRL_MAX); } } free(sc->sc_tty, M_USBDEV); free(sc->sc_ucom, M_USBDEV); } if (sc->sc_ifp != NULL) { callout_drain(&sc->sc_c); free_unr(uhso_ifnet_unit, sc->sc_ifp->if_dunit); mtx_lock(&sc->sc_mtx); uhso_if_stop(sc); bpfdetach(sc->sc_ifp); if_detach(sc->sc_ifp); if_free(sc->sc_ifp); mtx_unlock(&sc->sc_mtx); usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX); } device_claim_softc(self); uhso_free_softc(sc); return (0); }
static int ubsa_detach(device_t self) { struct ubsa_softc *sc = device_get_softc(self); int rv; DPRINTF(("ubsa_detach: sc = %p\n", sc)); if (sc->sc_intr_pipe != NULL) { usbd_abort_pipe(sc->sc_intr_pipe); usbd_close_pipe(sc->sc_intr_pipe); kfree(sc->sc_intr_buf, M_USBDEV); sc->sc_intr_pipe = NULL; } sc->sc_ucom.sc_dying = 1; rv = ucom_detach(&sc->sc_ucom); return (rv); }
static int ugensa_detach(device_t self) { struct ugensa_softc *sc = device_get_softc(self); int rv = 0; /* close the interrupt endpoint if that is opened */ if (sc->sc_intr_pipe != NULL) { usbd_abort_pipe(sc->sc_intr_pipe); usbd_close_pipe(sc->sc_intr_pipe); kfree(sc->sc_intr_buf, M_USBDEV); sc->sc_intr_pipe = NULL; } DPRINTF(("ugensa_detach: sc=%p\n", sc)); sc->sc_ucom.sc_dying = 1; rv = ucom_detach(&sc->sc_ucom); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_ucom.sc_udev, sc->sc_ucom.sc_dev); return (rv); }
/* * Setup a group of one or more serial ports. * * The mutex pointed to by "mtx" is applied before all * callbacks are called back. Also "mtx" must be applied * before calling into the ucom-layer! */ int ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc, int subunits, void *parent, const struct ucom_callback *callback, struct mtx *mtx) { int subunit; int error = 0; if ((sc == NULL) || (subunits <= 0) || (callback == NULL) || (mtx == NULL)) { return (EINVAL); } /* allocate a uniq unit number */ ssc->sc_unit = ucom_unit_alloc(); if (ssc->sc_unit == -1) return (ENOMEM); /* generate TTY name string */ snprintf(ssc->sc_ttyname, sizeof(ssc->sc_ttyname), UCOM_TTY_PREFIX "%d", ssc->sc_unit); /* create USB request handling process */ error = usb_proc_create(&ssc->sc_tq, mtx, "ucom", USB_PRI_MED); if (error) { ucom_unit_free(ssc->sc_unit); return (error); } ssc->sc_subunits = subunits; ssc->sc_flag = UCOM_FLAG_ATTACHED | UCOM_FLAG_FREE_UNIT; 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; sc[subunit].sc_super = ssc; sc[subunit].sc_mtx = mtx; sc[subunit].sc_parent = parent; sc[subunit].sc_callback = callback; error = ucom_attach_tty(ssc, &sc[subunit]); if (error) { ucom_detach(ssc, &sc[0]); return (error); } /* increment reference count */ ucom_ref(ssc); /* set subunit attached */ sc[subunit].sc_flag |= UCOM_FLAG_ATTACHED; } DPRINTF("tp = %p, unit = %d, subunits = %d\n", sc->sc_tty, ssc->sc_unit, ssc->sc_subunits); return (0); }