Example #1
0
/* 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;
}
Example #2
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);
}
Example #3
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);
}
Example #4
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);
}
Example #5
0
File: ld.c Project: MarginC/kame
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);
}
Example #6
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);
}
Example #7
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);
}
Example #8
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
Example #9
0
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;
}
Example #10
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;
}
Example #11
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);
}
Example #12
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);
}
Example #13
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);
}
Example #14
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;
}
Example #15
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);
}
Example #16
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);
}
Example #17
0
File: radio.c Project: MarginC/kame
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);
}
Example #18
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);
}
Example #19
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);
}
Example #20
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);
}
Example #21
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);
}
Example #22
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);
}
Example #23
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);
}
Example #25
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;
}
Example #26
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);
}
Example #27
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;
}
Example #28
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);
}