WinCE: Don't confirm protocol stalls with device in wince_transfer_callback()
authorSimon Haggett <simon.haggett@realvnc.com>
Thu, 21 Feb 2013 16:59:00 +0000 (16:59 +0000)
committerPete Batard <pete@akeo.ie>
Fri, 22 Feb 2013 00:55:23 +0000 (00:55 +0000)
When wince_transfer_callback() observes a stall (io_result set to
ERROR_NOT_SUPPORTED), it checks with the device (by sending a GET_STATUS
control transfer) that the endpoint is really stalled. This check is not
suitable for protocol stalls as these are always cleared at the start of the
next control transfer. When a protocol stall occurs, wince_transfer_callback()
observes that the corresponding control endpoint does not remain stalled and so
forces io_result to ERROR_SUCCESS. This then prevents applications from
detecting that a control request was not supported by the device.

This patch prevents wince_transfer_callback() from attempting to confirm
protocol stalls with the device, allowing io_result to remain set to
ERROR_NOT_SUPPORTED. A couple of comments and a debug log message within
wince_transfer_callback() are also corrected.

libusb/os/wince_usb.c
libusb/version_nano.h

index 8f5bb92..b90950f 100644 (file)
@@ -700,26 +700,26 @@ static void wince_transfer_callback(struct usbi_transfer *itransfer, uint32_t io
 
        usbi_dbg("handling I/O completion with errcode %d", io_result);
 
-       if (io_result == ERROR_NOT_SUPPORTED) {
-               /* The WinCE USB layer (and therefore the USB Kernel Wrapper Driver) will report
-                * USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the endpoint isn't actually
-                * stalled.
+       if (io_result == ERROR_NOT_SUPPORTED && 
+               transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) {
+               /* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper 
+                * Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the 
+                * endpoint isn't actually stalled.
                 *
                 * One example of this is that some devices will occasionally fail to reply to an IN
                 * token. The WinCE USB layer carries on with the transaction until it is completed
                 * (or cancelled) but then completes it with USB_ERROR_STALL.
                 *
-                * This code therefore needs to confirm that there really is a stall error, but checking
-                * the pipe status and requesting the endpoint status from the device.
+                * This code therefore needs to confirm that there really is a stall error, by both
+                * checking the pipe status and requesting the endpoint status from the device.
                 */
                BOOL halted = FALSE;
                usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall");
                if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) {
-                       /* The host side doesn't think the endpoint is halted, so check with the device if
-                        * it is stalled.
-                        *
-                        * So form a GET_STATUS control request. This is done synchronously,
-                        * which is a bit naughty, but this is a special corner case. */
+                       /* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS
+                        * control request to the device. This is done synchronously, which is a bit 
+                        * naughty, but this is a special corner case.
+                        */
                        WORD wStatus = 0;
                        DWORD written = 0;
                        UKW_CONTROL_HEADER ctrlHeader;
@@ -738,7 +738,7 @@ static void wince_transfer_callback(struct usbi_transfer *itransfer, uint32_t io
                                                usbi_dbg("Endpoint doesn't appear to be stalled, overriding error with success");
                                                io_result = ERROR_SUCCESS;
                                        } else {
-                                               usbi_dbg("Endpoint does appear to be stalled, but the host is halted, changing error");
+                                               usbi_dbg("Endpoint doesn't appear to be stalled, but the host is halted, changing error");
                                                io_result = ERROR_IO_DEVICE;
                                        }
                                }
index 4d6f906..fbd337f 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10618
+#define LIBUSB_NANO 10619