From: Xiaofan C. <xia...@gm...> - 2011-02-20 12:48:25
|
On Sun, Feb 20, 2011 at 7:11 PM, Xiaofan Chen <xia...@gm...> wrote: > On Sun, Feb 20, 2011 at 5:17 PM, Xiaofan Chen <xia...@gm...> wrote: >> On Thu, Jan 20, 2011 at 8:20 PM, Pete Batard <pb...@gm...> wrote: >>>> By the way, what if you run the application twice? I seem to get >>>> similar issues under Linux where the 2nd run will cause problems. >>>> Resetting the device will get it to work again. >>> >>> Same story on my side (from cygwin). Second run times out on read. >>> >>>> On the other hand, running Jan Axelson's test program will >>>> not have this issue. Strange. >>> >>> Hmmm, OK. I'll make on note of this and take a look when I have a chance. >>> >> >> Today I also tried the libusb-win32 based application (using libusb-win32 >> device driver or using libusb-win32 filter driver on top of WinUSB.sys), >> everything works fine, no reset is necessary. So it seems to be relate >> to libusb-1.0 behavior which may trigger potential firmware bug. > > Then I tested under Ubuntu Linux 10.10 with both libusb-0.1 and > libusb-1.0, the programs both work without calling > usb_reset_device()/libusb_reset_device() or resetting the > device. > > So the problem is now unique to libusb-1.0 Windows backend. > After some testing, it seems to me the issue is with libusb_set_configuration(devh, 1), after removing this call, the issue is gone. >From the known limitation, it is mentioned that "Neither WinUSB or HID can be used to set a device configuration that is different from the default one. This is a limitation of the Microsoft drivers." Therefore I have some doubts about the following codes in windows_usb.c. Apparently the Control Transfer may have some side effect on some device. Maybe a simple method is to try to get the active configuration (probably 1) and then if it is equal to the configuration the user wants to set, then just return success. /* * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver * does not currently expose a service that allows higher-level drivers to set * the configuration." */ static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config) { struct windows_device_priv *priv = __device_priv(dev_handle->dev); int r = LIBUSB_SUCCESS; if (config >= USB_MAXCONFIG) return LIBUSB_ERROR_INVALID_PARAM; r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE, LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config, 0, NULL, 0, 1000); if (r == LIBUSB_SUCCESS) { priv->active_config = (uint8_t)config; } return r; } -- Xiaofan |