curdev = devlist;
*curdev = NULL;
- for (bus = usb_busses; bus; bus = bus->next) {
+ for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor == vendor
&& dev->descriptor.idProduct == product)
\param dev libusb usb_dev to use
\retval 0: all fine
+ \retval -3: unable to config device
\retval -4: unable to open device
\retval -5: unable to claim device
\retval -6: reset failed
ftdi_error_return(-4, "usb_open() failed");
#ifdef LIBUSB_HAS_GET_DRIVER_NP
- // Try to detach ftdi_sio kernel module
- // Returns ENODATA if driver is not loaded
+ // Try to detach ftdi_sio kernel module.
+ // Returns ENODATA if driver is not loaded.
+ //
+ // The return code is kept in a separate variable and only parsed
+ // if usb_set_configuration() or usb_claim_interface() fails as the
+ // detach operation might be denied and everything still works fine.
+ // Likely scenario is a static ftdi_sio kernel module.
if (usb_detach_kernel_driver_np(ftdi->usb_dev, ftdi->interface) != 0 && errno != ENODATA)
detach_errno = errno;
#endif
+ // set configuration (needed especially for windows)
+ // tolerate EBUSY: one device with one configuration, but two interfaces
+ // and libftdi sessions to both interfaces (e.g. FT2232)
+ if (dev->descriptor.bNumConfigurations > 0 &&
+ usb_set_configuration(ftdi->usb_dev, dev->config[0].bConfigurationValue) &&
+ errno != EBUSY)
+ {
+ usb_close (ftdi->usb_dev);
+ if (detach_errno == EPERM) {
+ ftdi_error_return(-8, "inappropriate permissions on device!");
+ } else {
+ ftdi_error_return(-3, "unable to set usb configuration. Make sure ftdi_sio is unloaded!");
+ }
+ }
+
if (usb_claim_interface(ftdi->usb_dev, ftdi->interface) != 0) {
usb_close (ftdi->usb_dev);
if (detach_errno == EPERM) {
if (usb_find_devices() < 0)
ftdi_error_return(-2, "usb_find_devices() failed");
- for (bus = usb_busses; bus; bus = bus->next) {
+ for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor == vendor
&& dev->descriptor.idProduct == product) {
int result;
result = ftdi_usb_purge_rx_buffer(ftdi);
- if (!result)
+ if (result < 0)
return -1;
result = ftdi_usb_purge_tx_buffer(ftdi);
- if (!result)
+ if (result < 0)
return -2;
return 0;
output[0x07] = 0x02;
// Addr 08: Config descriptor
- // Bit 1: remote wakeup if 1
- // Bit 0: self powered if 1
- //
- j = 0;
+ // Bit 7: always 1
+ // Bit 6: 1 if this device is self powered, 0 if bus powered
+ // Bit 5: 1 if this device uses remote wakeup
+ // Bit 4: 1 if this device is battery powered
+ j = 0x80;
if (eeprom->self_powered == 1)
- j = j | 1;
+ j |= 0x40;
if (eeprom->remote_wakeup == 1)
- j = j | 2;
+ j |= 0x20;
output[0x08] = j;
// Addr 09: Max power consumption: max power = value * 2 mA
output[0x09] = eeprom->max_power;
- ;
// Addr 0A: Chip configuration
// Bit 7: 0 - reserved