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. Signed-off-by: Simon Haggett <simon.hagg...@realvnc.com> --- libusb/os/wince_usb.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libusb/os/wince_usb.c b/libusb/os/wince_usb.c index 8f5bb92..b90950f 100644 --- a/libusb/os/wince_usb.c +++ b/libusb/os/wince_usb.c @@ -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; } } -- 1.7.10.msysgit.1 ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_feb _______________________________________________ libusbx-devel mailing list libusbx-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libusbx-devel