static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
	struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
	struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
	BOOL direction_in, ret;
	struct winfd wfd;
	DWORD flags;
	HANDLE eventHandle;
	PUKW_CONTROL_HEADER setup = NULL;
	const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL;

	transfer_priv->pollable_fd = INVALID_WINFD;
	if (control_transfer) {
		setup = (PUKW_CONTROL_HEADER) transfer->buffer;
		direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN;
	} else {
		direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
	}
	flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER;
	flags |= UKW_TF_SHORT_TRANSFER_OK;

	eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (eventHandle == NULL) {
		usbi_err(ctx, "Failed to create event for async transfer");
		return LIBUSB_ERROR_NO_MEM;
	}

	wfd = usbi_create_fd(eventHandle, direction_in ? RW_READ : RW_WRITE, itransfer, &wince_cancel_transfer);
	if (wfd.fd < 0) {
		CloseHandle(eventHandle);
		return LIBUSB_ERROR_NO_MEM;
	}

	transfer_priv->pollable_fd = wfd;
	if (control_transfer) {
		// Split out control setup header and data buffer
		DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER);
		PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)];

		ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped);
	} else {
		ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer, 
			transfer->length, &transfer->actual_length, wfd.overlapped);
	}
	if (!ret) {
		int libusbErr = translate_driver_error(GetLastError());
		usbi_err(ctx, "UkwIssue%sTransfer failed: error %d",
			control_transfer ? "Control" : "Bulk", GetLastError());
		wince_clear_transfer_priv(itransfer);
		return libusbErr;
	}
	usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT);
	itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;

	return LIBUSB_SUCCESS;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
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;
}