Пример #1
0
int
obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
    unsigned char *buf, size_t len, int *host_endian)
{
	struct usb_device_fdesc udf;
	int fd, err;

	if ((fd = _bus_open(dev->bus_number)) < 0)
		return _errno_to_libusb(errno);

	udf.udf_bus = dev->bus_number;
	udf.udf_addr = dev->device_address;
	udf.udf_config_index = idx;
	udf.udf_size = len;
	udf.udf_data = buf;

	usbi_dbg("index %d, len %d", udf.udf_config_index, len);

	if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
		err = errno;
		close(fd);
		return _errno_to_libusb(err);
	}
	close(fd);

	*host_endian = 0;

	return (len);
}
Пример #2
0
static int
sunos_usb_open_ep0(sunos_dev_handle_priv_t *hpriv, sunos_dev_priv_t *dpriv)
{
	char filename[PATH_MAX + 1];

	if (hpriv->eps[0].datafd > 0) {

		return (LIBUSB_SUCCESS);
	}
	snprintf(filename, PATH_MAX, "%s/cntrl0", dpriv->ugenpath);

	usbi_dbg("opening %s", filename);
	hpriv->eps[0].datafd = open(filename, O_RDWR);
	if (hpriv->eps[0].datafd < 0) {
		return(_errno_to_libusb(errno));
	}

	snprintf(filename, PATH_MAX, "%s/cntrl0stat", dpriv->ugenpath);
	hpriv->eps[0].statfd = open(filename, O_RDONLY);
	if (hpriv->eps[0].statfd < 0) {
		close(hpriv->eps[0].datafd);
		hpriv->eps[0].datafd = -1;

		return(_errno_to_libusb(errno));
	}

	return (LIBUSB_SUCCESS);
}
Пример #3
0
int
_sync_gen_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer;
	int fd, nr = 1;

	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);

	if ((fd = _access_endpoint(transfer)) < 0)
		return _errno_to_libusb(errno);

	if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
		return _errno_to_libusb(errno);

	if (IS_XFERIN(transfer)) {
		if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
			if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0)
				return _errno_to_libusb(errno);

		nr = read(fd, transfer->buffer, transfer->length);
	} else {
		nr = write(fd, transfer->buffer, transfer->length);
	}

	if (nr < 0)
		return _errno_to_libusb(errno);

	itransfer->transferred = nr;

	return (0);
}
Пример #4
0
int
obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
{
	struct usb_ctl_request req;
	int fd, err;

	if ((fd = _bus_open(handle->dev->bus_number)) < 0)
		return _errno_to_libusb(errno);

	usbi_dbg("");

	req.ucr_addr = handle->dev->device_address;
	req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
	req.ucr_request.bRequest = UR_CLEAR_FEATURE;
	USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT);
	USETW(req.ucr_request.wIndex, endpoint);
	USETW(req.ucr_request.wLength, 0);

	if (ioctl(fd, USB_REQUEST, &req) < 0) {
		err = errno;
		close(fd);
		return _errno_to_libusb(err);
	}
	close(fd);

	return (LIBUSB_SUCCESS);
}
Пример #5
0
int
obsd_open(struct libusb_device_handle *handle)
{
	struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
	char devnode[16];

	if (dpriv->devname) {
		/*
		 * Only open ugen(4) attached devices read-write, all
		 * read-only operations are done through the bus node.
		 */
		snprintf(devnode, sizeof(devnode), DEVPATH "%s.00",
		    dpriv->devname);
		dpriv->fd = open(devnode, O_RDWR);
		if (dpriv->fd < 0)
			return _errno_to_libusb(errno);

		usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
	}

	if (pipe(hpriv->pipe) < 0)
		return _errno_to_libusb(errno);

	return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN);
}
Пример #6
0
int
_cache_active_config_descriptor(struct libusb_device *dev)
{
	struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
	struct usb_device_cdesc udc;
	struct usb_device_fdesc udf;
	unsigned char* buf;
	int fd, len, err;

	if ((fd = _bus_open(dev->bus_number)) < 0)
		return _errno_to_libusb(errno);

	usbi_dbg("fd %d, addr %d", fd, dev->device_address);

	udc.udc_bus = dev->bus_number;
	udc.udc_addr = dev->device_address;
	udc.udc_config_index = USB_CURRENT_CONFIG_INDEX;
	if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) {
		err = errno;
		close(fd);
		return _errno_to_libusb(errno);
	}

	usbi_dbg("active bLength %d", udc.udc_desc.bLength);

	len = UGETW(udc.udc_desc.wTotalLength);
	buf = malloc(len);
	if (buf == NULL)
		return (LIBUSB_ERROR_NO_MEM);

	udf.udf_bus = dev->bus_number;
	udf.udf_addr = dev->device_address;
	udf.udf_config_index = udc.udc_config_index;
	udf.udf_size = len;
	udf.udf_data = buf;

	usbi_dbg("index %d, len %d", udf.udf_config_index, len);

	if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
		err = errno;
		close(fd);
		free(buf);
		return _errno_to_libusb(err);
	}
	close(fd);

	if (dpriv->cdesc)
		free(dpriv->cdesc);
	dpriv->cdesc = buf;

	return (LIBUSB_SUCCESS);
}
Пример #7
0
int
sunos_cancel_transfer(struct usbi_transfer *itransfer)
{
	sunos_xfer_priv_t	*tpriv;
	sunos_dev_handle_priv_t	*hpriv;
	struct libusb_transfer	*transfer;
	struct aiocb	*aiocb;
	uint8_t		ep;
	int		ret;

	tpriv = usbi_transfer_get_os_priv(itransfer);
	aiocb = &tpriv->aiocb;
	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	hpriv = (sunos_dev_handle_priv_t *)transfer->dev_handle->os_priv;
	ep = sunos_usb_ep_index(transfer->endpoint);

	ret = aio_cancel(hpriv->eps[ep].datafd, aiocb);

	usbi_dbg("aio->fd=%d fd=%d ret = %d, %s", aiocb->aio_fildes,
	    hpriv->eps[ep].datafd, ret, (ret == AIO_CANCELED)?
	    strerror(0):strerror(errno));

	if (ret != AIO_CANCELED) {
		ret = _errno_to_libusb(errno);
	} else {
	/*
	 * we don't need to call usbi_handle_transfer_cancellation(),
	 * because we'll handle everything in sunos_async_callback.
	 */
		ret = LIBUSB_SUCCESS;
	}

	return (ret);
}
Пример #8
0
int
obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
    int num_ready)
{
	struct libusb_device_handle *handle;
	struct handle_priv *hpriv = NULL;
	struct usbi_transfer *itransfer;
	struct pollfd *pollfd;
	int i, err = 0;

	usbi_dbg("");

	pthread_mutex_lock(&ctx->open_devs_lock);
	for (i = 0; i < nfds && num_ready > 0; i++) {
		pollfd = &fds[i];

		if (!pollfd->revents)
			continue;

		hpriv = NULL;
		num_ready--;
		list_for_each_entry(handle, &ctx->open_devs, list,
		    struct libusb_device_handle) {
			hpriv = (struct handle_priv *)handle->os_priv;

			if (hpriv->pipe[0] == pollfd->fd)
				break;

			hpriv = NULL;
		}

		if (NULL == hpriv) {
			usbi_dbg("fd %d is not an event pipe!", pollfd->fd);
			err = ENOENT;
			break;
		}

		if (pollfd->revents & POLLERR) {
			usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
			usbi_handle_disconnect(handle);
			continue;
		}

		if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) {
			err = errno;
			break;
		}

		if ((err = usbi_handle_transfer_completion(itransfer,
		    LIBUSB_TRANSFER_COMPLETED)))
			break;
	}
	pthread_mutex_unlock(&ctx->open_devs_lock);

	if (err)
		return _errno_to_libusb(err);

	return (LIBUSB_SUCCESS);
}
Пример #9
0
int
obsd_open(struct libusb_device_handle *handle)
{
	struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;

	dpriv->fd = open(dpriv->devnode, O_RDWR);
	if (dpriv->fd < 0) {
		dpriv->fd = open(dpriv->devnode, O_RDONLY);
		if (dpriv->fd < 0)
			return _errno_to_libusb(errno);
	}

	usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd);

	if (pipe(hpriv->pipe) < 0)
		return _errno_to_libusb(errno);

	return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN);
}
Пример #10
0
int
_sync_control_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer;
	struct libusb_control_setup *setup;
	struct device_priv *dpriv;
	struct usb_ctl_request req;

	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
	setup = (struct libusb_control_setup *)transfer->buffer;

	usbi_dbg("type %d request %d value %d index %d length %d timeout %d",
	    setup->bmRequestType, setup->bRequest,
	    libusb_le16_to_cpu(setup->wValue),
	    libusb_le16_to_cpu(setup->wIndex),
	    libusb_le16_to_cpu(setup->wLength), transfer->timeout);

	req.ucr_request.bmRequestType = setup->bmRequestType;
	req.ucr_request.bRequest = setup->bRequest;
	
	(*(uint16_t *)req.ucr_request.wValue) = setup->wValue;
	(*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex;
	(*(uint16_t *)req.ucr_request.wLength) = setup->wLength;
	req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;

	if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
		req.ucr_flags = USBD_SHORT_XFER_OK;

	if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
		return _errno_to_libusb(errno);

	if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0)
		return _errno_to_libusb(errno);

	itransfer->transferred = req.ucr_actlen;

	usbi_dbg("transferred %d", itransfer->transferred);

	return (0);
}
Пример #11
0
int
obsd_set_configuration(struct libusb_device_handle *handle, int config)
{
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;

	usbi_dbg("configuration %d", config);

	if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
		return _errno_to_libusb(errno);

	return _cache_active_config_descriptor(handle->dev, dpriv->fd);
}
Пример #12
0
int
_cache_active_config_descriptor(struct libusb_device *dev, int fd)
{
	struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
	struct usb_config_desc ucd;
	struct usb_full_desc ufd;
	unsigned char* buf;
	int len;

	usbi_dbg("fd %d", fd);

	ucd.ucd_config_index = USB_CURRENT_CONFIG_INDEX;

	if ((ioctl(fd, USB_GET_CONFIG_DESC, &ucd)) < 0)
		return _errno_to_libusb(errno);

	usbi_dbg("active bLength %d", ucd.ucd_desc.bLength);

	len = UGETW(ucd.ucd_desc.wTotalLength);
	buf = malloc(len);
	if (buf == NULL)
		return (LIBUSB_ERROR_NO_MEM);

	ufd.ufd_config_index = ucd.ucd_config_index;
	ufd.ufd_size = len;
	ufd.ufd_data = buf;

	usbi_dbg("index %d, len %d", ufd.ufd_config_index, len);

	if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) {
		free(buf);
		return _errno_to_libusb(errno);
	}

	if (dpriv->cdesc)
		free(dpriv->cdesc);
	dpriv->cdesc = buf;

	return (0);
}
Пример #13
0
int
_sync_gen_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer;
	struct device_priv *dpriv;
	int fd, nr = 1;

	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;

	if (dpriv->devname == NULL)
		return (LIBUSB_ERROR_NOT_SUPPORTED);

	/*
	 * Bulk, Interrupt or Isochronous transfer depends on the
	 * endpoint and thus the node to open.
	 */
	if ((fd = _access_endpoint(transfer)) < 0)
		return _errno_to_libusb(errno);

	if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
		return _errno_to_libusb(errno);

	if (IS_XFERIN(transfer)) {
		if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
			if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0)
				return _errno_to_libusb(errno);

		nr = read(fd, transfer->buffer, transfer->length);
	} else {
		nr = write(fd, transfer->buffer, transfer->length);
	}

	if (nr < 0)
		return _errno_to_libusb(errno);

	itransfer->transferred = nr;

	return (0);
}
Пример #14
0
int
obsd_get_configuration(struct libusb_device_handle *handle, int *config)
{
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;

	usbi_dbg("");

	if (ioctl(dpriv->fd, USB_GET_CONFIG, config) < 0)
		return _errno_to_libusb(errno);

	usbi_dbg("configuration %d", *config);

	return (LIBUSB_SUCCESS);
}
Пример #15
0
int
obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
    unsigned char *buf, size_t len, int *host_endian)
{
	struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
	struct usb_full_desc ufd;
	int fd, err;

	usbi_dbg("index %d, len %d", idx, len);

	
	if (dpriv->fd >= 0) {
		fd = dpriv->fd;
	} else {
		fd = open(dpriv->devnode, O_RDONLY);
		if (fd < 0)
			return _errno_to_libusb(errno);
	}

	ufd.ufd_config_index = idx;
	ufd.ufd_size = len;
	ufd.ufd_data = buf;

	if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) {
		err = errno;
		if (dpriv->fd < 0)
			close(fd);
		return _errno_to_libusb(err);
	}

	if (dpriv->fd < 0)
		close(fd);

	*host_endian = 0;

	return (LIBUSB_SUCCESS);
}
Пример #16
0
int
sunos_submit_transfer(struct usbi_transfer *itransfer)
{
	struct	libusb_transfer *transfer;
	struct	libusb_device_handle *hdl;
	int	err = 0;

	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	hdl = transfer->dev_handle;

	err = sunos_check_device_and_status_open(hdl,
	    transfer->endpoint, transfer->type);
	if (err < 0) {

		return (_errno_to_libusb(err));
	}

	switch (transfer->type) {
	case LIBUSB_TRANSFER_TYPE_CONTROL:
		/* sync transfer */
		usbi_dbg("CTRL transfer: %d", transfer->length);
		err = solaris_submit_ctrl_on_default(transfer);
		break;

	case LIBUSB_TRANSFER_TYPE_BULK:
		/* fallthru */
	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
		if (transfer->type == LIBUSB_TRANSFER_TYPE_BULK)
			usbi_dbg("BULK transfer: %d", transfer->length);
		else
			usbi_dbg("INTR transfer: %d", transfer->length);
		err = sunos_do_async_io(transfer);
		break;

	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
		/* Isochronous/Stream is not supported */

		/* fallthru */
	case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
		if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
			usbi_dbg("ISOC transfer: %d", transfer->length);
		else
			usbi_dbg("BULK STREAM transfer: %d", transfer->length);
		err = LIBUSB_ERROR_NOT_SUPPORTED;
		break;
	}

	return (err);
}
Пример #17
0
int
obsd_set_configuration(struct libusb_device_handle *handle, int config)
{
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;

	if (dpriv->devname == NULL)
		return (LIBUSB_ERROR_NOT_SUPPORTED);

	usbi_dbg("bConfigurationValue %d", config);

	if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
		return _errno_to_libusb(errno);

	return _cache_active_config_descriptor(handle->dev);
}
Пример #18
0
int
obsd_submit_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer;
	struct handle_priv *hpriv;
	int err = 0;

	usbi_dbg("");

	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;

	switch (transfer->type) {
	case LIBUSB_TRANSFER_TYPE_CONTROL:
		err = _sync_control_transfer(itransfer);
		break;
	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
		if (IS_XFEROUT(transfer)) {
			/* Isochronous write is not supported */
			err = LIBUSB_ERROR_NOT_SUPPORTED;
			break;
		}
		err = _sync_gen_transfer(itransfer);
		break;
	case LIBUSB_TRANSFER_TYPE_BULK:
	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
		if (IS_XFEROUT(transfer) &&
		    transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
			err = LIBUSB_ERROR_NOT_SUPPORTED;
			break;
		}
		err = _sync_gen_transfer(itransfer);
		break;
	case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
		err = LIBUSB_ERROR_NOT_SUPPORTED;
		break;
	}

	if (err)
		return (err);

	if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0)
		return _errno_to_libusb(errno);

	return (LIBUSB_SUCCESS);
}
Пример #19
0
int
netbsd_open(struct libusb_device_handle *handle)
{
	struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;

	dpriv->fd = open(dpriv->devnode, O_RDWR);
	if (dpriv->fd < 0) {
		dpriv->fd = open(dpriv->devnode, O_RDONLY);
		if (dpriv->fd < 0)
			return _errno_to_libusb(errno);
	}

	usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd);

	return (LIBUSB_SUCCESS);
}
Пример #20
0
int
obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
{
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
	struct usb_ctl_request req;

	usbi_dbg("");

	req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
	req.ucr_request.bRequest = UR_CLEAR_FEATURE;
	USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT);
	USETW(req.ucr_request.wIndex, endpoint);
	USETW(req.ucr_request.wLength, 0);

	if (ioctl(dpriv->fd, USB_DO_REQUEST, &req) < 0)
		return _errno_to_libusb(errno);

	return (LIBUSB_SUCCESS);
}
Пример #21
0
int
obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface,
    int altsetting)
{
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
	struct usb_alt_interface intf;

	usbi_dbg("iface %d, setting %d", iface, altsetting);

	memset(&intf, 0, sizeof(intf));

	intf.uai_interface_index = iface;
	intf.uai_alt_no = altsetting;

	if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0)
		return _errno_to_libusb(errno);

	return (LIBUSB_SUCCESS);
}
Пример #22
0
int
obsd_open(struct libusb_device_handle *handle)
{
	struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
	char devnode[16];

	if (dpriv->devname) {
		/*
		 * Only open ugen(4) attached devices read-write, all
		 * read-only operations are done through the bus node.
		 */
		snprintf(devnode, sizeof(devnode), DEVPATH "%s.00",
		    dpriv->devname);
		dpriv->fd = open(devnode, O_RDWR);
		if (dpriv->fd < 0)
			return _errno_to_libusb(errno);

		usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
	}

	return (LIBUSB_SUCCESS);
}
Пример #23
0
int
obsd_get_device_list(struct libusb_context * ctx,
	struct discovered_devs **discdevs)
{
	struct libusb_device *dev;
	struct device_priv *dpriv;
	struct usb_device_info di;
	unsigned long session_id;
	char devnode[16];
	int fd, err, i;

