static int usbdk_do_bulk_transfer(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); struct winfd wfd; TransferResult transferRes; HANDLE sysHandle; transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer; transfer_priv->request.BufferLength = transfer->length; transfer_priv->request.EndpointAddress = transfer->endpoint; switch (transfer->type) { case LIBUSB_TRANSFER_TYPE_BULK: transfer_priv->request.TransferType = BulkTransferType; break; case LIBUSB_TRANSFER_TYPE_INTERRUPT: transfer_priv->request.TransferType = IntertuptTransferType; break; default: usbi_err(ctx, "Wrong transfer type (%d) in usbdk_do_bulk_transfer. %s", transfer->type, windows_error_str(0)); return LIBUSB_ERROR_INVALID_PARAM; } transfer_priv->pollable_fd = INVALID_WINFD; sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); wfd = usbi_create_fd(sysHandle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL); // Always use the handle returned from usbi_create_fd (wfd.handle) if (wfd.fd < 0) return LIBUSB_ERROR_NO_MEM; if (IS_XFERIN(transfer)) transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); else transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); switch (transferRes) { case TransferSuccess: wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; break; case TransferSuccessAsync: break; case TransferFailure: usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0)); usbi_free_fd(&wfd); return LIBUSB_ERROR_IO; } transfer_priv->pollable_fd = wfd; usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, IS_XFERIN(transfer) ? POLLIN : POLLOUT); 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 _access_endpoint(struct libusb_transfer *transfer) { struct handle_priv *hpriv; struct device_priv *dpriv; char *s, devnode[16]; int fd, endpt; mode_t mode; hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; endpt = UE_GET_ADDR(transfer->endpoint); mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; usbi_dbg("endpoint %d mode %d", endpt, mode); if (hpriv->endpoints[endpt] < 0) { strlcpy(devnode, dpriv->devnode, sizeof(devnode)); s = strchr(devnode, '.'); snprintf(s, 4, ".%02d", endpt); if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) if ((fd = open(devnode, mode)) < 0) return (-1); hpriv->endpoints[endpt] = fd; } return (hpriv->endpoints[endpt]); }
int _access_endpoint(struct libusb_transfer *transfer) { struct handle_priv *hpriv; struct device_priv *dpriv; char devnode[16]; int fd, endpt; mode_t mode; hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; endpt = UE_GET_ADDR(transfer->endpoint); mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; usbi_dbg("endpoint %d mode %d", endpt, mode); if (hpriv->endpoints[endpt] < 0) { /* Pick the right endpoint node */ snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d", dpriv->devname, endpt); /* We may need to read/write to the same endpoint later. */ if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) if ((fd = open(devnode, mode)) < 0) return (-1); hpriv->endpoints[endpt] = fd; } return (hpriv->endpoints[endpt]); }
static int usbdk_do_control_transfer(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); struct winfd wfd; ULONG Length; TransferResult transResult; HANDLE sysHandle; sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); wfd = usbi_create_fd(sysHandle, RW_READ, NULL, NULL); // Always use the handle returned from usbi_create_fd (wfd.handle) if (wfd.fd < 0) return LIBUSB_ERROR_NO_MEM; transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer; transfer_priv->request.BufferLength = transfer->length; transfer_priv->request.TransferType = ControlTransferType; transfer_priv->pollable_fd = INVALID_WINFD; Length = (ULONG)transfer->length; if (IS_XFERIN(transfer)) transResult = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); else transResult = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); switch (transResult) { case TransferSuccess: wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; wfd.overlapped->InternalHigh = (DWORD)Length; break; case TransferSuccessAsync: break; case TransferFailure: usbi_err(ctx, "ControlTransfer failed: %s", windows_error_str(0)); usbi_free_fd(&wfd); return LIBUSB_ERROR_IO; } // Use priv_transfer to store data needed for async polling transfer_priv->pollable_fd = wfd; usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN); return LIBUSB_SUCCESS; }
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); }
static int usbdk_do_iso_transfer(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); struct winfd wfd; TransferResult transferRes; int i; HANDLE sysHandle; transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer; transfer_priv->request.BufferLength = transfer->length; transfer_priv->request.EndpointAddress = transfer->endpoint; transfer_priv->request.TransferType = IsochronousTransferType; transfer_priv->request.IsochronousPacketsArraySize = transfer->num_iso_packets; transfer_priv->IsochronousPacketsArray = malloc(transfer->num_iso_packets * sizeof(ULONG64)); transfer_priv->request.IsochronousPacketsArray = (PVOID64)(uintptr_t)transfer_priv->IsochronousPacketsArray; if (!transfer_priv->IsochronousPacketsArray) { usbi_err(ctx, "Allocation of IsochronousPacketsArray is failed, %s", windows_error_str(0)); return LIBUSB_ERROR_IO; } transfer_priv->IsochronousResultsArray = malloc(transfer->num_iso_packets * sizeof(USB_DK_ISO_TRANSFER_RESULT)); transfer_priv->request.Result.IsochronousResultsArray = (PVOID64)(uintptr_t)transfer_priv->IsochronousResultsArray; if (!transfer_priv->IsochronousResultsArray) { usbi_err(ctx, "Allocation of isochronousResultsArray is failed, %s", windows_error_str(0)); free(transfer_priv->IsochronousPacketsArray); return LIBUSB_ERROR_IO; } for (i = 0; i < transfer->num_iso_packets; i++) transfer_priv->IsochronousPacketsArray[i] = transfer->iso_packet_desc[i].length; transfer_priv->pollable_fd = INVALID_WINFD; sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); wfd = usbi_create_fd(sysHandle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL); // Always use the handle returned from usbi_create_fd (wfd.handle) if (wfd.fd < 0) { free(transfer_priv->IsochronousPacketsArray); free(transfer_priv->IsochronousResultsArray); return LIBUSB_ERROR_NO_MEM; } if (IS_XFERIN(transfer)) transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); else transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); switch (transferRes) { case TransferSuccess: wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; break; case TransferSuccessAsync: break; case TransferFailure: usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0)); usbi_free_fd(&wfd); free(transfer_priv->IsochronousPacketsArray); free(transfer_priv->IsochronousResultsArray); return LIBUSB_ERROR_IO; } transfer_priv->pollable_fd = wfd; usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, IS_XFERIN(transfer) ? POLLIN : POLLOUT); return LIBUSB_SUCCESS; }