Sujet: Difference of behaviour on usb_reset between Linux and Windows
De: libusb-win32-devel-owner@lists.sourceforge.net
Date: Wed, 14 Nov 2007 06:29:30 -0800
Pour :: roms@lievin.net

You are not allowed to post to this mailing list, and your message has
been automatically rejected.  If you think that your messages are
being rejected in error, contact the mailing list owner at
libusb-win32-devel-owner@lists.sourceforge.net.




Sujet: Difference of behaviour on usb_reset between Linux and Windows
De: Romain Liévin
Date: Wed, 14 Nov 2007 15:29:28 +0100
Pour :: libusb-win32-devel@lists.sourceforge.net
Copie   :: Kevin Kofler

Hi,

I'm currently implementing support of the latest Texas Instruments'
graphing calculator for TiLP (www.tilp.info). This hand-held works under
Linux but run into troubles with libusb-win32. What's difference? TI's
software raises an IOCTL_INTERNAL_USB_RESET_PORT to reset hand-held and
triggers device address request/assignation. I have the same with libusb
under Linux thru usb_reset(). libusb-win32 raises an
IOCTL_INTERNAL_USB_RESET_PORT immediately followed by an
IOCTL_INTERNAL_USB_CYCLE_PORT. I think this is the wrong behaviour (see
below) so I'm actually using a modified version of libusb-win32 driver
to prevent this...

By comparing libusb-win32 and linux kernel behaviour from source code, I
can see:
1) linux: libusb_reset() call linux/kernel/drivers/usb/hub.c:

/**
* usb_reset_device - perform a USB port reset to reinitialize a device
* @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
*
* WARNING - don't use this routine to reset a composite device
* (one with multiple interfaces owned by separate drivers)!
* Use usb_reset_composite_device() instead.
*
* Do a port reset, reassign the device's address, and establish its
* former operating configuration.  If the reset fails, or the device's

=> this is equivalent to RESET_PORT

* descriptors change from their values before the reset, or the original
* configuration and altsettings cannot be restored, a flag will be set
* telling khubd to pretend the device has been disconnected and then
* re-connected.  All drivers will be unbound, and the device will be
* re-enumerated and probed all over again.

=> this is equivalent to CYCLE_PORT _but_ only if reset fails.

*
* Returns 0 if the reset succeeded, -ENODEV if the device has been

2) win32: libusb_reset() call src/drivers/reset_device.c:

<<
status = call_usbd(dev, NULL, IOCTL_INTERNAL_USB_RESET_PORT, timeout);

 if(!NT_SUCCESS(status))
   {
     DEBUG_ERROR("reset_device(): IOCTL_INTERNAL_USB_RESET_PORT failed: "
                 "status: 0x%x", status);
   }

 status = call_usbd(dev, NULL, IOCTL_INTERNAL_USB_CYCLE_PORT, timeout);

 if(!NT_SUCCESS(status))
   {
     DEBUG_ERROR("reset_device(): IOCTL_INTERNAL_USB_CYCLE_PORT failed: "
                 "status: 0x%x", status);
   }


So, libusb-win32 raises both IOCTL. I will suggest to raises the second
IOCTL if the previous IOCTL fails. Like that:

<<
if(!NT_SUCCESS(status))
   {
     DEBUG_ERROR("reset_device(): IOCTL_INTERNAL_USB_RESET_PORT failed: "
                 "status: 0x%x", status);

     status = call_usbd(dev, NULL, IOCTL_INTERNAL_USB_CYCLE_PORT, timeout);

     if(!NT_SUCCESS(status))
     {
       DEBUG_ERROR("reset_device(): IOCTL_INTERNAL_USB_CYCLE_PORT failed: "
                 "status: 0x%x", status);
     }
   }


Regards, Romain.