From owner-freebsd-usb@FreeBSD.ORG Tue Apr 17 19:59:40 2012 Return-Path: Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 2BF7D1065676 for ; Tue, 17 Apr 2012 19:59:40 +0000 (UTC) (envelope-from hselasky@c2i.net) Received: from swip.net (mailfe05.c2i.net [212.247.154.130]) by mx1.freebsd.org (Postfix) with ESMTP id 9814B8FC1A for ; Tue, 17 Apr 2012 19:59:39 +0000 (UTC) X-T2-Spam-Status: No, hits=-1.0 required=5.0 tests=ALL_TRUSTED Received: from [176.74.212.201] (account mc467741@c2i.net HELO laptop002.hselasky.homeunix.org) by mailfe05.swip.net (CommuniGate Pro SMTP 5.4.4) with ESMTPA id 261231046; Tue, 17 Apr 2012 21:59:37 +0200 From: Hans Petter Selasky To: Matthias Apitz Date: Tue, 17 Apr 2012 21:58:36 +0200 User-Agent: KMail/1.13.5 (FreeBSD/8.3-PRERELEASE; KDE/4.4.5; amd64; ; ) References: <20120417100147.GA2557@tiny> <201204172041.56552.hselasky@c2i.net> <20120417185216.GA1306@tiny> In-Reply-To: <20120417185216.GA1306@tiny> X-Face: 'mmZ:T{)),Oru^0c+/}w'`gU1$ubmG?lp!=R4Wy\ELYo2)@'UZ24N@ =?iso-8859-1?q?d2+AyewRX=7DmAm=3BYp=0A=09=7CU=5B?=@, _z/([?1bCfM{_"B<.J>mICJCHAzzGHI{y7{%JVz%R~yJHIji`y> =?iso-8859-1?q?Y=7Dk1C4TfysrsUI=0A=09-=25GU9V5=5DiUZF=26nRn9mJ=27=3F=26?=>O MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_stcjPEB6qXT1vpE" Message-Id: <201204172158.36499.hselasky@c2i.net> Cc: Bruce Cran , freebsd-usb@freebsd.org Subject: Re: dfu-util 0.5 X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Apr 2012 19:59:40 -0000 --Boundary-00=_stcjPEB6qXT1vpE Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Hi Matthias, I reviewed the dfu-util code and there is a bug there with regard to libusb usage. Can you try the attached patch. It fixes a duplicate libusb open bug. --HPS --Boundary-00=_stcjPEB6qXT1vpE Content-Type: text/x-patch; charset="iso-8859-1"; name="dfu-util.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dfu-util.patch" diff --git a/src/main.c b/src/main.c index 8986859..11ddf4f 100644 --- a/src/main.c +++ b/src/main.c @@ -63,7 +63,7 @@ int verbose = 0; * Iterate through all DFU interfaces and their alternate settings * and call the passed handler function on each setting until handler * returns non-zero. */ -static int find_dfu_if(libusb_device *dev, +static int find_dfu_if(libusb_device *dev, libusb_device_handle *devh, int (*handler)(struct dfu_if *, void *), void *v) { @@ -83,24 +83,25 @@ static int find_dfu_if(libusb_device *dev, cfg_idx++) { rc = libusb_get_config_descriptor(dev, cfg_idx, &cfg); if (rc) - return rc; + goto done; /* in some cases, noticably FreeBSD if uid != 0, * the configuration descriptors are empty */ if (!cfg) - return 0; + goto done; for (intf_idx = 0; intf_idx < cfg->bNumInterfaces; intf_idx++) { uif = &cfg->interface[intf_idx]; if (!uif) - return 0; + goto done; for (alt_idx = 0; alt_idx < uif->num_altsetting; alt_idx++) { intf = &uif->altsetting[alt_idx]; if (!intf) - return 0; + goto done; if (intf->bInterfaceClass == 0xfe && intf->bInterfaceSubClass == 1) { dfu_if->dev = dev; + dfu_if->dev_handle = devh; dfu_if->vendor = desc.idVendor; dfu_if->product = @@ -115,17 +116,21 @@ static int find_dfu_if(libusb_device *dev, dfu_if->flags |= DFU_IFF_DFU; else dfu_if->flags &= ~DFU_IFF_DFU; - if (!handler) - return 1; + if (!handler) { + rc = 1; + goto done; + } rc = handler(dfu_if, v); if (rc != 0) - return rc; + goto done; } } } - libusb_free_config_descriptor(cfg); } +done: + if (devh == NULL && dfu_if->dev_handle != NULL) + libusb_close(dfu_if->dev_handle); return 0; } @@ -145,7 +150,8 @@ static int _get_first_cb(struct dfu_if *dif, void *v) /* Fills in dif with the first found DFU interface */ static int get_first_dfu_if(struct dfu_if *dif) { - return find_dfu_if(dif->dev, &_get_first_cb, (void *) dif); + return find_dfu_if(dif->dev, dif->dev_handle, + &_get_first_cb, (void *) dif); } static int _check_match_cb(struct dfu_if *dif, void *v) @@ -164,7 +170,8 @@ static int _check_match_cb(struct dfu_if *dif, void *v) /* Fills in dif from the matching DFU interface/altsetting */ static int get_matching_dfu_if(struct dfu_if *dif) { - return find_dfu_if(dif->dev, &_check_match_cb, (void *) dif); + return find_dfu_if(dif->dev, dif->dev_handle, + &_check_match_cb, (void *) dif); } static int _count_match_cb(struct dfu_if *dif, void *v) @@ -185,7 +192,8 @@ static int _count_match_cb(struct dfu_if *dif, void *v) static int count_matching_dfu_if(struct dfu_if *dif) { dif->count = 0; - find_dfu_if(dif->dev, &_count_match_cb, (void *) dif); + find_dfu_if(dif->dev, dif->dev_handle, + &_count_match_cb, (void *) dif); return dif->count; } @@ -245,7 +253,7 @@ static int list_dfu_interfaces(libusb_context *ctx) for (i = 0; i < num_devs; ++i) { dev = list[i]; - find_dfu_if(dev, &print_dfu_if, NULL); + find_dfu_if(dev, NULL, &print_dfu_if, NULL); } libusb_free_device_list(list, 1); @@ -281,7 +289,7 @@ static int count_dfu_interfaces(libusb_device *dev) { int num_found = 0; - find_dfu_if(dev, &_count_cb, (void *) &num_found); + find_dfu_if(dev, NULL, &_count_cb, (void *) &num_found); return num_found; } @@ -939,7 +947,8 @@ dfustate: if (alt_name) { int n; - n = find_dfu_if(dif->dev, &alt_by_name, alt_name); + n = find_dfu_if(dif->dev, dif->dev_handle, + &alt_by_name, alt_name); if (!n) { fprintf(stderr, "No such Alternate Setting: \"%s\"\n", alt_name); --Boundary-00=_stcjPEB6qXT1vpE--