-
-
Notifications
You must be signed in to change notification settings - Fork 349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Please port to libusb 1.0 #300
Comments
Agree; I was trying to debug a nut installation on illumos and it took me quite some time to even locate the source code for libusb 0.1. |
thanks for the report guys, this is on my TODO stack for too long, and time has come to move on... |
@aquette I am curious if this is the best use of our time (both development and testing). libusb-1.0 is designed to overcome API issues relating to asynchronous calls (NUT operates synchronously, in a single thread), and to add support for USB 2.0+ features (Remember that most UPSes are USB 1.x, and many are 1.5 MBit/sec). If nothing else, this sounds like an excellent use case for libusb-compat, which is not marked deprecated, just that the 0.1 API is not recommended for new code. If we are going to require users to test their setup again, let's at least make it worth their time. |
@jblachly not sure how illumos does their package mirroring, but for future reference, the upstream source is at SourceForge and Debian keeps mirrors of the tarballs that go into their packages. |
@jimklimov you may be able to shed some light on the Illumos package for libusb 0.1... |
@jblachly @aquette : I should start by reminding that "illumos" is not an OS by itself, but rather a kernel and some basic tooling. Things like libusb are part of userland which comes (or not) with specific distributions, of which there are a dozen or so. I mostly work with OpenIndiana (and its bleeding-edge Hipster subproject), which currently has recipes mostly from back in 2012, for versions 0.1.8 of libusb-wrapper and libusb-ugen, with sources for both coming from http://libusb.sf.net/ - see https://github.com/OpenIndiana/oi-userland/tree/oi/hipster/components/libusb/ugen and https://github.com/OpenIndiana/oi-userland/tree/oi/hipster/components/libusb/wrapper . As I see on an OmniOS Bloody box, they have I believe both of these sets of packages/recipes can plausibly date back to Sun OpenSolaris packaging ( |
I don't think libusb-compat is in the debian archive |
@jimklimov I am working on SmartOS, but more importantly I am going to put some effort into the illumos kernel USB drivers in the area of HID-power. As you know, illumos recognizes HID-power class USB devices as "hid", but illumos' / opensolaris usba driver My earlier comment about "locating the source" referred not to getting nut installed (SmartOS and pkgsrc 'nut' package got everything installed no problem) , but rather when trying to track down why nut didn't work for me (the problem being of course with the Anyway, please let me know if I can help in any way, and thanks everyone for working on NUT. |
@jblachly having worked / assisted / contributed to ugen on Solaris with the developer (Jan Van Bruen), back in the early 2000, and also on the Linux kernel implementation, I can help. But I don't think this effort is worth. As for NUT, most USB (and HID) userland implementation just needs a generic USB access, and implement HID support on their own. Otherwise, take a look at libhid and similar userland efforts. Moreover, HID kernel support tends to be overweighted. |
worklog on the port: I've committed the configure checks: Configuration summary:... Actual implementation for the 1.0 backend underway... stay tuned. |
@aquette Thanks -- Perhaps best solution is to ensure that HID-Power class devices get the |
@jblachly: indeed, that would be optimal... but not sufficient. NUT has support for USB/HID PDC (power device class) and also for XCP, Qx, and more (drivers: bcmxcp_usb, blazer_usb, nutdrv_atcl_usb, richcomm_usb, riello_usb, tripplite_usb, nutdrv_qx) worklog on the port: usbhid-ups port complete (available on the https://github.com/networkupstools/nut/tree/libusb-1.0 branch). |
Worklog tracker
|
@aquette please remember to update Makefile.am when adding/renaming files.
http://buildbot.networkupstools.org/public/nut/waterfall?branch=libusb-1.0
|
indeed @clepple , thx for pointing ;) |
all, |
@cleppe: I've completely missed your comment on "the use of our time". I indeed think that switching to libusb 1.0 (not compat, which can't be marked as deprecated, since part of libusb 1.0) is a good thing. Even if we're not using isochronous endpoint, 1.0 is the way forward, and as you saw in the commit list, the port was not a huge deal. This will ease some integration, esp. on Windows and probably some BSD too (inc. Darwin). So we're now ready for the future, on the USB front... |
@aquette there may not have been much to commit, but there is a lot to test, and we can't simulate all of the USB error conditions that users may encounter. I am still not sure this is a big win for users. On OS X, we still have the same problem with USB HID devices: libusb-style access competes with the HID driver. BSD has had a problematic mix of libusb 0.1 and 1.0 APIs, and again, error conditions have been just different enough to cause problems. And I am not sure that moving to libusb 1.0 automatically solves the USB access problem on Windows (though I would like to be proven wrong on that front). Let's not rush the 2.7.5 release. This will need a lot of testing. |
@aquette can you please check on this? might only be needed for libusb-0.1. ../../../drivers/libusb1.c:70:19: warning: unused function 'typesafe_control_msg' [-Wunused-function] |
@aquette I commented over on the libusb1.c patch, but it isn't showing up here. Slightly updated:
Reference: https://www.freebsd.org/cgi/man.cgi?format=html&query=libusb(3) |
|
libusb 1.0 has introduced a new function (libusb_set_auto_detach_kernel_driver), beside from the explicit kernel driver detachment request (libusb_detach_kernel_driver). However, the former is not available on all systems. As an example, FreeBSD 10.1-10.3 does not have this. The detachment and interface claiming has been reworked to handle this case (reported by Charles Lepple) Reference: #300
@aquette the last commit doesn't cover |
@aquette Rather than make the altsetting code only build on libusb-0.1, it should probably use this: http://libusb.sourceforge.net/api-1.0/group__dev.html#ga3047fea29830a56524388fd423068b53 |
@abratchik wrote:
No need to guess: https://www.cs.unm.edu/~hjelmn/libusb_hotplug_api/group__syncio.html#gadb11f7a761bd12fc77a07f4568d56f38
I think Jim was referring to interface number zero here, rather than EP 0, because PR 1044 is about configurable interface numbers. @jimklimov wrote:
https://github.com/libusb/libusb/blob/master/libusb/libusb.h#L594 describes the format of the endpoint number. Something symbolic sounds good. I have no preference on the implementation, though using |
I am not fully sure what I was asking about (vague a bit about terminology and concepts) so risk saying something stupid or misleading, but I saw weirdness in (I think) argument formulations for both endpoints (and some "1" often there) and interfaces. Having all of them referenced in an understandable manner is beneficial :) |
If you see 0x80, that's an IN endpoint number, not an interface number. What the right way to deal with endpoint numbers is depends on the devices involved. Often you can get away with hardcoding endpoint numbers if they never change between device variants. Sometimes it's better to look at the descriptors and identify the endpoints by their position inside an interface, which itself can be identified by index or by its class or in some other way.
That's IN endpoint 1.
Same, IN endpoint 1 (which must be of interrupt type in this case). The 8 later is the buffer length and 1000 is a timeout.
This is actually wrong; USB_ENDPOINT_IN should be equal to 0x80. It should be (note that IN 1 (0x81) and OUT 1 (0x01) are distinct, separate endpoints)
Same story again, IN endpoint 1, length 8, timeout 1000.
In this case the HID input endpoint is, presumably, dynamically determined based on descriptors or some other way, so it comes from a structure, but it presumably lacks the IN bit so that gets added here (ORed would be more appropriate though).
I'm pretty sure the libusb0 code is written incorrectly (but works by accident). The prototype for that function is:
So the first parameter is the request type. But
That's a length.
The 0x81 stuff can be replaced with
Which makes it clear that these are hardcoded endpoint numbers for that given device. Addition should almost always be a logical OR instead; it doesn't make a difference for combining bitfields, but addition will break if e.g. one component already had the IN bit set, and OR is more idiomatic.
Endpoint zero is magical and used for control transfers almost always (and nothing else). For simple devices with only two data endpoints, those are often going to be either IN 1 (0x81) and OUT 1 (0x01), or something like IN 1 (0x81) and OUT 2 (0x02) (some devices prefer to use separate endpoint numbers for IN/OUT; this could be a USB device controller hardware limitation, or just caused by confused embedded engineers thinking they can't do that even though it's fully allowed). For a device with one interface, they would be part of interface 0, and you can usually get away with hardcoding them in that case. Devices with multiple interfaces though could end up having endpoint numbers change between device revisions / hardware; in that case it's a better idea to get the endpoint numbers from the interface descriptor. HID is a particularly special case, because it's a standard and often implemented alongside other things. Since many devices implement HID, you can't hardcode interface or endpoint numbers. The correct way to do this is to look through all interface descriptors and find the one that claims to have the HID class; then use that interface number and get the endpoint descriptors from that interface descriptor. That way you don't have to hardcode anything for specific devices. |
Thanks a lot for great details, should help us laymen understand the context... Would any PRs from you be possible to rectify this "correctly"? ;) |
After the recent merge of master into #1184, the installation instructions in #300 (comment) seem still valid, while little adjustments were needed here on a supposedly more blank Ubuntu system to reach the end:
The service is running and no broadcast messages about lost Communications were displayed again up to this point. Will return and update here, in case that happens again. |
Further working to converge the candidate libusb-1.0(+0.1) branches to get one of them merged into master, I realized that indeed libusb-1.0+0.1 is a superset of "plain" libusb-1.0, and beside some fixes applied in C code (xmalloc/xstrdup mostly), they differed in configure.ac and m4 included code to enable libusb-1.0 (or allow choosing the implementation). I proceeded currently with additional branches https://github.com/networkupstools/nut/tree/fightwarn-libusb-1.0+0.1 and https://github.com/networkupstools/nut/tree/fightwarn-libusb-1.0 to minimize the "non-functional differences" of the two branches (in particular, using the same M4 code for configure script now), and to proceed with the "Fightwarn effort" started a year ago with #823 - to have to code build cleanly without warnings, iterating to survive more and more warnings enabled. The latter is important, to allow for peace of mind when we add new features and refactor old bugs, to know that we did not introduce regressions for some platform and tool/language revision. To this effect, the latest changes I applied to those two efforts are a bit questionable to myself, but still seem the most reasonable way forward for the fightwarn effort and even for the goal of cleanly gaining libusb-1.0+0.1 in master as well. Namely, with our closely-related implementations for libusb0, libusb1, libshut, libhid and hidparser sources, we juggle more or less the same logical content all with different integer and pointer types as dictated by this or that backend. Some of those libraries were already converged to size_t and similar standard types during the past year of fightwarn, but for others trying to do so caused an explosion of issued warnings about inconsistent use of the types. Eventually the easiest way to complete the fightwarn-medium level for a confident NUT 2.7.5 release was to revive the libusb1.0 integration (otherwise tentatively delayed to 2.7.6) because it had introduced an abstraction for "usb_ctrl_char" type, and to build up from that - typedef'ing other typical arguments of the USB API and peppering the code with range-checked casts to those names. This way, at least as long as each driver is ultimately built into a single binary (no shared objects involved to mix the ABIs) - maybe starting with same sources (and different macro settings via Makefiles and configure script results), but using different object files where appropriate (e.g. SHUT vs USB builds of otherwise mostly-same drivers), each such built codepath uses the types of the respective backend API either "natively" or safely cast, with no compiler warnings in the end. In fact, this seems like a good stepping stone toward a more reasonable implementation - with NUT code defining and using some same standard integer types for these values (probably picking some "least common denominator" for the native backend APIs and ultimately wire protocols, using uint8_t, uint16_t, uint32_t, size_t etc. and adding more range-checked casts where appropriate in the libraries) so the ultimate consumer code in the actual drivers would not have to bother about the typedefs and their value ranges, but would use the C-standard numeric types and allow shared objects and compatible ABIs. But now that goal can be achieved separately (and maybe in another release), by redefining these typedefs to same tokens and making the codebase variants build and work with that new definition. Another separate effort would be to revise and reword the "magic 0x81" and bit maths, detailed in a few recent comments above. Perhaps one large last thing to take care of before landing these changes into master is to check that these "rather theoretical" codebase fixes did not break functionality in practice! So whoever can test https://github.com/networkupstools/nut/tree/fightwarn-libusb-1.0+0.1 with their USB and/or SHUT devices using various libusb versions - please do so and chime back here :) |
Hm, auto-close was not anticipated... but more or less matches reality - the branches were merged... |
Removed dependency to host-perl, not needed anymore after networkupstools/nut@3f7d050 Removed autoreconf, the tarball provided by upstream contains a configure script. This configure script however adds /usr/local/include to some tests which fail for us, instead of patching configure.ac and going through the autoreconf nightmare again we patch the configure script directly. Added configure option --without-doc Added more autoreconf variables to fix cross-compile issues. Changed "--with-drivers=all" to "--with-drivers=auto" because some new drivers need packages not provided by buildroot, for example: configure: error: Powerman client libraries not found, required for Powerman PDU client driver Added optional dependency to freeipmi. Added optional dependency to libusb, for details see networkupstools/nut#300 Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Hi,
nut currently uses libusb 0.1 which is deprecated for quite some time. Nut should be ported to libusb 1.0
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=810449
The text was updated successfully, but these errors were encountered: