[PATCH dfu-util] main: Try to get cached functional descriptor from libusb

Tormod Volden lists.tormod at gmail.com
Mon Sep 19 22:17:25 CEST 2011


From: Tormod Volden <debian.tormod at gmail.com>

So that we can avoid asking the device about it. In particular
the Freerunner does not like too much enquiries.
---

Stefan (or someone with a Freerunner),
can you please test this patch against current master?

Please report back if it found the "cached USB_DT_DFU" or not.

Thanks,
Tormod

 src/main.c |   39 +++++++++++++++++++++++++++++++++++++--
 1 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/src/main.c b/src/main.c
index 819e26c..40fc9de 100644
--- a/src/main.c
+++ b/src/main.c
@@ -451,6 +451,41 @@ static int usb_get_extra_descriptor(struct dfu_if *dfu_if, unsigned char type,
 				     size);
 }
 
+static int get_dfu_functional_descriptor(struct dfu_if *dfu_if, void *resbuf,
+					 int size)
+{
+	libusb_device *dev = dfu_if->dev;
+	struct libusb_config_descriptor *cfg;
+	const unsigned char *extra;
+	int extra_len;
+	int ret;
+
+	ret = libusb_get_config_descriptor_by_value(dev, dfu_if->configuration,
+						    &cfg);
+	if (ret)
+		return ret;
+
+	extra = cfg->interface[dfu_if->interface].
+			altsetting[dfu_if->altsetting].extra;
+	extra_len = cfg->interface[dfu_if->interface].
+			altsetting[dfu_if->altsetting].extra_length;
+	/* This assumes there is only one descriptor in extra */
+	if (extra && extra_len > 2 && extra[1] == USB_DT_DFU) {
+		printf("yoohoo! Found cached USB_DT_DFU of size %i\n",
+			extra_len);
+		if (extra_len > size)
+			extra_len = size;
+		memcpy(resbuf, extra, extra_len);
+		libusb_free_config_descriptor(cfg);
+		return extra_len;
+	}
+	libusb_free_config_descriptor(cfg);
+	printf("boooh! Did not find cached USB_DT_DFU\n");
+	/* Try retrieve it from device */
+	return usb_get_extra_descriptor(dfu_if, USB_DT_DFU,
+				dfu_if->interface, resbuf, size);
+}
+
 static void help(void)
 {
 	printf("Usage: dfu-util [options] ...\n"
@@ -890,8 +925,8 @@ status_again:
 
 	if (!transfer_size) {
 		/* Obtain DFU functional descriptor */
-		ret = usb_get_extra_descriptor(dif, USB_DT_DFU,
-				dif->interface, &func_dfu, sizeof(func_dfu));
+		ret = get_dfu_functional_descriptor(dif, &func_dfu,
+						    sizeof(func_dfu));
 		if (ret < 0) {
 			fprintf(stderr, "Error obtaining DFU functional "
 				"descriptor\n");
-- 
1.7.5.4




More information about the devel mailing list