Esempio n. 1
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);
}
Esempio n. 2
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);
}
Esempio n. 3
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);
}
Esempio n. 4
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);
}
Esempio n. 5
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;
}
Esempio n. 6
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);
}
Esempio n. 7
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);
}
Esempio n. 8
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);
}
Esempio n. 9
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);
}