From e3943041a1d8869fb9d6779d49946e0a9d7dbff2 Mon Sep 17 00:00:00 2001
From: Antonio Ospite <ao2@ao2.it>
Date: Wed, 10 Jun 2015 12:38:21 +0200
Subject: [PATCH 1/1] am7xxx-modeswitch: set USB configuration following libusb
 documentation

For the details see: http://libusb.sourceforge.net/api-1.0/caveats.html
---
 examples/am7xxx-modeswitch.c | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/examples/am7xxx-modeswitch.c b/examples/am7xxx-modeswitch.c
index b431084..1230bd4 100644
--- a/examples/am7xxx-modeswitch.c
+++ b/examples/am7xxx-modeswitch.c
@@ -35,6 +35,7 @@ int main(void)
 {
 	int ret;
 	libusb_device_handle *usb_device;
+	int current_configuration;
 	unsigned int len;
 	int transferred;
 
@@ -56,15 +57,26 @@ int main(void)
 		goto out;
 	}
 
-	ret = libusb_set_configuration(usb_device, AM7XXX_STORAGE_CONFIGURATION);
+	current_configuration = -1;
+	ret = libusb_get_configuration(usb_device, &current_configuration);
 	if (ret < 0) {
-		fprintf(stderr, "libusb_set_configuration failed: %s\n",
+		fprintf(stderr, "libusb_get_configuration failed: %s\n",
 			libusb_error_name(ret));
-		fprintf(stderr, "Cannot set configuration %hhu\n",
-			AM7XXX_STORAGE_CONFIGURATION);
 		goto out_libusb_close;
 	}
 
+	if (current_configuration != AM7XXX_STORAGE_CONFIGURATION) {
+		ret = libusb_set_configuration(usb_device,
+					       AM7XXX_STORAGE_CONFIGURATION);
+		if (ret < 0) {
+			fprintf(stderr, "libusb_set_configuration failed: %s\n",
+				libusb_error_name(ret));
+			fprintf(stderr, "Cannot set configuration %hhu\n",
+				AM7XXX_STORAGE_CONFIGURATION);
+			goto out_libusb_close;
+		}
+	}
+
 	libusb_set_auto_detach_kernel_driver(usb_device, 1);
 
 	ret = libusb_claim_interface(usb_device, AM7XXX_STORAGE_INTERFACE);
@@ -76,6 +88,24 @@ int main(void)
 		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;
+	ret = libusb_get_configuration(usb_device, &current_configuration);
+	if (ret < 0) {
+		fprintf(stderr, "libusb_get_configuration after claim failed: %s\n",
+			libusb_error_name(ret));
+		goto out_libusb_release_interface;
+	}
+
+	if (current_configuration != AM7XXX_STORAGE_CONFIGURATION) {
+		fprintf(stderr, "libusb configuration changed (expected: %hhu, current: %hhu\n",
+			AM7XXX_STORAGE_CONFIGURATION, current_configuration);
+		ret = -EINVAL;
+		goto out_libusb_release_interface;
+	}
+
 	len = sizeof(switch_command);
 	transferred = 0;
 	ret = libusb_bulk_transfer(usb_device, AM7XXX_STORAGE_OUT_EP,
-- 
2.1.4