Пример #1
0
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);
}
Пример #2
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);
}
Пример #3
0
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;
}
Пример #4
0
/*
 * "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);
}
Пример #5
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);
}
Пример #6
0
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);
}
Пример #7
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);
}
Пример #8
0
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);
}
Пример #9
0
/*
 * 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);
}