	usbi_dbg("");

	
	for (i = 0; i < USB_MAX_DEVICES; i++) {
		
		snprintf(devnode, sizeof(devnode), "/dev/ugen%d.00", i);

		if ((fd = open(devnode, O_RDONLY)) < 0) {
			if (errno != ENOENT && errno != ENXIO)
				usbi_err(ctx, "could not open %s", devnode);
			continue;
		}

		if (ioctl(fd, USB_GET_DEVICEINFO, &di) < 0)
			continue;

		session_id = (di.udi_bus << 8 | di.udi_addr);
		dev = usbi_get_device_by_session_id(ctx, session_id);

		if (dev == NULL) {
			dev = usbi_alloc_device(ctx, session_id);
			if (dev == NULL)
				return (LIBUSB_ERROR_NO_MEM);

			dev->bus_number = di.udi_bus;
			dev->device_address = di.udi_addr;
			dev->speed = di.udi_speed;

			dpriv = (struct device_priv *)dev->os_priv;
			strlcpy(dpriv->devnode, devnode, sizeof(devnode));
			dpriv->fd = -1;

			if (ioctl(fd, USB_GET_DEVICE_DESC, &dpriv->ddesc) < 0) {
				err = errno;
				goto error;
			}

			dpriv->cdesc = NULL;
			if (_cache_active_config_descriptor(dev, fd)) {
				err = errno;
				goto error;
			}

			if ((err = usbi_sanitize_device(dev)))
				goto error;
		}
		close(fd);

		if (discovered_devs_append(*discdevs, dev) == NULL)
			return (LIBUSB_ERROR_NO_MEM);
	}

