/* This is necessary when dynamically changing SAIP configuration. */ int sacom_detach(struct device *self, int flags) { struct sacom_softc *sc = (struct sacom_softc *)self; int maj, mn; /* locate the major number */ maj = cdevsw_lookup_major(&sacom_cdevsw); /* Nuke the vnodes for any open instances. */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); mn |= COMDIALOUT_MASK; vdevgone(maj, mn, mn, VCHR); /* Free the receive buffer. */ free(sc->sc_rbuf, M_DEVBUF); /* Detach and free the tty. */ tty_detach(sc->sc_tty); ttyfree(sc->sc_tty); /* Unhook the soft interrupt handler. */ softint_disestablish(sc->sc_si); #if NRND > 0 && defined(RND_COM) /* Unhook the entropy source. */ rnd_detach_source(&sc->rnd_source); #endif return 0; }
int cddetach(struct device *self, int flags) { struct cd_softc *cd = (struct cd_softc *)self; int bmaj, cmaj, mn; cd_kill_buffers(cd); /* Locate the lowest minor number to be detached. */ mn = DISKMINOR(self->dv_unit, 0); for (bmaj = 0; bmaj < nblkdev; bmaj++) if (bdevsw[bmaj].d_open == cdopen) vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK); for (cmaj = 0; cmaj < nchrdev; cmaj++) if (cdevsw[cmaj].d_open == cdopen) vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR); /* Get rid of the power hook. */ if (cd->sc_cdpwrhook != NULL) powerhook_disestablish(cd->sc_cdpwrhook); /* Detach disk. */ disk_detach(&cd->sc_dk); return (0); }
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 com_detach(struct device *self, int flags) { struct com_softc *sc = (struct com_softc *)self; int maj, mn; sc->sc_swflags |= COM_SW_DEAD; /* Locate the major number. */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == comopen) break; /* Nuke the vnodes for any open instances. */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); /* XXX a symbolic constant for the cua bit would be nicer. */ mn |= 0x80; vdevgone(maj, mn, mn, VCHR); /* Detach and free the tty. */ if (sc->sc_tty) { ttyfree(sc->sc_tty); } timeout_del(&sc->sc_dtr_tmo); timeout_del(&sc->sc_diag_tmo); softintr_disestablish(sc->sc_si); return (0); }
void ldenddetach(struct ld_softc *sc) { struct buf *bp; int s, bmaj, cmaj, mn; if ((sc->sc_flags & LDF_ENABLED) == 0) return; /* Wait for commands queued with the hardware to complete. */ if (sc->sc_queuecnt != 0) if (tsleep(&sc->sc_queuecnt, PRIBIO, "lddtch", 30 * hz)) printf("%s: not drained\n", sc->sc_dv.dv_xname); /* Locate the major numbers. */ for (bmaj = 0; bmaj <= nblkdev; bmaj++) if (bdevsw[bmaj].d_open == ldopen) break; for (cmaj = 0; cmaj <= nchrdev; cmaj++) if (cdevsw[cmaj].d_open == ldopen) break; /* Kill off any queued buffers. */ s = splbio(); while ((bp = BUFQ_FIRST(&sc->sc_bufq)) != NULL) { BUFQ_REMOVE(&sc->sc_bufq, bp); bp->b_error = EIO; bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; biodone(bp); } splx(s); /* Nuke the vnodes for any open instances. */ mn = DISKUNIT(sc->sc_dv.dv_unit); vdevgone(bmaj, mn, mn + (MAXPARTITIONS - 1), VBLK); vdevgone(cmaj, mn, mn + (MAXPARTITIONS - 1), VCHR); /* Detach from the disk list. */ disk_detach(&sc->sc_dk); #if NRND > 0 /* Unhook the entropy source. */ rnd_detach_source(&sc->sc_rnd_source); #endif /* Flush the device's cache. */ if (sc->sc_flush != NULL) if ((*sc->sc_flush)(sc) != 0) printf("%s: unable to flush cache\n", sc->sc_dv.dv_xname); }
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 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); }
/* Detach an interface from its attached bpf device. */ void bpfdetach(struct ifnet *ifp) { struct bpf_if *bp, *nbp, **pbp = &bpf_iflist; struct bpf_d *bd; int maj; for (bp = bpf_iflist; bp; bp = nbp) { nbp= bp->bif_next; if (bp->bif_ifp == ifp) { *pbp = nbp; /* Locate the major number. */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == bpfopen) break; for (bd = bp->bif_dlist; bd; bd = bp->bif_dlist) { struct bpf_d *d; /* * Locate the minor number and nuke the vnode * for any open instance. */ LIST_FOREACH(d, &bpf_d_list, bd_list) if (d == bd) { vdevgone(maj, d->bd_unit, d->bd_unit, VCHR); break; } } free(bp, M_DEVBUF); } else
static int ssdetach(device_t self, int flags) { struct ss_softc *ss = device_private(self); int s, cmaj, mn; /* locate the major number */ cmaj = cdevsw_lookup_major(&ss_cdevsw); /* kill any pending restart */ callout_stop(&ss->sc_callout); s = splbio(); /* Kill off any queued buffers. */ bufq_drain(ss->buf_queue); bufq_free(ss->buf_queue); /* Kill off any pending commands. */ scsipi_kill_pending(ss->sc_periph); splx(s); /* Nuke the vnodes for any open instances */ mn = SSUNIT(device_unit(self)); vdevgone(cmaj, mn, mn+SSNMINOR-1, VCHR); return 0; }
static int fddetach(device_t self, int flags) { struct fd_softc *fd = device_private(self); int bmaj, cmaj, i, mn; fd_motor_off(fd); /* locate the major number */ bmaj = bdevsw_lookup_major(&fd_bdevsw); cmaj = cdevsw_lookup_major(&fd_cdevsw); /* Nuke the vnodes for any open instances. */ for (i = 0; i < MAXPARTITIONS; i++) { mn = DISKMINOR(device_unit(self), i); vdevgone(bmaj, mn, mn, VBLK); vdevgone(cmaj, mn, mn, VCHR); } pmf_device_deregister(self); #if 0 /* XXX need to undo at detach? */ fd_set_properties(fd); #endif #if NRND > 0 rnd_detach_source(&fd->rnd_source); #endif disk_detach(&fd->sc_dk); disk_destroy(&fd->sc_dk); /* Kill off any queued buffers. */ bufq_drain(fd->sc_q); bufq_free(fd->sc_q); callout_destroy(&fd->sc_motoroff_ch); callout_destroy(&fd->sc_motoron_ch); return 0; }
/* * Detach a keyboard. To keep track of users of the softc we keep * a reference count that's incremented while inside, e.g., read. * If the keyboard is active and the reference count is > 0 (0 is the * normal state) we post an event and then wait for the process * that had the reference to wake us up again. Then we blow away the * vnode and return (which will deallocate the softc). */ int wskbd_detach(device_t self, int flags) { struct wskbd_softc *sc = device_private(self); struct wseventvar *evar; int maj, mn; int s; #if NWSMUX > 0 /* Tell parent mux we're leaving. */ if (sc->sc_base.me_parent != NULL) wsmux_detach_sc(&sc->sc_base); #endif callout_halt(&sc->sc_repeat_ch, NULL); callout_destroy(&sc->sc_repeat_ch); if (sc->sc_isconsole) { KASSERT(wskbd_console_device == sc); wskbd_console_device = NULL; } pmf_device_deregister(self); evar = sc->sc_base.me_evp; if (evar != NULL && evar->io != NULL) { s = spltty(); if (--sc->sc_refcnt >= 0) { struct wscons_event event; /* Wake everyone by generating a dummy event. */ event.type = 0; event.value = 0; if (wsevent_inject(evar, &event, 1) != 0) wsevent_wakeup(evar); /* Wait for processes to go away. */ if (tsleep(sc, PZERO, "wskdet", hz * 60)) aprint_error("wskbd_detach: %s didn't detach\n", device_xname(self)); } splx(s); } /* locate the major number */ maj = cdevsw_lookup_major(&wskbd_cdevsw); /* Nuke the vnodes for any open instances. */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); return (0); }
/* * Detach a keyboard. To keep track of users of the softc we keep * a reference count that's incremented while inside, e.g., read. * If the keyboard is active and the reference count is > 0 (0 is the * normal state) we post an event and then wait for the process * that had the reference to wake us up again. Then we blow away the * vnode and return (which will deallocate the softc). */ int wskbd_detach(struct device *self, int flags) { struct wskbd_softc *sc = (struct wskbd_softc *)self; struct wseventvar *evar; int maj, mn; int s; #if NWSMUX > 0 /* Tell parent mux we're leaving. */ if (sc->sc_base.me_parent != NULL) wsmux_detach_sc(&sc->sc_base); #endif #if NWSDISPLAY > 0 if (sc->sc_repeating) { sc->sc_repeating = 0; timeout_del(&sc->sc_repeat_ch); } #endif if (sc->sc_isconsole) { KASSERT(wskbd_console_device == sc); wskbd_console_device = NULL; } evar = sc->sc_base.me_evp; if (evar != NULL && evar->io != NULL) { s = spltty(); if (--sc->sc_refcnt >= 0) { /* Wake everyone by generating a dummy event. */ if (++evar->put >= WSEVENT_QSIZE) evar->put = 0; WSEVENT_WAKEUP(evar); /* Wait for processes to go away. */ if (tsleep(sc, PZERO, "wskdet", hz * 60)) printf("wskbd_detach: %s didn't detach\n", sc->sc_base.me_dv.dv_xname); } splx(s); } /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == wskbdopen) break; /* Nuke the vnodes for any open instances. */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); return (0); }
static int radiodetach(device_t self, int flags) { int maj, mn; /* locate the major number */ maj = cdevsw_lookup_major(&radio_cdevsw); /* Nuke the vnodes for any open instances (calls close). */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); return (0); }
static int ukdetach(device_t self, int flags) { int cmaj, mn; /* locate the major number */ cmaj = cdevsw_lookup_major(&uk_cdevsw); /* Nuke the vnodes for any open instances */ mn = device_unit(self); vdevgone(cmaj, mn, mn, VCHR); return 0; }
int mididetach(device_t self, int flags) { struct midi_softc *sc = device_private(self); int maj, mn; DPRINTFN(2,("%s: sc=%p flags=%d\n", __func__, sc, flags)); pmf_device_deregister(self); mutex_enter(sc->lock); sc->dying = 1; cv_broadcast(&sc->wchan); cv_broadcast(&sc->rchan); mutex_exit(sc->lock); /* locate the major number */ maj = cdevsw_lookup_major(&midi_cdevsw); /* * Nuke the vnodes for any open instances (calls close). * Will wait until any activity on the device nodes has ceased. * * XXXAD NOT YET. * * XXXAD NEED TO PREVENT NEW REFERENCES THROUGH AUDIO_ENTER(). */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); if (!(sc->props & MIDI_PROP_NO_OUTPUT)) { evcnt_detach(&sc->xmt.bytesDiscarded); evcnt_detach(&sc->xmt.incompleteMessages); } if (sc->props & MIDI_PROP_CAN_INPUT) { evcnt_detach(&sc->rcv.bytesDiscarded); evcnt_detach(&sc->rcv.incompleteMessages); } if (sc->sih != NULL) { softint_disestablish(sc->sih); sc->sih = NULL; } cv_destroy(&sc->wchan); cv_destroy(&sc->rchan); return (0); }
/* * Detach a mouse. To keep track of users of the softc we keep * a reference count that's incremented while inside, e.g., read. * If the mouse is active and the reference count is > 0 (0 is the * normal state) we post an event and then wait for the process * that had the reference to wake us up again. Then we blow away the * vnode and return (which will deallocate the softc). */ int wsmouse_detach(device_t self, int flags) { struct wsmouse_softc *sc = device_private(self); struct wseventvar *evar; int maj, mn; int s; #if NWSMUX > 0 /* Tell parent mux we're leaving. */ if (sc->sc_base.me_parent != NULL) { DPRINTF(("wsmouse_detach:\n")); wsmux_detach_sc(&sc->sc_base); } #endif /* If we're open ... */ evar = sc->sc_base.me_evp; if (evar != NULL && evar->io != NULL) { s = spltty(); if (--sc->sc_refcnt >= 0) { struct wscons_event event; /* Wake everyone by generating a dummy event. */ event.type = 0; event.value = 0; if (wsevent_inject(evar, &event, 1) != 0) wsevent_wakeup(evar); /* Wait for processes to go away. */ if (tsleep(sc, PZERO, "wsmdet", hz * 60)) printf("wsmouse_detach: %s didn't detach\n", device_xname(self)); } splx(s); } /* locate the major number */ maj = cdevsw_lookup_major(&wsmouse_cdevsw); /* Nuke the vnodes for any open instances (calls close). */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); return (0); }
int radiodetach(struct device *self, int flags) { /*struct radio_softc *sc = (struct radio_softc *)self;*/ int maj, mn; /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == radioopen) break; /* Nuke the vnodes for any open instances (calls close). */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); return (0); }
int cir_detach(device_t self, int flags) { struct cir_softc *sc = device_private(self); int maj, mn; /* locate the major number */ maj = cdevsw_lookup_major(&cir_cdevsw); /* Nuke the vnodes for any open instances (calls close). */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); seldestroy(&sc->sc_rdsel); 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); }
/* * Detach a mouse. To keep track of users of the softc we keep * a reference count that's incremented while inside, e.g., read. * If the mouse is active and the reference count is > 0 (0 is the * normal state) we post an event and then wait for the process * that had the reference to wake us up again. Then we blow away the * vnode and return (which will deallocate the softc). */ int wsmouse_detach(struct device *self, int flags) { struct wsmouse_softc *sc = (struct wsmouse_softc *)self; struct wseventvar *evar; int maj, mn; int s; #if NWSMUX > 0 /* Tell parent mux we're leaving. */ if (sc->sc_base.me_parent != NULL) { DPRINTF(("wsmouse_detach:\n")); wsmux_detach_sc(&sc->sc_base); } #endif /* If we're open ... */ evar = sc->sc_base.me_evp; if (evar != NULL && evar->io != NULL) { s = spltty(); if (--sc->sc_refcnt >= 0) { /* Wake everyone by generating a dummy event. */ if (++evar->put >= WSEVENT_QSIZE) evar->put = 0; WSEVENT_WAKEUP(evar); /* Wait for processes to go away. */ if (tsleep(sc, PZERO, "wsmdet", hz * 60)) printf("wsmouse_detach: %s didn't detach\n", sc->sc_base.me_dv.dv_xname); } splx(s); } /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == wsmouseopen) break; /* Nuke the vnodes for any open instances (calls close). */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); return (0); }
int videodetach(struct device *self, int flags) { struct video_softc *sc = (struct video_softc *)self; int maj, mn; if (sc->sc_fbuffer != NULL) free(sc->sc_fbuffer, M_DEVBUF); /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == videoopen) break; /* Nuke the vnodes for any open instances (calls close). */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); return (0); }
int urio_detach(device_t self, int flags) { struct urio_softc *sc = device_private(self); int s; int maj, mn; DPRINTF(("urio_detach: sc=%p flags=%d\n", sc, flags)); sc->sc_dying = 1; /* 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_waitold(sc->sc_dev); } splx(s); /* locate the major number */ maj = cdevsw_lookup_major(&urio_cdevsw); /* Nuke the vnodes for any open instances (calls close). */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->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 uscanner_detach(device_t self, int flags) { struct uscanner_softc *sc = device_private(self); int s; int maj, mn; DPRINTF(("uscanner_detach: sc=%p flags=%d\n", sc, flags)); sc->sc_dying = 1; sc->sc_dev_flags = 0; /* make close really close device */ /* Abort all pipes. Causes processes waiting for transfer to wake. */ 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) { /* Wait for processes to go away. */ usb_detach_waitold(sc->sc_dev); } splx(s); /* locate the major number */ maj = cdevsw_lookup_major(&uscanner_cdevsw); /* Nuke the vnodes for any open instances (calls close). */ mn = device_unit(self) * USB_MAX_ENDPOINTS; vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); seldestroy(&sc->sc_selq); return (0); }
int mididetach(struct device *self, int flags) { struct midi_softc *sc = (struct midi_softc *)self; int maj, mn; /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) { if (cdevsw[maj].d_open == midiopen) { /* Nuke the vnodes for any open instances (calls close). */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); } } /* * The close() method did nothing (device_lookup() returns * NULL), so quickly halt transfers (normally parent is already * gone, and code below is no-op), and wake-up user-land blocked * in read/write/ioctl, which return EIO. */ if (sc->flags) { if (sc->flags & FREAD) { sc->rchan = 0; wakeup(&sc->rchan); selwakeup(&sc->rsel); } if (sc->flags & FWRITE) { sc->wchan = 0; wakeup(&sc->wchan); selwakeup(&sc->wsel); } sc->hw_if->close(sc->hw_hdl); sc->flags = 0; } 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); }
static void vndclear(struct vnd_softc *vnd, int myminor) { struct vnode *vp = vnd->sc_vp; int fflags = FREAD; int bmaj, cmaj, i, mn; int s; #ifdef DEBUG if (vnddebug & VDB_FOLLOW) printf("vndclear(%p): vp %p\n", vnd, vp); #endif /* locate the major number */ bmaj = bdevsw_lookup_major(&vnd_bdevsw); cmaj = cdevsw_lookup_major(&vnd_cdevsw); /* Nuke the vnodes for any open instances */ for (i = 0; i < MAXPARTITIONS; i++) { mn = DISKMINOR(device_unit(vnd->sc_dev), i); vdevgone(bmaj, mn, mn, VBLK); if (mn != myminor) /* XXX avoid to kill own vnode */ vdevgone(cmaj, mn, mn, VCHR); } if ((vnd->sc_flags & VNF_READONLY) == 0) fflags |= FWRITE; s = splbio(); bufq_drain(vnd->sc_tab); splx(s); vnd->sc_flags |= VNF_VUNCONF; wakeup(&vnd->sc_tab); while (vnd->sc_flags & VNF_KTHREAD) tsleep(&vnd->sc_kthread, PRIBIO, "vnthr", 0); #ifdef VND_COMPRESSION /* free the compressed file buffers */ if (vnd->sc_flags & VNF_COMP) { if (vnd->sc_comp_offsets) { free(vnd->sc_comp_offsets, M_DEVBUF); vnd->sc_comp_offsets = NULL; } if (vnd->sc_comp_buff) { free(vnd->sc_comp_buff, M_DEVBUF); vnd->sc_comp_buff = NULL; } if (vnd->sc_comp_decombuf) { free(vnd->sc_comp_decombuf, M_DEVBUF); vnd->sc_comp_decombuf = NULL; } } #endif /* VND_COMPRESSION */ vnd->sc_flags &= ~(VNF_INITED | VNF_READONLY | VNF_VLABEL | VNF_VUNCONF | VNF_COMP | VNF_CLEARING); if (vp == NULL) panic("vndclear: null vp"); (void) vn_close(vp, fflags, vnd->sc_cred); kauth_cred_free(vnd->sc_cred); vnd->sc_vp = NULL; vnd->sc_cred = NULL; vnd->sc_size = 0; }
int ucom_detach(device_t self, int flags) { struct ucom_softc *sc = device_private(self); struct tty *tp = sc->sc_tty; int maj, mn; int s, i; 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; pmf_device_deregister(self); 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) { mutex_spin_enter(&tty_lock); CLR(tp->t_state, TS_CARR_ON); CLR(tp->t_cflag, CLOCAL | MDMBUF); ttyflush(tp, FREAD|FWRITE); mutex_spin_exit(&tty_lock); } /* Wait for processes to go away. */ usb_detach_waitold(sc->sc_dev); } softint_disestablish(sc->sc_si); splx(s); /* locate the major number */ maj = cdevsw_lookup_major(&ucom_cdevsw); /* Nuke the vnodes for any open instances. */ mn = device_unit(self); DPRINTF(("ucom_detach: maj=%d mn=%d\n", maj, mn)); vdevgone(maj, mn, mn, VCHR); vdevgone(maj, mn | UCOMDIALOUT_MASK, mn | UCOMDIALOUT_MASK, VCHR); vdevgone(maj, mn | UCOMCALLUNIT_MASK, mn | UCOMCALLUNIT_MASK, VCHR); /* Detach and free the tty. */ if (tp != NULL) { tty_detach(tp); tty_free(tp); sc->sc_tty = NULL; } for (i = 0; i < UCOM_IN_BUFFS; i++) { if (sc->sc_ibuff[i].ub_xfer != NULL) usbd_free_xfer(sc->sc_ibuff[i].ub_xfer); } for (i = 0; i < UCOM_OUT_BUFFS; i++) { if (sc->sc_obuff[i].ub_xfer != NULL) usbd_free_xfer(sc->sc_obuff[i].ub_xfer); } /* Detach the random source */ rnd_detach_source(&sc->sc_rndsource); return (0); }