int ulpt_detach(struct device *self, int flags) { struct ulpt_softc *sc = (struct ulpt_softc *)self; int s; int maj, mn; DPRINTF(("ulpt_detach: sc=%p\n", sc)); if (sc->sc_out_pipe != NULL) usbd_abort_pipe(sc->sc_out_pipe); if (sc->sc_in_pipe != NULL) usbd_abort_pipe(sc->sc_in_pipe); s = splusb(); if (--sc->sc_refcnt >= 0) { /* There is noone to wake, aborting the pipe is enough */ /* Wait for processes to go away. */ usb_detach_wait(&sc->sc_dev); } splx(s); /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == ulptopen) break; /* Nuke the vnodes for any open instances (calls close). */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); vdevgone(maj, mn | ULPT_NOPRIME , mn | ULPT_NOPRIME, VCHR); return (0); }
int uhid_detach(struct device *self, int flags) { struct uhid_softc *sc = (struct uhid_softc *)self; int s; int maj, mn; DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags)); if (sc->sc_hdev.sc_state & UHIDEV_OPEN) { s = splusb(); if (--sc->sc_refcnt >= 0) { /* Wake everyone */ wakeup(&sc->sc_q); /* Wait for processes to go away. */ usb_detach_wait(&sc->sc_hdev.sc_dev); } splx(s); } /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == uhidopen) break; /* Nuke the vnodes for any open instances (calls close). */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); return (0); }
int ucom_detach(struct device *self, int flags) { struct ucom_softc *sc = (struct ucom_softc *)self; struct tty *tp = sc->sc_tty; int maj, mn; int s; DPRINTF(("ucom_detach: sc=%p flags=%d tp=%p, pipe=%d,%d\n", sc, flags, tp, sc->sc_bulkin_no, sc->sc_bulkout_no)); sc->sc_dying = 1; if (sc->sc_bulkin_pipe != NULL) usbd_abort_pipe(sc->sc_bulkin_pipe); if (sc->sc_bulkout_pipe != NULL) usbd_abort_pipe(sc->sc_bulkout_pipe); s = splusb(); if (--sc->sc_refcnt >= 0) { /* Wake up anyone waiting */ if (tp != NULL) { CLR(tp->t_state, TS_CARR_ON); CLR(tp->t_cflag, CLOCAL | MDMBUF); ttyflush(tp, FREAD|FWRITE); } /* Wait for processes to go away. */ usb_detach_wait(&sc->sc_dev); } splx(s); /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == ucomopen) break; /* Nuke the vnodes for any open instances. */ mn = self->dv_unit; DPRINTF(("ucom_detach: maj=%d mn=%d\n", maj, mn)); vdevgone(maj, mn, mn, VCHR); vdevgone(maj, mn | UCOMCUA_MASK, mn | UCOMCUA_MASK, VCHR); /* Detach and free the tty. */ if (tp != NULL) { ttyfree(tp); sc->sc_tty = NULL; } return (0); }
int ugen_detach(struct device *self, int flags) { struct ugen_softc *sc = (struct ugen_softc *)self; struct ugen_endpoint *sce; int i, dir, endptno; int s, maj, mn; DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags)); /* Abort all pipes. Causes processes waiting for transfer to wake. */ for (i = 0; i < USB_MAX_ENDPOINTS; i++) { for (dir = OUT; dir <= IN; dir++) { sce = &sc->sc_endpoints[i][dir]; if (sce && sce->pipeh) usbd_abort_pipe(sce->pipeh); } } s = splusb(); if (--sc->sc_refcnt >= 0) { /* Wake everyone */ for (i = 0; i < USB_MAX_ENDPOINTS; i++) wakeup(&sc->sc_endpoints[i][IN]); /* Wait for processes to go away. */ usb_detach_wait(&sc->sc_dev); } splx(s); /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == ugenopen) break; /* Nuke the vnodes for any open instances (calls close). */ mn = self->dv_unit * USB_MAX_ENDPOINTS; vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR); for (endptno = 0; endptno < USB_MAX_ENDPOINTS; endptno++) { if (sc->sc_is_open[endptno]) ugen_do_close(sc, endptno, FREAD|FWRITE); } return (0); }
static int ubt_detach(device_t self) { struct ubt_softc *sc = device_get_softc(self); DPRINTF("sc=%p \n", sc); sc->sc_dying = 1; if (!sc->sc_ok) return 0; /* Detach HCI interface */ if (sc->sc_unit) { hci_detach(sc->sc_unit); sc->sc_unit = NULL; } /* * Abort all pipes. Causes processes waiting for transfer to wake. * * Actually, hci_detach() above will call ubt_disable() which may * call ubt_abortdealloc(), but lets be sure since doing it twice * wont cause an error. */ ubt_abortdealloc(sc); /* wait for all processes to finish */ if (sc->sc_refcnt-- > 0) usb_detach_wait(sc->sc_dev); if (sc->sysctl_tree != NULL) { sc->sysctl_tree = NULL; sysctl_ctx_free(&sc->sysctl_ctx); } usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); DPRINTFN(1, "driver detached\n"); return 0; }
int ucom_detach(struct ucom_softc *sc) { struct tty *tp = sc->sc_tty; int s; DPRINTF(("ucom_detach: sc = %p, tp = %p\n", sc, sc->sc_tty)); sc->sc_dying = 1; if (sc->sc_bulkin_pipe != NULL) usbd_abort_pipe(sc->sc_bulkin_pipe); if (sc->sc_bulkout_pipe != NULL) usbd_abort_pipe(sc->sc_bulkout_pipe); if (tp != NULL) { if (tp->t_state & TS_ISOPEN) { device_printf(sc->sc_dev, "still open, forcing close\n"); (*linesw[tp->t_line].l_close)(tp, 0); tp->t_gen++; ttyclose(tp); ttwakeup(tp); ttwwakeup(tp); } } else { DPRINTF(("ucom_detach: no tty\n")); return (0); } s = splusb(); if (--sc->sc_refcnt >= 0) { /* Wait for processes to go away. */ usb_detach_wait(USBDEV(sc->sc_dev)); } splx(s); destroy_dev(sc->dev); return (0); }
int urio_detach(struct device *self, int flags) { struct urio_softc *sc = (struct urio_softc *)self; int s; int maj, mn; DPRINTF(("urio_detach: sc=%p flags=%d\n", sc, flags)); /* Abort all pipes. Causes processes waiting for transfer to wake. */ if (sc->sc_in_pipe != NULL) { usbd_abort_pipe(sc->sc_in_pipe); usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; } if (sc->sc_out_pipe != NULL) { usbd_abort_pipe(sc->sc_out_pipe); usbd_close_pipe(sc->sc_out_pipe); sc->sc_out_pipe = NULL; } s = splusb(); if (--sc->sc_refcnt >= 0) { /* Wait for processes to go away. */ usb_detach_wait(&sc->sc_dev); } splx(s); /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == urioopen) break; /* Nuke the vnodes for any open instances (calls close). */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); return (0); }
int wi_usb_detach(struct device *self, int flags) { struct wi_usb_softc *sc = (struct wi_usb_softc *)self; struct ifnet *ifp = WI_GET_IFP(sc); struct wi_softc *wsc = &sc->sc_wi; int s; int err; /* Detached before attach finished, so just bail out. */ if (!sc->wi_usb_attached) return (0); if (sc->wi_thread_info != NULL) { sc->wi_thread_info->dying = 1; sc->wi_thread_info->status |= WI_DYING; if (sc->wi_thread_info->idle) wakeup(sc->wi_thread_info); } /* tasks? */ s = splusb(); /* detach wi */ if (!(wsc->wi_flags & WI_FLAGS_ATTACHED)) { printf("%s: already detached\n", sc->wi_usb_dev.dv_xname); splx(s); return (0); } wi_detach(&sc->sc_wi); wsc->wi_flags = 0; if (ifp->if_softc != NULL) { ether_ifdetach(ifp); if_detach(ifp); } sc->wi_usb_attached = 0; if (--sc->wi_usb_refcnt >= 0) { /* Wait for processes to go away. */ usb_detach_wait(&sc->wi_usb_dev); } while (sc->wi_usb_nummem) { sc->wi_usb_nummem--; if (sc->wi_usb_txmem[sc->wi_usb_nummem] != NULL) free(sc->wi_usb_txmem[sc->wi_usb_nummem], M_DEVBUF); sc->wi_usb_txmem[sc->wi_usb_nummem] = NULL; } if (sc->wi_usb_ep[WI_USB_ENDPT_INTR] != NULL) { usbd_abort_pipe(sc->wi_usb_ep[WI_USB_ENDPT_INTR]); err = usbd_close_pipe(sc->wi_usb_ep[WI_USB_ENDPT_INTR]); if (err) { printf("%s: close intr pipe failed: %s\n", sc->wi_usb_dev.dv_xname, usbd_errstr(err)); } sc->wi_usb_ep[WI_USB_ENDPT_INTR] = NULL; } if (sc->wi_usb_ep[WI_USB_ENDPT_TX] != NULL) { usbd_abort_pipe(sc->wi_usb_ep[WI_USB_ENDPT_TX]); err = usbd_close_pipe(sc->wi_usb_ep[WI_USB_ENDPT_TX]); if (err) { printf("%s: close tx pipe failed: %s\n", sc->wi_usb_dev.dv_xname, usbd_errstr(err)); } sc->wi_usb_ep[WI_USB_ENDPT_TX] = NULL; } if (sc->wi_usb_ep[WI_USB_ENDPT_RX] != NULL) { usbd_abort_pipe(sc->wi_usb_ep[WI_USB_ENDPT_RX]); err = usbd_close_pipe(sc->wi_usb_ep[WI_USB_ENDPT_RX]); if (err) { printf("%s: close rx pipe failed: %s\n", sc->wi_usb_dev.dv_xname, usbd_errstr(err)); } sc->wi_usb_ep[WI_USB_ENDPT_RX] = NULL; } splx(s); return (0); }
int ucom_detach(struct device *self, int flags) { struct ucom_softc *sc = (struct ucom_softc *)self; struct tty *tp = sc->sc_tty; int maj, mn; int s; DPRINTF(("ucom_detach: sc=%p flags=%d tp=%p, pipe=%d,%d\n", sc, flags, tp, sc->sc_bulkin_no, sc->sc_bulkout_no)); if (sc->sc_bulkin_pipe != NULL) { usbd_abort_pipe(sc->sc_bulkin_pipe); usbd_close_pipe(sc->sc_bulkin_pipe); sc->sc_bulkin_pipe = NULL; } if (sc->sc_bulkout_pipe != NULL) { usbd_abort_pipe(sc->sc_bulkout_pipe); usbd_close_pipe(sc->sc_bulkout_pipe); sc->sc_bulkout_pipe = NULL; } if (sc->sc_ixfer != NULL) { if (sc->sc_uhidev == NULL) usbd_free_xfer(sc->sc_ixfer); sc->sc_ixfer = NULL; } if (sc->sc_oxfer != NULL) { usbd_free_buffer(sc->sc_oxfer); if (sc->sc_uhidev == NULL) usbd_free_xfer(sc->sc_oxfer); sc->sc_oxfer = NULL; } s = splusb(); if (--sc->sc_refcnt >= 0) { /* Wake up anyone waiting */ if (tp != NULL) { CLR(tp->t_state, TS_CARR_ON); CLR(tp->t_cflag, CLOCAL | MDMBUF); ttyflush(tp, FREAD|FWRITE); } usb_detach_wait(&sc->sc_dev); } splx(s); /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == ucomopen) break; /* Nuke the vnodes for any open instances. */ mn = self->dv_unit; DPRINTF(("ucom_detach: maj=%d mn=%d\n", maj, mn)); vdevgone(maj, mn, mn, VCHR); vdevgone(maj, mn | UCOMCUA_MASK, mn | UCOMCUA_MASK, VCHR); /* Detach and free the tty. */ if (tp != NULL) { (*LINESW(tp, l_close))(tp, FNONBLOCK, curproc); s = spltty(); CLR(tp->t_state, TS_BUSY | TS_FLUSH); ttyclose(tp); splx(s); ttyfree(tp); sc->sc_tty = NULL; } return (0); }