	return (LIBUSB_SUCCESS);

error:
	close(fd);
	libusb_unref_device(dev);
	return _errno_to_libusb(err);
}
Пример #24
0
int
_sync_control_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer;
	struct libusb_control_setup *setup;
	struct device_priv *dpriv;
	struct usb_ctl_request req;

	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
	setup = (struct libusb_control_setup *)transfer->buffer;

	usbi_dbg("type %x request %x value %x index %d length %d timeout %d",
	    setup->bmRequestType, setup->bRequest,
	    libusb_le16_to_cpu(setup->wValue),
	    libusb_le16_to_cpu(setup->wIndex),
	    libusb_le16_to_cpu(setup->wLength), transfer->timeout);

	req.ucr_addr = transfer->dev_handle->dev->device_address;
	req.ucr_request.bmRequestType = setup->bmRequestType;
	req.ucr_request.bRequest = setup->bRequest;
	/* Don't use USETW, libusb already deals with the endianness */
	(*(uint16_t *)req.ucr_request.wValue) = setup->wValue;
	(*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex;
	(*(uint16_t *)req.ucr_request.wLength) = setup->wLength;
	req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;

	if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
		req.ucr_flags = USBD_SHORT_XFER_OK;

	if (dpriv->devname == NULL) {
		/*
		 * XXX If the device is not attached to ugen(4) it is
		 * XXX still possible to submit a control transfer but
		 * XXX with the default timeout only.
		 */
		int fd, err;

		if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0)
			return _errno_to_libusb(errno);

		if ((ioctl(fd, USB_REQUEST, &req)) < 0) {
			err = errno;
			close(fd);
			return _errno_to_libusb(err);
		}
		close(fd);
	} else {
		if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
			return _errno_to_libusb(errno);

		if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0)
			return _errno_to_libusb(errno);
	}

	itransfer->transferred = req.ucr_actlen;

	usbi_dbg("transferred %d", itransfer->transferred);

	return (0);
}