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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }