2 * Windows CE backend for libusb 1.0
3 * Copyright © 2011-2013 RealVNC Ltd.
4 * Large portions taken from Windows backend, which is
5 * Copyright © 2009-2010 Pete Batard <pbatard@gmail.com>
6 * With contributions from Michael Plante, Orin Eman et al.
7 * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
8 * Major code testing contribution by Xiaofan Chen
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
31 #include "wince_usb.h"
34 int windows_version = WINDOWS_CE;
35 static uint64_t hires_frequency, hires_ticks_to_ps;
36 static HANDLE driver_handle = INVALID_HANDLE_VALUE;
37 static int concurrent_usage = -1;
40 * Converts a windows error to human readable string
41 * uses retval as errorcode, or, if 0, use GetLastError()
43 #if defined(ENABLE_LOGGING)
44 static const char *windows_error_str(DWORD retval)
46 static TCHAR wErr_string[ERR_BUFFER_SIZE];
47 static char err_string[ERR_BUFFER_SIZE];
49 DWORD error_code, format_error;
53 error_code = retval ? retval : GetLastError();
55 safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("[%u] "), (unsigned int)error_code);
57 size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
58 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &wErr_string[safe_tcslen(wErr_string)],
59 ERR_BUFFER_SIZE - (DWORD)safe_tcslen(wErr_string), NULL);
61 format_error = GetLastError();
63 safe_stprintf(wErr_string, ERR_BUFFER_SIZE,
64 _T("Windows error code %u (FormatMessage error code %u)"),
65 (unsigned int)error_code, (unsigned int)format_error);
67 safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("Unknown error code %u"), (unsigned int)error_code);
69 // Remove CR/LF terminators
70 for (i = safe_tcslen(wErr_string) - 1; ((wErr_string[i] == 0x0A) || (wErr_string[i] == 0x0D)); i--)
74 if (WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, err_string, ERR_BUFFER_SIZE, NULL, NULL) < 0)
75 strcpy(err_string, "Unable to convert error string");
81 static struct wince_device_priv *_device_priv(struct libusb_device *dev)
83 return (struct wince_device_priv *)dev->os_priv;
86 // ceusbkwrapper to libusb error code mapping
87 static int translate_driver_error(DWORD error)
90 case ERROR_INVALID_PARAMETER:
91 return LIBUSB_ERROR_INVALID_PARAM;
92 case ERROR_CALL_NOT_IMPLEMENTED:
93 case ERROR_NOT_SUPPORTED:
94 return LIBUSB_ERROR_NOT_SUPPORTED;
95 case ERROR_NOT_ENOUGH_MEMORY:
96 return LIBUSB_ERROR_NO_MEM;
97 case ERROR_INVALID_HANDLE:
98 return LIBUSB_ERROR_NO_DEVICE;
100 return LIBUSB_ERROR_BUSY;
102 // Error codes that are either unexpected, or have
103 // no suitable LIBUSB_ERROR equivalent.
104 case ERROR_CANCELLED:
105 case ERROR_INTERNAL_ERROR:
107 return LIBUSB_ERROR_OTHER;
111 static int init_dllimports(void)
113 DLL_GET_HANDLE(ceusbkwrapper);
114 DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE);
115 DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceList, TRUE);
116 DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseDeviceList, TRUE);
117 DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceAddress, TRUE);
118 DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceDescriptor, TRUE);
119 DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfigDescriptor, TRUE);
120 DLL_LOAD_FUNC(ceusbkwrapper, UkwCloseDriver, TRUE);
121 DLL_LOAD_FUNC(ceusbkwrapper, UkwCancelTransfer, TRUE);
122 DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueControlTransfer, TRUE);
123 DLL_LOAD_FUNC(ceusbkwrapper, UkwClaimInterface, TRUE);
124 DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseInterface, TRUE);
125 DLL_LOAD_FUNC(ceusbkwrapper, UkwSetInterfaceAlternateSetting, TRUE);
126 DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltHost, TRUE);
127 DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltDevice, TRUE);
128 DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfig, TRUE);
129 DLL_LOAD_FUNC(ceusbkwrapper, UkwSetConfig, TRUE);
130 DLL_LOAD_FUNC(ceusbkwrapper, UkwResetDevice, TRUE);
131 DLL_LOAD_FUNC(ceusbkwrapper, UkwKernelDriverActive, TRUE);
132 DLL_LOAD_FUNC(ceusbkwrapper, UkwAttachKernelDriver, TRUE);
133 DLL_LOAD_FUNC(ceusbkwrapper, UkwDetachKernelDriver, TRUE);
134 DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE);
135 DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE);
137 return LIBUSB_SUCCESS;
140 static void exit_dllimports(void)
142 DLL_FREE_HANDLE(ceusbkwrapper);
145 static int init_device(
146 struct libusb_device *dev, UKW_DEVICE drv_dev,
147 unsigned char bus_addr, unsigned char dev_addr)
149 struct wince_device_priv *priv = _device_priv(dev);
150 int r = LIBUSB_SUCCESS;
152 dev->bus_number = bus_addr;
153 dev->device_address = dev_addr;
156 if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc)))
157 r = translate_driver_error(GetLastError());
162 // Internal API functions
163 static int wince_init(struct libusb_context *ctx)
165 int r = LIBUSB_ERROR_OTHER;
167 LARGE_INTEGER li_frequency;
168 TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
170 _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
171 semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
172 if (semaphore == NULL) {
173 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
174 return LIBUSB_ERROR_NO_MEM;
177 // A successful wait brings our semaphore count to 0 (unsignaled)
178 // => any concurent wait stalls until the semaphore's release
179 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
180 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
181 CloseHandle(semaphore);
182 return LIBUSB_ERROR_NO_MEM;
185 // NB: concurrent usage supposes that init calls are equally balanced with
186 // exit calls. If init is called more than exit, we will not exit properly
187 if ( ++concurrent_usage == 0 ) { // First init?
188 // Initialize pollable file descriptors
192 if (init_dllimports() != LIBUSB_SUCCESS) {
193 usbi_err(ctx, "could not resolve DLL functions");
194 r = LIBUSB_ERROR_NOT_SUPPORTED;
198 // try to open a handle to the driver
199 driver_handle = UkwOpenDriver();
200 if (driver_handle == INVALID_HANDLE_VALUE) {
201 usbi_err(ctx, "could not connect to driver");
202 r = LIBUSB_ERROR_NOT_SUPPORTED;
206 // find out if we have access to a monotonic (hires) timer
207 if (QueryPerformanceFrequency(&li_frequency)) {
208 hires_frequency = li_frequency.QuadPart;
209 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
210 // to picoseconds to compute the tv_nsecs part in clock_gettime
211 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
212 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
214 usbi_dbg("no hires timer available on this platform");
216 hires_ticks_to_ps = UINT64_C(0);
219 // At this stage, either we went through full init successfully, or didn't need to
222 init_exit: // Holds semaphore here.
223 if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
227 if (driver_handle != INVALID_HANDLE_VALUE) {
228 UkwCloseDriver(driver_handle);
229 driver_handle = INVALID_HANDLE_VALUE;
233 if (r != LIBUSB_SUCCESS)
234 --concurrent_usage; // Not expected to call libusb_exit if we failed.
236 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
237 CloseHandle(semaphore);
241 static void wince_exit(void)
244 TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
246 _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
247 semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
248 if (semaphore == NULL)
251 // A successful wait brings our semaphore count to 0 (unsignaled)
252 // => any concurent wait stalls until the semaphore release
253 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
254 CloseHandle(semaphore);
258 // Only works if exits and inits are balanced exactly
259 if (--concurrent_usage < 0) { // Last exit
263 if (driver_handle != INVALID_HANDLE_VALUE) {
264 UkwCloseDriver(driver_handle);
265 driver_handle = INVALID_HANDLE_VALUE;
269 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
270 CloseHandle(semaphore);
273 static int wince_get_device_list(
274 struct libusb_context *ctx,
275 struct discovered_devs **discdevs)
277 UKW_DEVICE devices[MAX_DEVICE_COUNT];
278 struct discovered_devs *new_devices = *discdevs;
280 struct libusb_device *dev = NULL;
281 unsigned char bus_addr, dev_addr;
282 unsigned long session_id;
284 DWORD release_list_offset = 0;
285 int r = LIBUSB_SUCCESS;
287 success = UkwGetDeviceList(driver_handle, devices, MAX_DEVICE_COUNT, &count);
289 int libusbErr = translate_driver_error(GetLastError());
290 usbi_err(ctx, "could not get devices: %s", windows_error_str(0));
294 for (i = 0; i < count; ++i) {
295 release_list_offset = i;
296 success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id);
298 r = translate_driver_error(GetLastError());
299 usbi_err(ctx, "could not get device address for %u: %s", (unsigned int)i, windows_error_str(0));
303 dev = usbi_get_device_by_session_id(ctx, session_id);
305 usbi_dbg("using existing device for %u/%u (session %lu)",
306 bus_addr, dev_addr, session_id);
307 // Release just this element in the device list (as we already hold a
309 UkwReleaseDeviceList(driver_handle, &devices[i], 1);
310 release_list_offset++;
312 usbi_dbg("allocating new device for %u/%u (session %lu)",
313 bus_addr, dev_addr, session_id);
314 dev = usbi_alloc_device(ctx, session_id);
316 r = LIBUSB_ERROR_NO_MEM;
320 r = init_device(dev, devices[i], bus_addr, dev_addr);
324 r = usbi_sanitize_device(dev);
329 new_devices = discovered_devs_append(new_devices, dev);
331 r = LIBUSB_ERROR_NO_MEM;
335 safe_unref_device(dev);
338 *discdevs = new_devices;
341 *discdevs = new_devices;
342 safe_unref_device(dev);
343 // Release the remainder of the unprocessed device list.
344 // The devices added to new_devices already will still be passed up to libusb,
345 // which can dispose of them at its leisure.
346 UkwReleaseDeviceList(driver_handle, &devices[release_list_offset], count - release_list_offset);
350 static int wince_open(struct libusb_device_handle *handle)
352 // Nothing to do to open devices as a handle to it has
353 // been retrieved by wince_get_device_list
354 return LIBUSB_SUCCESS;
357 static void wince_close(struct libusb_device_handle *handle)
359 // Nothing to do as wince_open does nothing.
362 static int wince_get_device_descriptor(
363 struct libusb_device *device,
364 unsigned char *buffer, int *host_endian)
366 struct wince_device_priv *priv = _device_priv(device);
369 memcpy(buffer, &priv->desc, DEVICE_DESC_LENGTH);
370 return LIBUSB_SUCCESS;
373 static int wince_get_active_config_descriptor(
374 struct libusb_device *device,
375 unsigned char *buffer, size_t len, int *host_endian)
377 struct wince_device_priv *priv = _device_priv(device);
378 DWORD actualSize = len;
381 if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize))
382 return translate_driver_error(GetLastError());
387 static int wince_get_config_descriptor(
388 struct libusb_device *device,
389 uint8_t config_index,
390 unsigned char *buffer, size_t len, int *host_endian)
392 struct wince_device_priv *priv = _device_priv(device);
393 DWORD actualSize = len;
396 if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize))
397 return translate_driver_error(GetLastError());
402 static int wince_get_configuration(
403 struct libusb_device_handle *handle,
406 struct wince_device_priv *priv = _device_priv(handle->dev);
409 if (!UkwGetConfig(priv->dev, &cv))
410 return translate_driver_error(GetLastError());
413 return LIBUSB_SUCCESS;
416 static int wince_set_configuration(
417 struct libusb_device_handle *handle,
420 struct wince_device_priv *priv = _device_priv(handle->dev);
421 // Setting configuration 0 places the device in Address state.
422 // This should correspond to the "unconfigured state" required by
423 // libusb when the specified configuration is -1.
424 UCHAR cv = (config < 0) ? 0 : config;
425 if (!UkwSetConfig(priv->dev, cv))
426 return translate_driver_error(GetLastError());
428 return LIBUSB_SUCCESS;
431 static int wince_claim_interface(
432 struct libusb_device_handle *handle,
433 int interface_number)
435 struct wince_device_priv *priv = _device_priv(handle->dev);
437 if (!UkwClaimInterface(priv->dev, interface_number))
438 return translate_driver_error(GetLastError());
440 return LIBUSB_SUCCESS;
443 static int wince_release_interface(
444 struct libusb_device_handle *handle,
445 int interface_number)
447 struct wince_device_priv *priv = _device_priv(handle->dev);
449 if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0))
450 return translate_driver_error(GetLastError());
452 if (!UkwReleaseInterface(priv->dev, interface_number))
453 return translate_driver_error(GetLastError());
455 return LIBUSB_SUCCESS;
458 static int wince_set_interface_altsetting(
459 struct libusb_device_handle *handle,
460 int interface_number, int altsetting)
462 struct wince_device_priv *priv = _device_priv(handle->dev);
464 if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting))
465 return translate_driver_error(GetLastError());
467 return LIBUSB_SUCCESS;
470 static int wince_clear_halt(
471 struct libusb_device_handle *handle,
472 unsigned char endpoint)
474 struct wince_device_priv *priv = _device_priv(handle->dev);
476 if (!UkwClearHaltHost(priv->dev, endpoint))
477 return translate_driver_error(GetLastError());
479 if (!UkwClearHaltDevice(priv->dev, endpoint))
480 return translate_driver_error(GetLastError());
482 return LIBUSB_SUCCESS;
485 static int wince_reset_device(
486 struct libusb_device_handle *handle)
488 struct wince_device_priv *priv = _device_priv(handle->dev);
490 if (!UkwResetDevice(priv->dev))
491 return translate_driver_error(GetLastError());
493 return LIBUSB_SUCCESS;
496 static int wince_kernel_driver_active(
497 struct libusb_device_handle *handle,
498 int interface_number)
500 struct wince_device_priv *priv = _device_priv(handle->dev);
503 if (!UkwKernelDriverActive(priv->dev, interface_number, &result))
504 return translate_driver_error(GetLastError());
506 return result ? 1 : 0;
509 static int wince_detach_kernel_driver(
510 struct libusb_device_handle *handle,
511 int interface_number)
513 struct wince_device_priv *priv = _device_priv(handle->dev);
515 if (!UkwDetachKernelDriver(priv->dev, interface_number))
516 return translate_driver_error(GetLastError());
518 return LIBUSB_SUCCESS;
521 static int wince_attach_kernel_driver(
522 struct libusb_device_handle *handle,
523 int interface_number)
525 struct wince_device_priv *priv = _device_priv(handle->dev);
527 if (!UkwAttachKernelDriver(priv->dev, interface_number))
528 return translate_driver_error(GetLastError());
530 return LIBUSB_SUCCESS;
533 static void wince_destroy_device(struct libusb_device *dev)
535 struct wince_device_priv *priv = _device_priv(dev);
537 UkwReleaseDeviceList(driver_handle, &priv->dev, 1);
540 static void wince_clear_transfer_priv(struct usbi_transfer *itransfer)
542 struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
543 struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd);
545 // No need to cancel transfer as it is either complete or abandoned
546 wfd.itransfer = NULL;
547 CloseHandle(wfd.handle);
548 usbi_free_fd(&transfer_priv->pollable_fd);
551 static int wince_cancel_transfer(struct usbi_transfer *itransfer)
553 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
554 struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
555 struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
557 if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT))
558 return translate_driver_error(GetLastError());
560 return LIBUSB_SUCCESS;
563 static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer)
565 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
566 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
567 struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
568 struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
569 BOOL direction_in, ret;
573 PUKW_CONTROL_HEADER setup = NULL;
574 const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL;
576 transfer_priv->pollable_fd = INVALID_WINFD;
577 if (control_transfer) {
578 setup = (PUKW_CONTROL_HEADER) transfer->buffer;
579 direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN;
581 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
583 flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER;
584 flags |= UKW_TF_SHORT_TRANSFER_OK;
586 eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
587 if (eventHandle == NULL) {
588 usbi_err(ctx, "Failed to create event for async transfer");
589 return LIBUSB_ERROR_NO_MEM;
592 wfd = usbi_create_fd(eventHandle, direction_in ? RW_READ : RW_WRITE, itransfer, &wince_cancel_transfer);
594 CloseHandle(eventHandle);
595 return LIBUSB_ERROR_NO_MEM;
598 transfer_priv->pollable_fd = wfd;
599 if (control_transfer) {
600 // Split out control setup header and data buffer
601 DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER);
602 PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)];
604 ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped);
606 ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer,
607 transfer->length, &transfer->actual_length, wfd.overlapped);
611 int libusbErr = translate_driver_error(GetLastError());
612 usbi_err(ctx, "UkwIssue%sTransfer failed: error %u",
613 control_transfer ? "Control" : "Bulk", (unsigned int)GetLastError());
614 wince_clear_transfer_priv(itransfer);
617 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT);
619 return LIBUSB_SUCCESS;
622 static int wince_submit_iso_transfer(struct usbi_transfer *itransfer)
624 return LIBUSB_ERROR_NOT_SUPPORTED;
627 static int wince_submit_transfer(struct usbi_transfer *itransfer)
629 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
631 switch (transfer->type) {
632 case LIBUSB_TRANSFER_TYPE_CONTROL:
633 case LIBUSB_TRANSFER_TYPE_BULK:
634 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
635 return wince_submit_control_or_bulk_transfer(itransfer);
636 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
637 return wince_submit_iso_transfer(itransfer);
638 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
639 return LIBUSB_ERROR_NOT_SUPPORTED;
641 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
642 return LIBUSB_ERROR_INVALID_PARAM;
646 static void wince_transfer_callback(
647 struct usbi_transfer *itransfer,
648 uint32_t io_result, uint32_t io_size)
650 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
651 struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
652 struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
655 usbi_dbg("handling I/O completion with errcode %u", io_result);
657 if (io_result == ERROR_NOT_SUPPORTED &&
658 transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) {
659 /* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper
660 * Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the
661 * endpoint isn't actually stalled.
663 * One example of this is that some devices will occasionally fail to reply to an IN
664 * token. The WinCE USB layer carries on with the transaction until it is completed
665 * (or cancelled) but then completes it with USB_ERROR_STALL.
667 * This code therefore needs to confirm that there really is a stall error, by both
668 * checking the pipe status and requesting the endpoint status from the device.
671 usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall");
672 if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) {
673 /* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS
674 * control request to the device. This is done synchronously, which is a bit
675 * naughty, but this is a special corner case.
679 UKW_CONTROL_HEADER ctrlHeader;
680 ctrlHeader.bmRequestType = LIBUSB_REQUEST_TYPE_STANDARD |
681 LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_ENDPOINT;
682 ctrlHeader.bRequest = LIBUSB_REQUEST_GET_STATUS;
683 ctrlHeader.wValue = 0;
684 ctrlHeader.wIndex = transfer->endpoint;
685 ctrlHeader.wLength = sizeof(wStatus);
686 if (UkwIssueControlTransfer(priv->dev,
687 UKW_TF_IN_TRANSFER | UKW_TF_SEND_TO_ENDPOINT,
688 &ctrlHeader, &wStatus, sizeof(wStatus), &written, NULL)) {
689 if (written == sizeof(wStatus) &&
690 (wStatus & STATUS_HALT_FLAG) == 0) {
691 if (!halted || UkwClearHaltHost(priv->dev, transfer->endpoint)) {
692 usbi_dbg("Endpoint doesn't appear to be stalled, overriding error with success");
693 io_result = ERROR_SUCCESS;
695 usbi_dbg("Endpoint doesn't appear to be stalled, but the host is halted, changing error");
696 io_result = ERROR_IO_DEVICE;
705 itransfer->transferred += io_size;
706 status = LIBUSB_TRANSFER_COMPLETED;
708 case ERROR_CANCELLED:
709 usbi_dbg("detected transfer cancel");
710 status = LIBUSB_TRANSFER_CANCELLED;
712 case ERROR_NOT_SUPPORTED:
713 case ERROR_GEN_FAILURE:
714 usbi_dbg("detected endpoint stall");
715 status = LIBUSB_TRANSFER_STALL;
717 case ERROR_SEM_TIMEOUT:
718 usbi_dbg("detected semaphore timeout");
719 status = LIBUSB_TRANSFER_TIMED_OUT;
721 case ERROR_OPERATION_ABORTED:
722 usbi_dbg("detected operation aborted");
723 status = LIBUSB_TRANSFER_CANCELLED;
726 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result));
727 status = LIBUSB_TRANSFER_ERROR;
731 wince_clear_transfer_priv(itransfer);
732 if (status == LIBUSB_TRANSFER_CANCELLED)
733 usbi_handle_transfer_cancellation(itransfer);
735 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
738 static void wince_handle_callback(
739 struct usbi_transfer *itransfer,
740 uint32_t io_result, uint32_t io_size)
742 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
744 switch (transfer->type) {
745 case LIBUSB_TRANSFER_TYPE_CONTROL:
746 case LIBUSB_TRANSFER_TYPE_BULK:
747 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
748 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
749 wince_transfer_callback (itransfer, io_result, io_size);
751 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
754 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
758 static int wince_handle_events(
759 struct libusb_context *ctx,
760 struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
762 struct wince_transfer_priv* transfer_priv = NULL;
763 POLL_NFDS_TYPE i = 0;
765 struct usbi_transfer *transfer;
766 DWORD io_size, io_result;
767 int r = LIBUSB_SUCCESS;
769 usbi_mutex_lock(&ctx->open_devs_lock);
770 for (i = 0; i < nfds && num_ready > 0; i++) {
772 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
779 // Because a Windows OVERLAPPED is used for poll emulation,
780 // a pollable fd is created and stored with each transfer
781 usbi_mutex_lock(&ctx->flying_transfers_lock);
782 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
783 transfer_priv = usbi_transfer_get_os_priv(transfer);
784 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
789 usbi_mutex_unlock(&ctx->flying_transfers_lock);
791 if (found && HasOverlappedIoCompleted(transfer_priv->pollable_fd.overlapped)) {
792 io_result = (DWORD)transfer_priv->pollable_fd.overlapped->Internal;
793 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
794 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
795 // let handle_callback free the event using the transfer wfd
796 // If you don't use the transfer wfd, you run a risk of trying to free a
797 // newly allocated wfd that took the place of the one from the transfer.
798 wince_handle_callback(transfer, io_result, io_size);
800 usbi_err(ctx, "matching transfer for fd %d has not completed", fds[i]);
801 r = LIBUSB_ERROR_OTHER;
804 usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
805 r = LIBUSB_ERROR_NOT_FOUND;
809 usbi_mutex_unlock(&ctx->open_devs_lock);
815 * Monotonic and real time functions
817 static int wince_clock_gettime(int clk_id, struct timespec *tp)
819 LARGE_INTEGER hires_counter;
820 ULARGE_INTEGER rtime;
825 case USBI_CLOCK_MONOTONIC:
826 if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) {
827 tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
828 tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
829 return LIBUSB_SUCCESS;
831 // Fall through and return real-time if monotonic read failed or was not detected @ init
832 case USBI_CLOCK_REALTIME:
833 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
834 // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
835 // Note however that our resolution is bounded by the Windows system time
836 // functions and is at best of the order of 1 ms (or, usually, worse)
838 SystemTimeToFileTime(&st, &filetime);
839 rtime.LowPart = filetime.dwLowDateTime;
840 rtime.HighPart = filetime.dwHighDateTime;
841 rtime.QuadPart -= EPOCH_TIME;
842 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
843 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
844 return LIBUSB_SUCCESS;
846 return LIBUSB_ERROR_INVALID_PARAM;
850 const struct usbi_os_backend wince_backend = {
856 wince_get_device_list,
857 NULL, /* hotplug_poll */
861 wince_get_device_descriptor,
862 wince_get_active_config_descriptor,
863 wince_get_config_descriptor,
864 NULL, /* get_config_descriptor_by_value() */
866 wince_get_configuration,
867 wince_set_configuration,
868 wince_claim_interface,
869 wince_release_interface,
871 wince_set_interface_altsetting,
875 NULL, /* alloc_streams */
876 NULL, /* free_streams */
878 NULL, /* dev_mem_alloc() */
879 NULL, /* dev_mem_free() */
881 wince_kernel_driver_active,
882 wince_detach_kernel_driver,
883 wince_attach_kernel_driver,
885 wince_destroy_device,
887 wince_submit_transfer,
888 wince_cancel_transfer,
889 wince_clear_transfer_priv,
892 NULL, /* handle_transfer_completion() */
895 sizeof(struct wince_device_priv),
897 sizeof(struct wince_transfer_priv),