Beispiel #1
0
static int
ndisusb_detach(device_t self)
{
	int i;
	struct ndis_softc       *sc = device_get_softc(self);
	struct ndisusb_ep	*ne;

	sc->ndisusb_status |= NDISUSB_STATUS_DETACH;

	ndis_pnpevent_nic(self, NDIS_PNP_EVENT_SURPRISE_REMOVED);

	if (sc->ndisusb_status & NDISUSB_STATUS_SETUP_EP) {
		usbd_transfer_unsetup(sc->ndisusb_dread_ep.ne_xfer, 1);
		usbd_transfer_unsetup(sc->ndisusb_dwrite_ep.ne_xfer, 1);
	}
	for (i = 0; i < NDISUSB_ENDPT_MAX; i++) {
		ne = &sc->ndisusb_ep[i];
		usbd_transfer_unsetup(ne->ne_xfer, 1);
	}

	(void)ndis_detach(self);

	lockuninit(&sc->ndisusb_lock);
	return (0);
}
Beispiel #2
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);
}
Beispiel #3
0
static int
ndis_detach_usb(device_t dev)
{
	struct ndis_softc *sc;
	struct ndisusb_ep *ne;
	int i;

	sc = device_get_softc(dev);
	sc->ndisusb_status |= NDISUSB_STATUS_DETACH;

	ndis_pnp_event_nic(sc, NDIS_DEVICE_PNP_EVENT_SURPRISE_REMOVED, 0);

	if (sc->ndisusb_status & NDISUSB_STATUS_SETUP_EP) {
		usbd_transfer_unsetup(sc->ndisusb_dread_ep.ne_xfer, 1);
		usbd_transfer_unsetup(sc->ndisusb_dwrite_ep.ne_xfer, 1);
	}
	for (i = 0; i < NDISUSB_ENDPT_MAX; i++) {
		ne = &sc->ndisusb_ep[i];
		usbd_transfer_unsetup(ne->ne_xfer, 1);
	}

	ndis_detach(dev);

	mtx_destroy(&sc->ndisusb_mtx);
	return (0);
}
static int
ugen_transfer_setup(struct usb_fifo *f,
    const struct usb_config *setup, uint8_t n_setup)
{
	struct usb_endpoint *ep = usb_fifo_softc(f);
	struct usb_device *udev = f->udev;
	uint8_t iface_index = ep->iface_index;
	int error;

	mtx_unlock(f->priv_mtx);

	/*
	 * "usbd_transfer_setup()" can sleep so one needs to make a wrapper,
	 * exiting the mutex and checking things
	 */
	error = usbd_transfer_setup(udev, &iface_index, f->xfer,
	    setup, n_setup, f, f->priv_mtx);
	if (error == 0) {

		if (f->xfer[0]->nframes == 1) {
			error = usb_fifo_alloc_buffer(f,
			    f->xfer[0]->max_data_length, 2);
		} else {
			error = usb_fifo_alloc_buffer(f,
			    f->xfer[0]->max_frame_size,
			    2 * f->xfer[0]->nframes);
		}
		if (error) {
			usbd_transfer_unsetup(f->xfer, n_setup);
		}
	}
	mtx_lock(f->priv_mtx);

	return (error);
}
Beispiel #5
0
static int
uhso_attach_bulkserial(struct uhso_softc *sc, struct usb_interface *iface,
    int type)
{
	usb_error_t uerr;
	int tty;

	/* Try attaching RD/WR/INTR first */
	uerr = usbd_transfer_setup(sc->sc_udev,
	    &iface->idesc->bInterfaceNumber, sc->sc_xfer,
	    uhso_bs_config, UHSO_BULK_ENDPT_MAX, sc, &sc->sc_mtx);
	if (uerr) {
		/* Try only RD/WR */
		uerr = usbd_transfer_setup(sc->sc_udev,
		    &iface->idesc->bInterfaceNumber, sc->sc_xfer,
		    uhso_bs_config, UHSO_BULK_ENDPT_MAX - 1, sc, &sc->sc_mtx);
	}
	if (uerr) {
		UHSO_DPRINTF(0, "usbd_transfer_setup failed");
		return (-1);
	}

	tty = uhso_alloc_tty(sc);
	if (tty < 0) {
		usbd_transfer_unsetup(sc->sc_xfer, UHSO_BULK_ENDPT_MAX);
		return (ENOMEM);
	}

	sc->sc_tty[tty].ht_muxport = -1;
	return (0);
}
Beispiel #6
0
int
ubt_detach(device_t dev)
{
	struct ubt_softc	*sc = device_get_softc(dev);
	node_p			node = sc->sc_node;

	/* Destroy Netgraph node */
	if (node != NULL) {
		sc->sc_node = NULL;
		NG_NODE_REALLY_DIE(node);
		ng_rmnode_self(node);
	}

	/* Make sure ubt_task in gone */
	taskqueue_drain(taskqueue_swi, &sc->sc_task);

	/* Free USB transfers, if any */
	usbd_transfer_unsetup(sc->sc_xfer, UBT_N_TRANSFER);

	/* Destroy queues */
	UBT_NG_LOCK(sc);
	NG_BT_MBUFQ_DESTROY(&sc->sc_cmdq);
	NG_BT_MBUFQ_DESTROY(&sc->sc_aclq);
	NG_BT_MBUFQ_DESTROY(&sc->sc_scoq);
	UBT_NG_UNLOCK(sc);

	mtx_destroy(&sc->sc_if_mtx);
	mtx_destroy(&sc->sc_ng_mtx);

	return (0);
} /* ubt_detach */
Beispiel #7
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);
}
Beispiel #8
0
static int
cdce_detach(device_t dev)
{
	struct cdce_softc *sc = device_get_softc(dev);
	struct usb_ether *ue = &sc->sc_ue;

	/* stop all USB transfers first */
	usbd_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER);
	uether_ifdetach(ue);
	mtx_destroy(&sc->sc_mtx);

	return (0);
}
int
ugen_fs_uninit(struct usb_fifo *f)
{
	if (f->fs_xfer == NULL) {
		return (EINVAL);
	}
	usbd_transfer_unsetup(f->fs_xfer, f->fs_ep_max);
	free(f->fs_xfer, M_USB);
	f->fs_xfer = NULL;
	f->fs_ep_max = 0;
	f->fs_ep_ptr = NULL;
	f->flag_iscomplete = 0;
	usb_fifo_free_buffer(f);
	return (0);
}
Beispiel #10
0
static int
ipheth_detach(device_t dev)
{
	struct ipheth_softc *sc = device_get_softc(dev);
	struct usb_ether *ue = &sc->sc_ue;

	/* stop all USB transfers first */
	usbd_transfer_unsetup(sc->sc_xfer, IPHETH_N_TRANSFER);

	uether_ifdetach(ue);

	lockuninit(&sc->sc_lock);

	return (0);
}
Beispiel #11
0
static int
uhid_detach(device_t dev)
{
	struct uhid_softc *sc = device_get_softc(dev);

	usb_fifo_detach(&sc->sc_fifo);

	usbd_transfer_unsetup(sc->sc_xfer, UHID_N_TRANSFER);

	if (sc->sc_repdesc_ptr) {
		if (!(sc->sc_flags & UHID_FLAG_STATIC_DESC)) {
			free(sc->sc_repdesc_ptr, M_USBDEV);
		}
	}
	mtx_destroy(&sc->sc_mtx);

	return (0);
}
static void
ugen_close(struct usb_fifo *f, int fflags)
{
	DPRINTFN(6, "flag=0x%x\n", fflags);

	/* cleanup */

	mtx_lock(f->priv_mtx);
	usbd_transfer_stop(f->xfer[0]);
	usbd_transfer_stop(f->xfer[1]);
	mtx_unlock(f->priv_mtx);

	usbd_transfer_unsetup(f->xfer, 2);
	usb_fifo_free_buffer(f);

	if (ugen_fs_uninit(f)) {
		/* ignore any errors - we are closing */
		DPRINTFN(6, "no FIFOs\n");
	}
}
Beispiel #13
0
static int
g_modem_detach(device_t dev)
{
	struct g_modem_softc *sc = device_get_softc(dev);

	DPRINTF("\n");

	lockmgr(&sc->sc_lock, LK_EXCLUSIVE);
	usb_callout_stop(&sc->sc_callout);
	usb_callout_stop(&sc->sc_watchdog);
	lockmgr(&sc->sc_lock, LK_RELEASE);

	usbd_transfer_unsetup(sc->sc_xfer, G_MODEM_N_TRANSFER);

	usb_callout_drain(&sc->sc_callout);
	usb_callout_drain(&sc->sc_watchdog);

	lockuninit(&sc->sc_lock);

	return (0);
}
Beispiel #14
0
static int
g_audio_detach(device_t dev)
{
	struct g_audio_softc *sc = device_get_softc(dev);

	DPRINTF("\n");

	mtx_lock(&sc->sc_mtx);
	usb_callout_stop(&sc->sc_callout);
	usb_callout_stop(&sc->sc_watchdog);
	mtx_unlock(&sc->sc_mtx);

	usbd_transfer_unsetup(sc->sc_xfer, G_AUDIO_N_TRANSFER);

	usb_callout_drain(&sc->sc_callout);
	usb_callout_drain(&sc->sc_watchdog);

	mtx_destroy(&sc->sc_mtx);

	return (0);
}
Beispiel #15
0
static int
rtwn_usb_detach(device_t self)
{
	struct rtwn_usb_softc *uc = device_get_softc(self);
	struct rtwn_softc *sc = &uc->uc_sc;

	/* Generic detach. */
	rtwn_detach(sc);

	/* Free Tx/Rx buffers. */
	rtwn_usb_free_tx_list(sc);
	rtwn_usb_free_rx_list(sc);

	/* Detach all USB transfers. */
	usbd_transfer_unsetup(uc->uc_xfer, RTWN_N_TRANSFER);

	rtwn_detach_private(sc);
	mtx_destroy(&sc->sc_mtx);

	return (0);
}
static int
ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
{
	struct usb_config usb_config[1];
	struct usb_device_request req;
	union {
		struct usb_fs_complete *pcomp;
		struct usb_fs_start *pstart;
		struct usb_fs_stop *pstop;
		struct usb_fs_open *popen;
		struct usb_fs_close *pclose;
		struct usb_fs_clear_stall_sync *pstall;
		void   *addr;
	}     u;
	struct usb_endpoint *ep;
	struct usb_endpoint_descriptor *ed;
	int error = 0;
	uint8_t iface_index;
	uint8_t isread;
	uint8_t ep_index;

	u.addr = addr;

	DPRINTFN(6, "cmd=0x%08lx\n", cmd);

	switch (cmd) {
	case USB_FS_COMPLETE:
		mtx_lock(f->priv_mtx);
		error = ugen_fs_get_complete(f, &ep_index);
		mtx_unlock(f->priv_mtx);

		if (error) {
			error = EBUSY;
			break;
		}
		u.pcomp->ep_index = ep_index;
		error = ugen_fs_copy_out(f, u.pcomp->ep_index);
		break;

	case USB_FS_START:
		error = ugen_fs_copy_in(f, u.pstart->ep_index);
		if (error) {
			break;
		}
		mtx_lock(f->priv_mtx);
		usbd_transfer_start(f->fs_xfer[u.pstart->ep_index]);
		mtx_unlock(f->priv_mtx);
		break;

	case USB_FS_STOP:
		if (u.pstop->ep_index >= f->fs_ep_max) {
			error = EINVAL;
			break;
		}
		mtx_lock(f->priv_mtx);
		usbd_transfer_stop(f->fs_xfer[u.pstop->ep_index]);
		mtx_unlock(f->priv_mtx);
		break;

	case USB_FS_OPEN:
		if (u.popen->ep_index >= f->fs_ep_max) {
			error = EINVAL;
			break;
		}
		if (f->fs_xfer[u.popen->ep_index] != NULL) {
			error = EBUSY;
			break;
		}
		if (u.popen->max_bufsize > USB_FS_MAX_BUFSIZE) {
			u.popen->max_bufsize = USB_FS_MAX_BUFSIZE;
		}
		if (u.popen->max_frames > USB_FS_MAX_FRAMES) {
			u.popen->max_frames = USB_FS_MAX_FRAMES;
			break;
		}
		if (u.popen->max_frames == 0) {
			error = EINVAL;
			break;
		}
		ep = usbd_get_ep_by_addr(f->udev, u.popen->ep_no);
		if (ep == NULL) {
			error = EINVAL;
			break;
		}
		ed = ep->edesc;
		if (ed == NULL) {
			error = ENXIO;
			break;
		}
		iface_index = ep->iface_index;

		bzero(usb_config, sizeof(usb_config));

		usb_config[0].type = ed->bmAttributes & UE_XFERTYPE;
		usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
		usb_config[0].direction = ed->bEndpointAddress & (UE_DIR_OUT | UE_DIR_IN);
		usb_config[0].interval = USB_DEFAULT_INTERVAL;
		usb_config[0].flags.proxy_buffer = 1;
		usb_config[0].callback = &ugen_default_fs_callback;
		usb_config[0].timeout = 0;	/* no timeout */
		usb_config[0].frames = u.popen->max_frames;
		usb_config[0].bufsize = u.popen->max_bufsize;
		usb_config[0].usb_mode = USB_MODE_DUAL;	/* both modes */

		if (usb_config[0].type == UE_CONTROL) {
			if (f->udev->flags.usb_mode != USB_MODE_HOST) {
				error = EINVAL;
				break;
			}
		} else {

			isread = ((usb_config[0].endpoint &
			    (UE_DIR_IN | UE_DIR_OUT)) == UE_DIR_IN);

			if (f->udev->flags.usb_mode != USB_MODE_HOST) {
				isread = !isread;
			}
			/* check permissions */
			if (isread) {
				if (!(fflags & FREAD)) {
					error = EPERM;
					break;
				}
			} else {
				if (!(fflags & FWRITE)) {
					error = EPERM;
					break;
				}
			}
		}
		error = usbd_transfer_setup(f->udev, &iface_index,
		    f->fs_xfer + u.popen->ep_index, usb_config, 1,
		    f, f->priv_mtx);
		if (error == 0) {
			/* update maximums */
			u.popen->max_packet_length =
			    f->fs_xfer[u.popen->ep_index]->max_frame_size;
			u.popen->max_bufsize =
			    f->fs_xfer[u.popen->ep_index]->max_data_length;
			f->fs_xfer[u.popen->ep_index]->priv_fifo =
			    ((uint8_t *)0) + u.popen->ep_index;
		} else {
			error = ENOMEM;
		}
		break;

	case USB_FS_CLOSE:
		if (u.pclose->ep_index >= f->fs_ep_max) {
			error = EINVAL;
			break;
		}
		if (f->fs_xfer[u.pclose->ep_index] == NULL) {
			error = EINVAL;
			break;
		}
		usbd_transfer_unsetup(f->fs_xfer + u.pclose->ep_index, 1);
		break;

	case USB_FS_CLEAR_STALL_SYNC:
		if (u.pstall->ep_index >= f->fs_ep_max) {
			error = EINVAL;
			break;
		}
		if (f->fs_xfer[u.pstall->ep_index] == NULL) {
			error = EINVAL;
			break;
		}
		if (f->udev->flags.usb_mode != USB_MODE_HOST) {
			error = EINVAL;
			break;
		}
		mtx_lock(f->priv_mtx);
		error = usbd_transfer_pending(f->fs_xfer[u.pstall->ep_index]);
		mtx_unlock(f->priv_mtx);

		if (error) {
			return (EBUSY);
		}
		ep = f->fs_xfer[u.pstall->ep_index]->endpoint;

		/* setup a clear-stall packet */
		req.bmRequestType = UT_WRITE_ENDPOINT;
		req.bRequest = UR_CLEAR_FEATURE;
		USETW(req.wValue, UF_ENDPOINT_HALT);
		req.wIndex[0] = ep->edesc->bEndpointAddress;
		req.wIndex[1] = 0;
		USETW(req.wLength, 0);

		error = usbd_do_request(f->udev, NULL, &req, NULL);
		if (error == 0) {
			usbd_clear_data_toggle(f->udev, ep);
		} else {
			error = ENXIO;
		}
		break;

	default:
		error = ENOIOCTL;
		break;
	}

	DPRINTFN(6, "error=%d\n", error);

	return (error);
}