return code; \
} while(0);
+#define ftdi_error_return_free_device_list(code, str, devs) do { \
+ libusb_free_device_list(devs,1); \
+ ftdi->error_str = str; \
+ return code; \
+ } while(0);
+
/**
Internal function to close usb device pointer.
*/
int ftdi_init(struct ftdi_context *ftdi)
{
+ ftdi->usb_ctx = NULL;
ftdi->usb_dev = NULL;
ftdi->usb_read_timeout = 5000;
ftdi->usb_write_timeout = 5000;
free(ftdi->readbuffer);
ftdi->readbuffer = NULL;
}
- libusb_exit(NULL);
+ libusb_exit(ftdi->usb_ctx);
}
/**
int count = 0;
int i = 0;
- if (libusb_init(NULL) < 0)
+ if (libusb_init(&ftdi->usb_ctx) < 0)
ftdi_error_return(-4, "libusb_init() failed");
- if (libusb_get_device_list(NULL, &devs) < 0)
+ if (libusb_get_device_list(ftdi->usb_ctx, &devs) < 0)
ftdi_error_return(-5, "libusb_get_device_list() failed");
curdev = devlist;
}
else
{
- ftdi_error_return(-3, "unable to set usb configuration. Make sure ftdi_sio is unloaded!");
+ ftdi_error_return(-3, "unable to set usb configuration. Make sure the default FTDI driver is not in use");
}
}
}
}
else
{
- ftdi_error_return(-5, "unable to claim usb device. Make sure ftdi_sio is unloaded!");
+ ftdi_error_return(-5, "unable to claim usb device. Make sure the default FTDI driver is not in use");
}
}
char string[256];
int i = 0;
- if (libusb_init(NULL) < 0)
+ if (libusb_init(&ftdi->usb_ctx) < 0)
ftdi_error_return(-11, "libusb_init() failed");
- if (libusb_get_device_list(NULL, &devs) < 0)
- ftdi_error_return(-12, "libusb_get_device_list() failed");
-
if (ftdi == NULL)
ftdi_error_return(-11, "ftdi context invalid");
+ if (libusb_get_device_list(ftdi->usb_ctx, &devs) < 0)
+ ftdi_error_return(-12, "libusb_get_device_list() failed");
+
while ((dev = devs[i++]) != NULL)
{
struct libusb_device_descriptor desc;
+ int res;
if (libusb_get_device_descriptor(dev, &desc) < 0)
- ftdi_error_return(-13, "libusb_get_device_descriptor() failed");
+ ftdi_error_return_free_device_list(-13, "libusb_get_device_descriptor() failed", devs);
if (desc.idVendor == vendor && desc.idProduct == product)
{
if (libusb_open(dev, &ftdi->usb_dev) < 0)
- ftdi_error_return(-4, "usb_open() failed");
+ ftdi_error_return_free_device_list(-4, "usb_open() failed", devs);
if (description != NULL)
{
if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iProduct, (unsigned char *)string, sizeof(string)) < 0)
{
libusb_close (ftdi->usb_dev);
- ftdi_error_return(-8, "unable to fetch product description");
+ ftdi_error_return_free_device_list(-8, "unable to fetch product description", devs);
}
if (strncmp(string, description, sizeof(string)) != 0)
{
if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iSerialNumber, (unsigned char *)string, sizeof(string)) < 0)
{
ftdi_usb_close_internal (ftdi);
- ftdi_error_return(-9, "unable to fetch serial number");
+ ftdi_error_return_free_device_list(-9, "unable to fetch serial number", devs);
}
if (strncmp(string, serial, sizeof(string)) != 0)
{
continue;
}
- return ftdi_usb_open_dev(ftdi, dev);
+ res = ftdi_usb_open_dev(ftdi, dev);
+ libusb_free_device_list(devs,1);
+ return res;
}
}
// device not found
- ftdi_error_return(-3, "device not found");
+ ftdi_error_return_free_device_list(-3, "device not found", devs);
}
/**
unsigned int bus_number, device_address;
int i = 0;
- if (libusb_init (NULL) < 0)
+ if (libusb_init (&ftdi->usb_ctx) < 0)
ftdi_error_return(-1, "libusb_init() failed");
- if (libusb_get_device_list(NULL, &devs) < 0)
+ if (libusb_get_device_list(ftdi->usb_ctx, &devs) < 0)
ftdi_error_return(-2, "libusb_get_device_list() failed");
/* XXX: This doesn't handle symlinks/odd paths/etc... */
if (sscanf (description + 2, "%u/%u", &bus_number, &device_address) != 2)
- ftdi_error_return(-11, "illegal description format");
+ ftdi_error_return_free_device_list(-11, "illegal description format", devs);
while ((dev = devs[i++]) != NULL)
{
+ int ret;
if (bus_number == libusb_get_bus_number (dev)
&& device_address == libusb_get_device_address (dev))
- return ftdi_usb_open_dev(ftdi, dev);
+ {
+ ret = ftdi_usb_open_dev(ftdi, dev);
+ libusb_free_device_list(devs,1);
+ return ret;
+ }
}
// device not found
- ftdi_error_return(-3, "device not found");
+ ftdi_error_return_free_device_list(-3, "device not found", devs);
}
else if (description[0] == 'i' || description[0] == 's')
{
return offset;
}
-#ifdef LIBFTDI_LINUX_ASYNC_MODE
-#ifdef USB_CLASS_PTP
-#error LIBFTDI_LINUX_ASYNC_MODE is not compatible with libusb-compat-0.1!
-#endif
static void ftdi_read_data_cb(struct libusb_transfer *transfer)
{
struct ftdi_transfer_control *tc = (struct ftdi_transfer_control *) transfer->user_data;
Writes data to the chip. Does not wait for completion of the transfer
nor does it make sure that the transfer was successful.
- Use libusb 1.0 Asynchronous API.
- Only available if compiled with --with-async-mode.
+ Use libusb 1.0 asynchronous API.
\param ftdi pointer to ftdi_context
\param buf Buffer with the data
Reads data from the chip. Does not wait for completion of the transfer
nor does it make sure that the transfer was successful.
- Use libusb 1.0 Asynchronous API.
- Only available if compiled with --with-async-mode.
+ Use libusb 1.0 asynchronous API.
\param ftdi pointer to ftdi_context
\param buf Buffer with the data
/**
Wait for completion of the transfer.
- Use libusb 1.0 Asynchronous API.
- Only available if compiled with --with-async-mode.
+ Use libusb 1.0 asynchronous API.
\param tc pointer to ftdi_transfer_control
while (!tc->completed)
{
- ret = libusb_handle_events(NULL);
+ ret = libusb_handle_events(tc->ftdi->usb_ctx);
if (ret < 0)
{
if (ret == LIBUSB_ERROR_INTERRUPTED)
continue;
libusb_cancel_transfer(tc->transfer);
while (!tc->completed)
- if (libusb_handle_events(NULL) < 0)
+ if (libusb_handle_events(tc->ftdi->usb_ctx) < 0)
break;
libusb_free_transfer(tc->transfer);
free (tc);
return ret;
}
-#endif // LIBFTDI_LINUX_ASYNC_MODE
-
/**
Configure write buffer chunk size.
Default is 4096.
}
/**
+ Frees allocated memory in eeprom.
+
+ \param eeprom Pointer to ftdi_eeprom
+*/
+void ftdi_eeprom_free(struct ftdi_eeprom *eeprom)
+{
+ if (eeprom->manufacturer != 0) {
+ free(eeprom->manufacturer);
+ eeprom->manufacturer = 0;
+ }
+ if (eeprom->product != 0) {
+ free(eeprom->product);
+ eeprom->product = 0;
+ }
+ if (eeprom->serial != 0) {
+ free(eeprom->serial);
+ eeprom->serial = 0;
+ }
+}
+
+/**
Build binary output from ftdi_eeprom structure.
Output is suitable for ftdi_write_eeprom().