Hi, This patch fixes misleading errors being sent to the application from libftdi.
Background: usb_open() will silently succeed when the device node can only be opened read-only and not read-write. When this occurs, various subsequent ioctls to that node will fail, and are presented to the application as failures of those specific operations, even though the root cause is a permissions error. Using usb_claim_interface after every usb_open() would reveal a permissions problem earlier, but it is desirable in this case to scan properties of USB devices to find FTDI chips without necessarily attempting to claim every device for exclusive access. The patch ensures that when libftdi performs a libusb operation on an opened but not claimed USB device, a failure due to a permissions error will be propagated to the application as a permissions error and not a different, red-herring error. -- Ryan C. Underwood, <[email protected]>
--- libftdi-0.20/src/ftdi.c 2012-11-16 10:32:50.000000000 -0600
+++ ftdi.eperm.c 2012-11-16 10:30:12.303281040 -0600
@@ -358,6 +358,8 @@
int ftdi_usb_get_strings(struct ftdi_context * ftdi, struct usb_device * dev,
char * manufacturer, int mnf_len, char * description, int desc_len, char * serial, int serial_len)
{
+ int err;
+
if ((ftdi==NULL) || (dev==NULL))
return -1;
@@ -366,27 +368,33 @@
if (manufacturer != NULL)
{
- if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iManufacturer, manufacturer, mnf_len) <= 0)
+ if ((err = usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iManufacturer, manufacturer, mnf_len)) <= 0)
{
ftdi_usb_close_internal (ftdi);
+ if (err == -EPERM)
+ ftdi_error_return(-4, usb_strerror());
ftdi_error_return(-7, usb_strerror());
}
}
if (description != NULL)
{
- if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iProduct, description, desc_len) <= 0)
+ if ((err = usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iProduct, description, desc_len)) <= 0)
{
ftdi_usb_close_internal (ftdi);
+ if (err == -EPERM)
+ ftdi_error_return(-4, usb_strerror());
ftdi_error_return(-8, usb_strerror());
}
}
if (serial != NULL)
{
- if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iSerialNumber, serial, serial_len) <= 0)
+ if ((err = usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iSerialNumber, serial, serial_len)) <= 0)
{
ftdi_usb_close_internal (ftdi);
+ if (err == -EPERM)
+ ftdi_error_return(-4, usb_strerror());
ftdi_error_return(-9, usb_strerror());
}
}
@@ -641,6 +649,7 @@
struct usb_bus *bus;
struct usb_device *dev;
char string[256];
+ int err;
usb_init();
@@ -664,9 +673,11 @@
if (description != NULL)
{
- if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iProduct, string, sizeof(string)) <= 0)
+ if ((err = usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iProduct, string, sizeof(string))) <= 0)
{
ftdi_usb_close_internal (ftdi);
+ if (err == -EPERM)
+ ftdi_error_return(-4, "unable to fetch product description");
ftdi_error_return(-8, "unable to fetch product description");
}
if (strncmp(string, description, sizeof(string)) != 0)
@@ -678,9 +689,11 @@
}
if (serial != NULL)
{
- if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iSerialNumber, string, sizeof(string)) <= 0)
+ if ((err = usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iSerialNumber, string, sizeof(string))) <= 0)
{
ftdi_usb_close_internal (ftdi);
+ if (err == -EPERM)
+ ftdi_error_return(-4, "unable to fetch serial number");
ftdi_error_return(-9, "unable to fetch serial number");
}
if (strncmp(string, serial, sizeof(string)) != 0)
signature.asc
Description: Digital signature
