From owner-freebsd-usb@freebsd.org Sun Jun 28 09:28:12 2020 Return-Path: Delivered-To: freebsd-usb@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 8A711346985 for ; Sun, 28 Jun 2020 09:28:12 +0000 (UTC) (envelope-from jbe-mlist@magnetkern.de) Received: from sapphire.magnetkern.de (sapphire.magnetkern.de [185.228.139.199]) by mx1.freebsd.org (Postfix) with ESMTP id 49vlfM2gvZz49L4 for ; Sun, 28 Jun 2020 09:28:10 +0000 (UTC) (envelope-from jbe-mlist@magnetkern.de) Received: from titanium (p5dd45c70.dip0.t-ipconnect.de [93.212.92.112]) by sapphire.magnetkern.de (Postfix) with ESMTPSA id 6AF1E1775; Sun, 28 Jun 2020 09:28:09 +0000 (UTC) Date: Sun, 28 Jun 2020 11:28:08 +0200 From: Jan Behrens To: Tomasz CEDRO Cc: "freebsd-usb@FreeBSD.org" Subject: Re: USB reset fails when using a LimeSDR Mini on FreeBSD Message-Id: <20200628112808.3e0c2bb374a784af7adf29fa@magnetkern.de> In-Reply-To: <20200627173604.7f7b7777140e66dbad812fc7@magnetkern.de> References: <20200625121052.e9f7e7cbeb68fad264ec80a9@magnetkern.de> <20200625200849.6af81489a80c2f97d4f89ee6@magnetkern.de> <20200625224522.44d6584465cb6e20d17be320@magnetkern.de> <0ec3e5a3-7f31-d1cd-6862-6066c431aa80@selasky.org> <20200626135151.e5542cf97fad213c4ad661f2@magnetkern.de> <5c0729f9-9e98-52f7-a5cb-6c5dfd2287a3@selasky.org> <20200626172851.872f3a08fa6e632666683230@magnetkern.de> <20200627144419.f14371695d9b62ea99106c4a@magnetkern.de> <20200627173604.7f7b7777140e66dbad812fc7@magnetkern.de> X-Mailer: Sylpheed 3.7.0 (GTK+ 2.24.32; amd64-portbld-freebsd12.0) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Rspamd-Queue-Id: 49vlfM2gvZz49L4 X-Spamd-Bar: - Authentication-Results: mx1.freebsd.org; dkim=none; dmarc=none; spf=pass (mx1.freebsd.org: domain of jbe-mlist@magnetkern.de designates 185.228.139.199 as permitted sender) smtp.mailfrom=jbe-mlist@magnetkern.de X-Spamd-Result: default: False [-1.34 / 15.00]; TO_DN_EQ_ADDR_SOME(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; ARC_NA(0.00)[]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; MV_CASE(0.50)[]; R_SPF_ALLOW(-0.20)[+mx]; MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[magnetkern.de]; NEURAL_HAM_LONG(-0.98)[-0.976]; NEURAL_SPAM_SHORT(0.30)[0.298]; TO_MATCH_ENVRCPT_SOME(0.00)[]; RCPT_COUNT_TWO(0.00)[2]; NEURAL_HAM_MEDIUM(-0.96)[-0.958]; RCVD_NO_TLS_LAST(0.10)[]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:197540, ipnet:185.228.136.0/22, country:DE]; RCVD_COUNT_TWO(0.00)[2]; MID_RHS_MATCH_FROM(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[93.212.92.112:received] X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 28 Jun 2020 09:28:12 -0000 On Sat, 27 Jun 2020 17:36:04 +0200 Jan Behrens wrote: > On Sat, 27 Jun 2020 16:12:45 +0200 > Tomasz CEDRO wrote: > > > I guess the FreeBSD's LibUSB implementation should be one-to-one > > compatible with the GNU LibUSB. Unless GNU LibUSB behaves wrong, in which case there'd be a good reason for FreeBSD's LibUSB to behave differently. But not sure if that's the case. > > I would try to test and compare it > > with Linux and MacOS implementation and see the difference: > > > > 1. If the problem exists on FreeBSD, Linux, MacOS. If so/no then if > > there are different error messages / codes. If there are more verbose > > codes / messages on systems other than BSD then FreeBSD's > > implementation may need an update. However, the difference here seems > > to be the USB stack itself. As I currently have no Linux installed on my machines, I tested with a friend how the SoapySDR module for the LimeSDR Mini (SoapyLMS7 from Lime Suite 20.01.0) behaves on Linux in regard to the libusb_reset_device() call. This is our result: We modified LimeSuite-20.01.0/src/ConnectionFTDI/ConnectionFT601.cpp in the following way: At the begin of the file: #include #include And then below: fprintf(stderr, "DEBUG: Executing libusb_reset_device() [UID=%i, effective UID=%i]\n", getuid(), geteuid()); if (libusb_reset_device(dev_handle)!=0) return ReportError(-1, "USB reset failed", libusb_strerror(libusb_error(r))); fprintf(stderr, "DEBUG: libusb_reset_device() executed successfully.\n"); This resulted in the following output: $ SoapySDRUtil --make ###################################################### ## Soapy SDR -- the SDR abstraction library ## ###################################################### Make device linux; GNU C++ version 7.3.0; Boost_106501; UHD_003.010.003.000-0-unknown [INFO] Make connection: 'LimeSDR Mini [USB 2.0] 1D3AC7FE409032' DEBUG: Executing libusb_reset_device() [UID=1000, effective UID=1000] DEBUG: libusb_reset_device() executed successfully. [INFO] Reference clock 40.00 MHz [INFO] Device name: LimeSDR-Mini [INFO] Reference: 40 MHz [INFO] LMS7002M register cache: Disabled driver=FT601 hardware=LimeSDR-Mini boardSerialNumber=0x1d3ac7fe409032 firmwareVersion=6 gatewareVersion=1.30 hardwareVersion=1 protocolVersion=1 Thus libusb_reset_device() returns without an error on GNU/Linux, despite being executed as user (UID and EUID = 1000). This proves that on Linux there is no problem in executing the call as non-root. The problem appears on FreeBSD only. > > > > 2. If that function blocks normal operations on FreeBSD while without > > it everything works fine, then it may be wrapped around ifdef and > > simply removed for FreeBSD. Whether the libusb_reset_device() call is needed or not isn't clear to me. It *appears* to work without the call, but I'm not sure if there are side effects or corner cases. The context of the call is as follows: [...] libusb_open(devs[i], &dev_handle) [...]; if(libusb_kernel_driver_active(dev_handle, 1) == 1) //find out if kernel driver is attached { lime::debug("Kernel Driver Active"); if(libusb_detach_kernel_driver(dev_handle, 1) == 0) //detach it lime::debug("Kernel Driver Detached!"); } int r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device if (r < 0) return ReportError(-1, "Cannot claim interface - %s", libusb_strerror(libusb_error(r))); if ((r = libusb_claim_interface(dev_handle, 1))<0) //claim interface 1 of device return ReportError(-1, "Cannot claim interface - %s", libusb_strerror(libusb_error(r))); lime::debug("Claimed Interface"); if (libusb_reset_device(dev_handle)!=0) return ReportError(-1, "USB reset failed", libusb_strerror(libusb_error(r))); FT_FlushPipe(ctrlRdEp); //clear ctrl ep rx buffer FT_SetStreamPipe(ctrlRdEp,64); FT_SetStreamPipe(ctrlWrEp,64); isConnected = true; return 0; See: https://github.com/myriadrf/LimeSuite/blob/1c1c202f9a6ae4bb34068b6f3f576f7f8e74c7f1/src/ConnectionFTDI/ConnectionFT601.cpp#L160 > > > > 3. Make sure this is not a bug in the LimeSDR firmware that makes this > > non-standard behaviour. As shown above, no problem on Linux. It might still be wrong to call libusb_reset_device(), but for that we'd need to understand why it's called and if it's generally a bad practice to call it as driver that runs as non-root (and if there are alternatives or if it's just not necessary to do the call). > > > > 4. According to `man usbconfig` reset will perform "Reset the device. > > This forces the USB stack to reenumerate the bus.". If LimeSDR uses > > some dynamic USB interfaces configuration and re-organizes itself at > > runtime then I would observe how the FreeBSD USB stack reacts to that > > changes. Such reset may not be even necessary by hand (or from libusb) > > if the OS re-enumerates the bus for you. Maybe on other OS it is > > important to call that libusb reset to make sure the bus is > > re-enumerated. > > > > @HPS is the author of the USB stack so he could provide some hints.. > > but without actually seeing the device it can be hard to achieve :-) For that, it would be helpful to understand when libusb_reset_device() needs to or should be called, and if it's (supposed to be) the same on FreeBSD, Linux, and macOS. > > [...] > > > > Are you sure this is the problem? When run as root does the program > > works fine? If so, there may be a systctl setting for the stack that > > may allow user to reset / power-on-off the port (@HPS?)? You may want > > to take a look at `sysctl -a | grep usb` to search for such sysctl > > option. Maybe also `man usbconfig` and `man usb`. Regards, Jan