libusbx 1.0.18 *FINAL RELEASE*
[libusbx.git] / libusb / os / wince_usb.c
blobc7ab7f6b2fa50d2117dd1a01908df6b0c2b3f1c4
1 /*
2 * Windows CE backend for libusbx 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
25 #include <libusbi.h>
27 #include <stdint.h>
28 #include <errno.h>
29 #include <inttypes.h>
31 #include "wince_usb.h"
33 // Forward declares
34 static int wince_clock_gettime(int clk_id, struct timespec *tp);
35 unsigned __stdcall wince_clock_gettime_threaded(void* param);
37 // Global variables
38 uint64_t hires_frequency, hires_ticks_to_ps;
39 int errno;
40 const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
41 enum windows_version windows_version = WINDOWS_CE;
42 static int concurrent_usage = -1;
43 // Timer thread
44 // NB: index 0 is for monotonic and 1 is for the thread exit event
45 HANDLE timer_thread = NULL;
46 HANDLE timer_mutex = NULL;
47 struct timespec timer_tp;
48 volatile LONG request_count[2] = {0, 1}; // last one must be > 0
49 HANDLE timer_request[2] = { NULL, NULL };
50 HANDLE timer_response = NULL;
51 HANDLE driver_handle = INVALID_HANDLE_VALUE;
54 * Converts a windows error to human readable string
55 * uses retval as errorcode, or, if 0, use GetLastError()
57 #if defined(ENABLE_LOGGING)
58 static char* windows_error_str(uint32_t retval)
60 static TCHAR wErr_string[ERR_BUFFER_SIZE];
61 static char err_string[ERR_BUFFER_SIZE];
63 DWORD size;
64 size_t i;
65 uint32_t error_code, format_error;
67 error_code = retval?retval:GetLastError();
69 safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("[%d] "), error_code);
71 size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
72 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &wErr_string[safe_tcslen(wErr_string)],
73 ERR_BUFFER_SIZE - (DWORD)safe_tcslen(wErr_string), NULL);
74 if (size == 0) {
75 format_error = GetLastError();
76 if (format_error)
77 safe_stprintf(wErr_string, ERR_BUFFER_SIZE,
78 _T("Windows error code %u (FormatMessage error code %u)"), error_code, format_error);
79 else
80 safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("Unknown error code %u"), error_code);
81 } else {
82 // Remove CR/LF terminators
83 for (i=safe_tcslen(wErr_string)-1; ((wErr_string[i]==0x0A) || (wErr_string[i]==0x0D)); i--) {
84 wErr_string[i] = 0;
87 if (WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, err_string, ERR_BUFFER_SIZE, NULL, NULL) < 0)
89 strcpy(err_string, "Unable to convert error string");
91 return err_string;
93 #endif
95 static struct wince_device_priv *_device_priv(struct libusb_device *dev)
97 return (struct wince_device_priv *) dev->os_priv;
100 // ceusbkwrapper to libusb error code mapping
101 static int translate_driver_error(int error)
103 switch (error) {
104 case ERROR_INVALID_PARAMETER:
105 return LIBUSB_ERROR_INVALID_PARAM;
106 case ERROR_CALL_NOT_IMPLEMENTED:
107 case ERROR_NOT_SUPPORTED:
108 return LIBUSB_ERROR_NOT_SUPPORTED;
109 case ERROR_NOT_ENOUGH_MEMORY:
110 return LIBUSB_ERROR_NO_MEM;
111 case ERROR_INVALID_HANDLE:
112 return LIBUSB_ERROR_NO_DEVICE;
113 case ERROR_BUSY:
114 return LIBUSB_ERROR_BUSY;
116 // Error codes that are either unexpected, or have
117 // no suitable LIBUSB_ERROR equivilant.
118 case ERROR_CANCELLED:
119 case ERROR_INTERNAL_ERROR:
120 default:
121 return LIBUSB_ERROR_OTHER;
125 static int init_dllimports()
127 DLL_LOAD(ceusbkwrapper.dll, UkwOpenDriver, TRUE);
128 DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceList, TRUE);
129 DLL_LOAD(ceusbkwrapper.dll, UkwReleaseDeviceList, TRUE);
130 DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceAddress, TRUE);
131 DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceDescriptor, TRUE);
132 DLL_LOAD(ceusbkwrapper.dll, UkwGetConfigDescriptor, TRUE);
133 DLL_LOAD(ceusbkwrapper.dll, UkwCloseDriver, TRUE);
134 DLL_LOAD(ceusbkwrapper.dll, UkwCancelTransfer, TRUE);
135 DLL_LOAD(ceusbkwrapper.dll, UkwIssueControlTransfer, TRUE);
136 DLL_LOAD(ceusbkwrapper.dll, UkwClaimInterface, TRUE);
137 DLL_LOAD(ceusbkwrapper.dll, UkwReleaseInterface, TRUE);
138 DLL_LOAD(ceusbkwrapper.dll, UkwSetInterfaceAlternateSetting, TRUE);
139 DLL_LOAD(ceusbkwrapper.dll, UkwClearHaltHost, TRUE);
140 DLL_LOAD(ceusbkwrapper.dll, UkwClearHaltDevice, TRUE);
141 DLL_LOAD(ceusbkwrapper.dll, UkwGetConfig, TRUE);
142 DLL_LOAD(ceusbkwrapper.dll, UkwSetConfig, TRUE);
143 DLL_LOAD(ceusbkwrapper.dll, UkwResetDevice, TRUE);
144 DLL_LOAD(ceusbkwrapper.dll, UkwKernelDriverActive, TRUE);
145 DLL_LOAD(ceusbkwrapper.dll, UkwAttachKernelDriver, TRUE);
146 DLL_LOAD(ceusbkwrapper.dll, UkwDetachKernelDriver, TRUE);
147 DLL_LOAD(ceusbkwrapper.dll, UkwIssueBulkTransfer, TRUE);
148 DLL_LOAD(ceusbkwrapper.dll, UkwIsPipeHalted, TRUE);
149 return LIBUSB_SUCCESS;
152 static int init_device(struct libusb_device *dev, UKW_DEVICE drv_dev,
153 unsigned char bus_addr, unsigned char dev_addr)
155 struct wince_device_priv *priv = _device_priv(dev);
156 int r = LIBUSB_SUCCESS;
158 dev->bus_number = bus_addr;
159 dev->device_address = dev_addr;
160 priv->dev = drv_dev;
162 if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc))) {
163 r = translate_driver_error(GetLastError());
165 return r;
168 // Internal API functions
169 static int wince_init(struct libusb_context *ctx)
171 int i, r = LIBUSB_ERROR_OTHER;
172 HANDLE semaphore;
173 TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
175 _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
176 semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
177 if (semaphore == NULL) {
178 usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
179 return LIBUSB_ERROR_NO_MEM;
182 // A successful wait brings our semaphore count to 0 (unsignaled)
183 // => any concurent wait stalls until the semaphore's release
184 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
185 usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
186 CloseHandle(semaphore);
187 return LIBUSB_ERROR_NO_MEM;
190 // NB: concurrent usage supposes that init calls are equally balanced with
191 // exit calls. If init is called more than exit, we will not exit properly
192 if ( ++concurrent_usage == 0 ) { // First init?
193 // Initialize pollable file descriptors
194 init_polling();
196 // Load DLL imports
197 if (init_dllimports() != LIBUSB_SUCCESS) {
198 usbi_err(ctx, "could not resolve DLL functions");
199 r = LIBUSB_ERROR_NOT_SUPPORTED;
200 goto init_exit;
203 // try to open a handle to the driver
204 driver_handle = UkwOpenDriver();
205 if (driver_handle == INVALID_HANDLE_VALUE) {
206 usbi_err(ctx, "could not connect to driver");
207 r = LIBUSB_ERROR_NOT_SUPPORTED;
208 goto init_exit;
211 // Windows CE doesn't have a way of specifying thread affinity, so this code
212 // just has to hope QueryPerformanceCounter doesn't report different values when
213 // running on different cores.
214 r = LIBUSB_ERROR_NO_MEM;
215 for (i = 0; i < 2; i++) {
216 timer_request[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
217 if (timer_request[i] == NULL) {
218 usbi_err(ctx, "could not create timer request event %d - aborting", i);
219 goto init_exit;
222 timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
223 if (timer_response == NULL) {
224 usbi_err(ctx, "could not create timer response semaphore - aborting");
225 goto init_exit;
227 timer_mutex = CreateMutex(NULL, FALSE, NULL);
228 if (timer_mutex == NULL) {
229 usbi_err(ctx, "could not create timer mutex - aborting");
230 goto init_exit;
232 timer_thread = CreateThread(NULL, 0, wince_clock_gettime_threaded, NULL, 0, NULL);
233 if (timer_thread == NULL) {
234 usbi_err(ctx, "Unable to create timer thread - aborting");
235 goto init_exit;
238 // Wait for timer thread to init before continuing.
239 if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) {
240 usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting");
241 goto init_exit;
244 // At this stage, either we went through full init successfully, or didn't need to
245 r = LIBUSB_SUCCESS;
247 init_exit: // Holds semaphore here.
248 if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
249 if (driver_handle != INVALID_HANDLE_VALUE) {
250 UkwCloseDriver(driver_handle);
251 driver_handle = INVALID_HANDLE_VALUE;
253 if (timer_thread) {
254 SetEvent(timer_request[1]); // actually the signal to quit the thread.
255 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
256 usbi_warn(ctx, "could not wait for timer thread to quit");
257 TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
258 // all objects it might have held anyway.
260 CloseHandle(timer_thread);
261 timer_thread = NULL;
263 for (i = 0; i < 2; i++) {
264 if (timer_request[i]) {
265 CloseHandle(timer_request[i]);
266 timer_request[i] = NULL;
269 if (timer_response) {
270 CloseHandle(timer_response);
271 timer_response = NULL;
273 if (timer_mutex) {
274 CloseHandle(timer_mutex);
275 timer_mutex = NULL;
279 if (r != LIBUSB_SUCCESS)
280 --concurrent_usage; // Not expected to call libusb_exit if we failed.
282 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
283 CloseHandle(semaphore);
284 return r;
287 static void wince_exit(void)
289 int i;
290 HANDLE semaphore;
291 TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
293 _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
294 semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
295 if (semaphore == NULL) {
296 return;
299 // A successful wait brings our semaphore count to 0 (unsignaled)
300 // => any concurent wait stalls until the semaphore release
301 if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
302 CloseHandle(semaphore);
303 return;
306 // Only works if exits and inits are balanced exactly
307 if (--concurrent_usage < 0) { // Last exit
308 exit_polling();
310 if (timer_thread) {
311 SetEvent(timer_request[1]); // actually the signal to quit the thread.
312 if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
313 usbi_dbg("could not wait for timer thread to quit");
314 TerminateThread(timer_thread, 1);
316 CloseHandle(timer_thread);
317 timer_thread = NULL;
319 for (i = 0; i < 2; i++) {
320 if (timer_request[i]) {
321 CloseHandle(timer_request[i]);
322 timer_request[i] = NULL;
325 if (timer_response) {
326 CloseHandle(timer_response);
327 timer_response = NULL;
329 if (timer_mutex) {
330 CloseHandle(timer_mutex);
331 timer_mutex = NULL;
333 if (driver_handle != INVALID_HANDLE_VALUE) {
334 UkwCloseDriver(driver_handle);
335 driver_handle = INVALID_HANDLE_VALUE;
339 ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
340 CloseHandle(semaphore);
343 static int wince_get_device_list(
344 struct libusb_context *ctx,
345 struct discovered_devs **discdevs)
347 UKW_DEVICE devices[MAX_DEVICE_COUNT];
348 struct discovered_devs * new_devices = *discdevs;
349 DWORD count = 0, i;
350 struct libusb_device *dev = NULL;
351 unsigned char bus_addr, dev_addr;
352 unsigned long session_id;
353 BOOL success;
354 DWORD release_list_offset = 0;
355 int r = LIBUSB_SUCCESS;
357 success = UkwGetDeviceList(driver_handle, devices, MAX_DEVICE_COUNT, &count);
358 if (!success) {
359 int libusbErr = translate_driver_error(GetLastError());
360 usbi_err(ctx, "could not get devices: %s", windows_error_str(0));
361 return libusbErr;
363 for(i = 0; i < count; ++i) {
364 release_list_offset = i;
365 success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id);
366 if (!success) {
367 r = translate_driver_error(GetLastError());
368 usbi_err(ctx, "could not get device address for %d: %s", i, windows_error_str(0));
369 goto err_out;
371 dev = usbi_get_device_by_session_id(ctx, session_id);
372 if (dev) {
373 usbi_dbg("using existing device for %d/%d (session %ld)",
374 bus_addr, dev_addr, session_id);
375 // Release just this element in the device list (as we already hold a
376 // reference to it).
377 UkwReleaseDeviceList(driver_handle, &devices[i], 1);
378 release_list_offset++;
379 } else {
380 usbi_dbg("allocating new device for %d/%d (session %ld)",
381 bus_addr, dev_addr, session_id);
382 dev = usbi_alloc_device(ctx, session_id);
383 if (!dev) {
384 r = LIBUSB_ERROR_NO_MEM;
385 goto err_out;
387 r = init_device(dev, devices[i], bus_addr, dev_addr);
388 if (r < 0)
389 goto err_out;
390 r = usbi_sanitize_device(dev);
391 if (r < 0)
392 goto err_out;
394 new_devices = discovered_devs_append(new_devices, dev);
395 if (!discdevs) {
396 r = LIBUSB_ERROR_NO_MEM;
397 goto err_out;
399 safe_unref_device(dev);
401 *discdevs = new_devices;
402 return r;
403 err_out:
404 *discdevs = new_devices;
405 safe_unref_device(dev);
406 // Release the remainder of the unprocessed device list.
407 // The devices added to new_devices already will still be passed up to libusb,
408 // which can dispose of them at its leisure.
409 UkwReleaseDeviceList(driver_handle, &devices[release_list_offset], count - release_list_offset);
410 return r;
413 static int wince_open(struct libusb_device_handle *handle)
415 // Nothing to do to open devices as a handle to it has
416 // been retrieved by wince_get_device_list
417 return LIBUSB_SUCCESS;
420 static void wince_close(struct libusb_device_handle *handle)
422 // Nothing to do as wince_open does nothing.
425 static int wince_get_device_descriptor(
426 struct libusb_device *device,
427 unsigned char *buffer, int *host_endian)
429 struct wince_device_priv *priv = _device_priv(device);
431 *host_endian = 1;
432 memcpy(buffer, &priv->desc, DEVICE_DESC_LENGTH);
433 return LIBUSB_SUCCESS;
436 static int wince_get_active_config_descriptor(
437 struct libusb_device *device,
438 unsigned char *buffer, size_t len, int *host_endian)
440 struct wince_device_priv *priv = _device_priv(device);
441 DWORD actualSize = len;
442 *host_endian = 0;
443 if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize)) {
444 return translate_driver_error(GetLastError());
446 return actualSize;
449 static int wince_get_config_descriptor(
450 struct libusb_device *device,
451 uint8_t config_index,
452 unsigned char *buffer, size_t len, int *host_endian)
454 struct wince_device_priv *priv = _device_priv(device);
455 DWORD actualSize = len;
456 *host_endian = 0;
457 if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize)) {
458 return translate_driver_error(GetLastError());
460 return actualSize;
463 static int wince_get_configuration(
464 struct libusb_device_handle *handle,
465 int *config)
467 struct wince_device_priv *priv = _device_priv(handle->dev);
468 UCHAR cv = 0;
469 if (!UkwGetConfig(priv->dev, &cv)) {
470 return translate_driver_error(GetLastError());
472 (*config) = cv;
473 return LIBUSB_SUCCESS;
476 static int wince_set_configuration(
477 struct libusb_device_handle *handle,
478 int config)
480 struct wince_device_priv *priv = _device_priv(handle->dev);
481 // Setting configuration 0 places the device in Address state.
482 // This should correspond to the "unconfigured state" required by
483 // libusb when the specified configuration is -1.
484 UCHAR cv = (config < 0) ? 0 : config;
485 if (!UkwSetConfig(priv->dev, cv)) {
486 return translate_driver_error(GetLastError());
488 return LIBUSB_SUCCESS;
491 static int wince_claim_interface(
492 struct libusb_device_handle *handle,
493 int interface_number)
495 struct wince_device_priv *priv = _device_priv(handle->dev);
496 if (!UkwClaimInterface(priv->dev, interface_number)) {
497 return translate_driver_error(GetLastError());
499 return LIBUSB_SUCCESS;
502 static int wince_release_interface(
503 struct libusb_device_handle *handle,
504 int interface_number)
506 struct wince_device_priv *priv = _device_priv(handle->dev);
507 if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0)) {
508 return translate_driver_error(GetLastError());
510 if (!UkwReleaseInterface(priv->dev, interface_number)) {
511 return translate_driver_error(GetLastError());
513 return LIBUSB_SUCCESS;
516 static int wince_set_interface_altsetting(
517 struct libusb_device_handle *handle,
518 int interface_number, int altsetting)
520 struct wince_device_priv *priv = _device_priv(handle->dev);
521 if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting)) {
522 return translate_driver_error(GetLastError());
524 return LIBUSB_SUCCESS;
527 static int wince_clear_halt(
528 struct libusb_device_handle *handle,
529 unsigned char endpoint)
531 struct wince_device_priv *priv = _device_priv(handle->dev);
532 if (!UkwClearHaltHost(priv->dev, endpoint)) {
533 return translate_driver_error(GetLastError());
535 if (!UkwClearHaltDevice(priv->dev, endpoint)) {
536 return translate_driver_error(GetLastError());
538 return LIBUSB_SUCCESS;
541 static int wince_reset_device(
542 struct libusb_device_handle *handle)
544 struct wince_device_priv *priv = _device_priv(handle->dev);
545 if (!UkwResetDevice(priv->dev)) {
546 return translate_driver_error(GetLastError());
548 return LIBUSB_SUCCESS;
551 static int wince_kernel_driver_active(
552 struct libusb_device_handle *handle,
553 int interface_number)
555 struct wince_device_priv *priv = _device_priv(handle->dev);
556 BOOL result = FALSE;
557 if (!UkwKernelDriverActive(priv->dev, interface_number, &result)) {
558 return translate_driver_error(GetLastError());
560 return result ? 1 : 0;
563 static int wince_detach_kernel_driver(
564 struct libusb_device_handle *handle,
565 int interface_number)
567 struct wince_device_priv *priv = _device_priv(handle->dev);
568 if (!UkwDetachKernelDriver(priv->dev, interface_number)) {
569 return translate_driver_error(GetLastError());
571 return LIBUSB_SUCCESS;
574 static int wince_attach_kernel_driver(
575 struct libusb_device_handle *handle,
576 int interface_number)
578 struct wince_device_priv *priv = _device_priv(handle->dev);
579 if (!UkwAttachKernelDriver(priv->dev, interface_number)) {
580 return translate_driver_error(GetLastError());
582 return LIBUSB_SUCCESS;
585 static void wince_destroy_device(
586 struct libusb_device *dev)
588 struct wince_device_priv *priv = _device_priv(dev);
589 UkwReleaseDeviceList(driver_handle, &priv->dev, 1);
592 static void wince_clear_transfer_priv(
593 struct usbi_transfer *itransfer)
595 struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
596 struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd);
597 // No need to cancel transfer as it is either complete or abandoned
598 wfd.itransfer = NULL;
599 CloseHandle(wfd.handle);
600 usbi_free_fd(&transfer_priv->pollable_fd);
603 static int wince_cancel_transfer(
604 struct usbi_transfer *itransfer)
606 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
607 struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
608 struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
610 if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT)) {
611 return translate_driver_error(GetLastError());
613 return LIBUSB_SUCCESS;
616 static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer)
618 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
619 struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
620 struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
621 struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
622 BOOL direction_in, ret;
623 struct winfd wfd;
624 DWORD flags;
625 HANDLE eventHandle;
626 PUKW_CONTROL_HEADER setup = NULL;
627 const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL;
629 transfer_priv->pollable_fd = INVALID_WINFD;
630 if (control_transfer) {
631 setup = (PUKW_CONTROL_HEADER) transfer->buffer;
632 direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN;
633 } else {
634 direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
636 flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER;
637 flags |= UKW_TF_SHORT_TRANSFER_OK;
639 eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
640 if (eventHandle == NULL) {
641 usbi_err(ctx, "Failed to create event for async transfer");
642 return LIBUSB_ERROR_NO_MEM;
645 wfd = usbi_create_fd(eventHandle, direction_in ? RW_READ : RW_WRITE, itransfer, &wince_cancel_transfer);
646 if (wfd.fd < 0) {
647 CloseHandle(eventHandle);
648 return LIBUSB_ERROR_NO_MEM;
651 transfer_priv->pollable_fd = wfd;
652 if (control_transfer) {
653 // Split out control setup header and data buffer
654 DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER);
655 PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)];
657 ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped);
658 } else {
659 ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer,
660 transfer->length, &transfer->actual_length, wfd.overlapped);
662 if (!ret) {
663 int libusbErr = translate_driver_error(GetLastError());
664 usbi_err(ctx, "UkwIssue%sTransfer failed: error %d",
665 control_transfer ? "Control" : "Bulk", GetLastError());
666 wince_clear_transfer_priv(itransfer);
667 return libusbErr;
669 usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT);
670 itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
672 return LIBUSB_SUCCESS;
675 static int wince_submit_iso_transfer(struct usbi_transfer *itransfer)
677 return LIBUSB_ERROR_NOT_SUPPORTED;
680 static int wince_submit_transfer(
681 struct usbi_transfer *itransfer)
683 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
685 switch (transfer->type) {
686 case LIBUSB_TRANSFER_TYPE_CONTROL:
687 case LIBUSB_TRANSFER_TYPE_BULK:
688 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
689 return wince_submit_control_or_bulk_transfer(itransfer);
690 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
691 return wince_submit_iso_transfer(itransfer);
692 default:
693 usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
694 return LIBUSB_ERROR_INVALID_PARAM;
698 static void wince_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
700 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
701 struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
702 struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
703 int status;
705 usbi_dbg("handling I/O completion with errcode %d", io_result);
707 if (io_result == ERROR_NOT_SUPPORTED &&
708 transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) {
709 /* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper
710 * Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the
711 * endpoint isn't actually stalled.
713 * One example of this is that some devices will occasionally fail to reply to an IN
714 * token. The WinCE USB layer carries on with the transaction until it is completed
715 * (or cancelled) but then completes it with USB_ERROR_STALL.
717 * This code therefore needs to confirm that there really is a stall error, by both
718 * checking the pipe status and requesting the endpoint status from the device.
720 BOOL halted = FALSE;
721 usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall");
722 if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) {
723 /* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS
724 * control request to the device. This is done synchronously, which is a bit
725 * naughty, but this is a special corner case.
727 WORD wStatus = 0;
728 DWORD written = 0;
729 UKW_CONTROL_HEADER ctrlHeader;
730 ctrlHeader.bmRequestType = LIBUSB_REQUEST_TYPE_STANDARD |
731 LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_ENDPOINT;
732 ctrlHeader.bRequest = LIBUSB_REQUEST_GET_STATUS;
733 ctrlHeader.wValue = 0;
734 ctrlHeader.wIndex = transfer->endpoint;
735 ctrlHeader.wLength = sizeof(wStatus);
736 if (UkwIssueControlTransfer(priv->dev,
737 UKW_TF_IN_TRANSFER | UKW_TF_SEND_TO_ENDPOINT,
738 &ctrlHeader, &wStatus, sizeof(wStatus), &written, NULL)) {
739 if (written == sizeof(wStatus) &&
740 (wStatus & STATUS_HALT_FLAG) == 0) {
741 if (!halted || UkwClearHaltHost(priv->dev, transfer->endpoint)) {
742 usbi_dbg("Endpoint doesn't appear to be stalled, overriding error with success");
743 io_result = ERROR_SUCCESS;
744 } else {
745 usbi_dbg("Endpoint doesn't appear to be stalled, but the host is halted, changing error");
746 io_result = ERROR_IO_DEVICE;
753 switch(io_result) {
754 case ERROR_SUCCESS:
755 itransfer->transferred += io_size;
756 status = LIBUSB_TRANSFER_COMPLETED;
757 break;
758 case ERROR_CANCELLED:
759 usbi_dbg("detected transfer cancel");
760 status = LIBUSB_TRANSFER_CANCELLED;
761 break;
762 case ERROR_NOT_SUPPORTED:
763 case ERROR_GEN_FAILURE:
764 usbi_dbg("detected endpoint stall");
765 status = LIBUSB_TRANSFER_STALL;
766 break;
767 case ERROR_SEM_TIMEOUT:
768 usbi_dbg("detected semaphore timeout");
769 status = LIBUSB_TRANSFER_TIMED_OUT;
770 break;
771 case ERROR_OPERATION_ABORTED:
772 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
773 usbi_dbg("detected timeout");
774 status = LIBUSB_TRANSFER_TIMED_OUT;
775 } else {
776 usbi_dbg("detected operation aborted");
777 status = LIBUSB_TRANSFER_CANCELLED;
779 break;
780 default:
781 usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result));
782 status = LIBUSB_TRANSFER_ERROR;
783 break;
785 wince_clear_transfer_priv(itransfer);
786 if (status == LIBUSB_TRANSFER_CANCELLED) {
787 usbi_handle_transfer_cancellation(itransfer);
788 } else {
789 usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
793 static void wince_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
795 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
797 switch (transfer->type) {
798 case LIBUSB_TRANSFER_TYPE_CONTROL:
799 case LIBUSB_TRANSFER_TYPE_BULK:
800 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
801 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
802 wince_transfer_callback (itransfer, io_result, io_size);
803 break;
804 default:
805 usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
809 static int wince_handle_events(
810 struct libusb_context *ctx,
811 struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
813 struct wince_transfer_priv* transfer_priv = NULL;
814 POLL_NFDS_TYPE i = 0;
815 BOOL found = FALSE;
816 struct usbi_transfer *transfer;
817 DWORD io_size, io_result;
819 usbi_mutex_lock(&ctx->open_devs_lock);
820 for (i = 0; i < nfds && num_ready > 0; i++) {
822 usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
824 if (!fds[i].revents) {
825 continue;
828 num_ready--;
830 // Because a Windows OVERLAPPED is used for poll emulation,
831 // a pollable fd is created and stored with each transfer
832 usbi_mutex_lock(&ctx->flying_transfers_lock);
833 list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
834 transfer_priv = usbi_transfer_get_os_priv(transfer);
835 if (transfer_priv->pollable_fd.fd == fds[i].fd) {
836 found = TRUE;
837 break;
840 usbi_mutex_unlock(&ctx->flying_transfers_lock);
842 if (found && HasOverlappedIoCompleted(transfer_priv->pollable_fd.overlapped)) {
843 io_result = (DWORD)transfer_priv->pollable_fd.overlapped->Internal;
844 io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
845 usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
846 // let handle_callback free the event using the transfer wfd
847 // If you don't use the transfer wfd, you run a risk of trying to free a
848 // newly allocated wfd that took the place of the one from the transfer.
849 wince_handle_callback(transfer, io_result, io_size);
850 } else if (found) {
851 usbi_err(ctx, "matching transfer for fd %x has not completed", fds[i]);
852 return LIBUSB_ERROR_OTHER;
853 } else {
854 usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
855 return LIBUSB_ERROR_NOT_FOUND;
859 usbi_mutex_unlock(&ctx->open_devs_lock);
860 return LIBUSB_SUCCESS;
864 * Monotonic and real time functions
866 unsigned __stdcall wince_clock_gettime_threaded(void* param)
868 LARGE_INTEGER hires_counter, li_frequency;
869 LONG nb_responses;
870 int timer_index;
872 // Init - find out if we have access to a monotonic (hires) timer
873 if (!QueryPerformanceFrequency(&li_frequency)) {
874 usbi_dbg("no hires timer available on this platform");
875 hires_frequency = 0;
876 hires_ticks_to_ps = UINT64_C(0);
877 } else {
878 hires_frequency = li_frequency.QuadPart;
879 // The hires frequency can go as high as 4 GHz, so we'll use a conversion
880 // to picoseconds to compute the tv_nsecs part in clock_gettime
881 hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
882 usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
885 // Signal wince_init() that we're ready to service requests
886 if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
887 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
890 // Main loop - wait for requests
891 while (1) {
892 timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
893 if ( (timer_index != 0) && (timer_index != 1) ) {
894 usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
895 continue;
897 if (request_count[timer_index] == 0) {
898 // Request already handled
899 ResetEvent(timer_request[timer_index]);
900 // There's still a possiblity that a thread sends a request between the
901 // time we test request_count[] == 0 and we reset the event, in which case
902 // the request would be ignored. The simple solution to that is to test
903 // request_count again and process requests if non zero.
904 if (request_count[timer_index] == 0)
905 continue;
907 switch (timer_index) {
908 case 0:
909 WaitForSingleObject(timer_mutex, INFINITE);
910 // Requests to this thread are for hires always
911 if (QueryPerformanceCounter(&hires_counter) != 0) {
912 timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
913 timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
914 } else {
915 // Fallback to real-time if we can't get monotonic value
916 // Note that real-time clock does not wait on the mutex or this thread.
917 wince_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
919 ReleaseMutex(timer_mutex);
921 nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
922 if ( (nb_responses)
923 && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
924 usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
926 continue;
927 case 1: // time to quit
928 usbi_dbg("timer thread quitting");
929 return 0;
932 usbi_dbg("ERROR: broken timer thread");
933 return 1;
936 static int wince_clock_gettime(int clk_id, struct timespec *tp)
938 FILETIME filetime;
939 ULARGE_INTEGER rtime;
940 DWORD r;
941 SYSTEMTIME st;
942 switch(clk_id) {
943 case USBI_CLOCK_MONOTONIC:
944 if (hires_frequency != 0) {
945 while (1) {
946 InterlockedIncrement((LONG*)&request_count[0]);
947 SetEvent(timer_request[0]);
948 r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
949 switch(r) {
950 case WAIT_OBJECT_0:
951 WaitForSingleObject(timer_mutex, INFINITE);
952 *tp = timer_tp;
953 ReleaseMutex(timer_mutex);
954 return LIBUSB_SUCCESS;
955 case WAIT_TIMEOUT:
956 usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
957 break; // Retry until successful
958 default:
959 usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
960 return LIBUSB_ERROR_OTHER;
964 // Fall through and return real-time if monotonic was not detected @ timer init
965 case USBI_CLOCK_REALTIME:
966 // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
967 // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
968 // Note however that our resolution is bounded by the Windows system time
969 // functions and is at best of the order of 1 ms (or, usually, worse)
970 GetSystemTime(&st);
971 SystemTimeToFileTime(&st, &filetime);
972 rtime.LowPart = filetime.dwLowDateTime;
973 rtime.HighPart = filetime.dwHighDateTime;
974 rtime.QuadPart -= epoch_time;
975 tp->tv_sec = (long)(rtime.QuadPart / 10000000);
976 tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
977 return LIBUSB_SUCCESS;
978 default:
979 return LIBUSB_ERROR_INVALID_PARAM;
983 const struct usbi_os_backend wince_backend = {
984 "Windows CE",
986 wince_init,
987 wince_exit,
989 wince_get_device_list,
990 NULL, /* hotplug_poll */
991 wince_open,
992 wince_close,
994 wince_get_device_descriptor,
995 wince_get_active_config_descriptor,
996 wince_get_config_descriptor,
997 NULL, /* get_config_descriptor_by_value() */
999 wince_get_configuration,
1000 wince_set_configuration,
1001 wince_claim_interface,
1002 wince_release_interface,
1004 wince_set_interface_altsetting,
1005 wince_clear_halt,
1006 wince_reset_device,
1008 wince_kernel_driver_active,
1009 wince_detach_kernel_driver,
1010 wince_attach_kernel_driver,
1012 wince_destroy_device,
1014 wince_submit_transfer,
1015 wince_cancel_transfer,
1016 wince_clear_transfer_priv,
1018 wince_handle_events,
1020 wince_clock_gettime,
1021 sizeof(struct wince_device_priv),
1022 sizeof(struct wince_device_handle_priv),
1023 sizeof(struct wince_transfer_priv),