From owner-freebsd-usb@FreeBSD.ORG Tue Apr 17 20:06:52 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 C898B1065672 for ; Tue, 17 Apr 2012 20:06:52 +0000 (UTC) (envelope-from hselasky@c2i.net) Received: from swip.net (mailfe03.c2i.net [212.247.154.66]) by mx1.freebsd.org (Postfix) with ESMTP id 37D1B8FC18 for ; Tue, 17 Apr 2012 20:06:52 +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 mailfe03.swip.net (CommuniGate Pro SMTP 5.4.4) with ESMTPA id 97679819; Tue, 17 Apr 2012 22:06:44 +0200 From: Hans Petter Selasky To: freebsd-usb@freebsd.org Date: Tue, 17 Apr 2012 22:05:43 +0200 User-Agent: KMail/1.13.5 (FreeBSD/8.3-PRERELEASE; KDE/4.4.5; amd64; ; ) References: <20120417100147.GA2557@tiny> <20120417185216.GA1306@tiny> <201204172158.36499.hselasky@c2i.net> In-Reply-To: <201204172158.36499.hselasky@c2i.net> X-Face: 'mmZ:T{)),Oru^0c+/}w'`gU1$ubmG?lp!=R4Wy\ELYo2)@'UZ24N@d2+AyewRX}mAm; Yp |U[@, _z/([?1bCfM{_"B<.J>mICJCHAzzGHI{y7{%JVz%R~yJHIji`y>Y}k1C4TfysrsUI -%GU9V5]iUZF&nRn9mJ'?&>O MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_X0cjPFIooSR/hBr" Message-Id: <201204172205.43267.hselasky@c2i.net> Cc: Bruce Cran 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 20:06:52 -0000 --Boundary-00=_X0cjPFIooSR/hBr Content-Type: Text/Plain; charset="iso-8859-15" Content-Transfer-Encoding: 7bit On Tuesday 17 April 2012 21:58:36 Hans Petter Selasky wrote: > 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 Found a small bug. Try updated patch. --HPS --Boundary-00=_X0cjPFIooSR/hBr Content-Type: text/x-patch; charset="iso-8859-15"; 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..46f0e01 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) { @@ -76,6 +76,9 @@ static int find_dfu_if(libusb_device *dev, int rc; memset(dfu_if, 0, sizeof(*dfu_if)); + + dfu_if->dev_handle = devh; + rc = libusb_get_device_descriptor(dev, &desc); if (rc) return rc; @@ -83,21 +86,21 @@ 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; @@ -115,17 +118,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 +152,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 +172,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 +194,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 +255,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 +291,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 +949,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=_X0cjPFIooSR/hBr--