am7xxx: use libusb_error_name to print the return value of libusb calls
[libam7xxx.git] / src / am7xxx.c
index 8837e41..ecec7d7 100644 (file)
@@ -385,8 +385,8 @@ static int read_data(am7xxx_device *dev, uint8_t *buffer, unsigned int len)
 
        ret = libusb_bulk_transfer(dev->usb_device, 0x81, buffer, len, &transferred, 0);
        if (ret != 0 || (unsigned int)transferred != len) {
-               error(dev->ctx, "ret: %d\ttransferred: %d (expected %u)\n",
-                     ret, transferred, len);
+               error(dev->ctx, "%s. Transferred: %d (expected %u)\n",
+                     libusb_error_name(ret), transferred, len);
                return ret;
        }
 
@@ -404,8 +404,8 @@ static int send_data(am7xxx_device *dev, uint8_t *buffer, unsigned int len)
 
        ret = libusb_bulk_transfer(dev->usb_device, 0x1, buffer, len, &transferred, 0);
        if (ret != 0 || (unsigned int)transferred != len) {
-               error(dev->ctx, "ret: %d\ttransferred: %d (expected %u)\n",
-                     ret, transferred, len);
+               error(dev->ctx, "%s. Transferred: %d (expected %u)\n",
+                     libusb_error_name(ret), transferred, len);
                return ret;
        }
 
@@ -708,6 +708,7 @@ static int open_device(am7xxx_context *ctx,
                       am7xxx_device **dev)
 {
        int ret;
+       int current_configuration;
 
        *dev = find_device(ctx, device_index);
        if (*dev == NULL) {
@@ -724,7 +725,7 @@ static int open_device(am7xxx_context *ctx,
 
        ret = libusb_open(usb_dev, &((*dev)->usb_device));
        if (ret < 0) {
-               debug(ctx, "libusb_open failed\n");
+               debug(ctx, "libusb_open failed: %s\n", libusb_error_name(ret));
                goto out;
        }
 
@@ -732,19 +733,39 @@ static int open_device(am7xxx_context *ctx,
         * to close it again before bailing out.
         */
 
-       ret = libusb_set_configuration((*dev)->usb_device,
-                                      (*dev)->desc->configuration);
-       if (ret < 0) {
-               debug(ctx, "libusb_set_configuration failed\n");
-               debug(ctx, "Cannot set configuration %hhu\n",
-                     (*dev)->desc->configuration);
-               goto out_libusb_close;
+       current_configuration = -1;
+       libusb_get_configuration((*dev)->usb_device, &current_configuration);
+       if (current_configuration != (*dev)->desc->configuration) {
+               ret = libusb_set_configuration((*dev)->usb_device,
+                                              (*dev)->desc->configuration);
+               if (ret < 0) {
+                       debug(ctx, "libusb_set_configuration failed: %s\n",
+                             libusb_error_name(ret));
+                       debug(ctx, "Cannot set configuration %hhu\n",
+                             (*dev)->desc->configuration);
+                       goto out_libusb_close;
+               }
        }
 
+       libusb_set_auto_detach_kernel_driver((*dev)->usb_device, 1);
+
        ret = libusb_claim_interface((*dev)->usb_device,
                                     (*dev)->desc->interface_number);
        if (ret < 0) {
-               debug(ctx, "libusb_claim_interface failed\n");
+               debug(ctx, "libusb_claim_interface failed: %s\n",
+                     libusb_error_name(ret));
+               debug(ctx, "Cannot claim interface %hhu\n",
+                     (*dev)->desc->interface_number);
+               goto out_libusb_close;
+       }
+
+       /* Checking that the configuration has not changed, as suggested in
+        * http://libusb.sourceforge.net/api-1.0/caveats.html
+        */
+       current_configuration = -1;
+       libusb_get_configuration((*dev)->usb_device, &current_configuration);
+       if (current_configuration != (*dev)->desc->configuration) {
+               debug(ctx, "libusb configuration changed\n");
                debug(ctx, "Cannot claim interface %hhu\n",
                      (*dev)->desc->interface_number);
                goto out_libusb_close;
@@ -767,13 +788,13 @@ typedef enum {
  * This is where the central logic of multi-device support is.
  *
  * When 'op' == SCAN_OP_BUILD_DEVLIST the parameters 'open_device_index' and
- * 'dev' are ignored; the function returns 0 on success and a negative value
+ * 'dev' are ignored; the function returns 0 on success or a negative value
  * on error.
  *
  * When 'op' == SCAN_OP_OPEN_DEVICE the function opens the supported USB
  * device with index 'open_device_index' and returns the correspondent
  * am7xxx_device in the 'dev' parameter; the function returns the value from
- * open_device(), which is 0 on success, 1 if the device was already open and
+ * open_device(), which is 0 on success, 1 if the device was already open or
  * a negative value on error.
  *
  * NOTES: