On Sat, 27 Jun 2020 17:36:04 +0200 Jan Behrens <[email protected]> wrote:
> On Sat, 27 Jun 2020 16:12:45 +0200 > Tomasz CEDRO <[email protected]> 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 <unistd.h> #include <sys/types.h> 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 _______________________________________________ [email protected] mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-usb To unsubscribe, send any mail to "[email protected]"
