Wednesday, August 11, 2021

Re: libusb1 and Yoctopuce USB sensors

On 2021-08-11, Julian Smith <jules@op59.net> wrote:
> On Mon, 9 Aug 2021 17:35:36 -0000 (UTC)
> Stuart Henderson <stu.lists@spacehopper.org> wrote:
>
>> On 2021-08-08, Julian Smith <jules@op59.net> wrote:
>> > I've been trying to get a yoctopuce (https://www.yoctopuce.com/) USB
>> > sensor to work on OpenBSD, but have run into problems.
>> >
>> > The sensor has Linux code
>> > (https://github.com/yoctopuce/yoctolib_cpp.git) that uses libusb, but
>> > on OpenBSD using the libusb1 package, libusb_kernel_driver_active() and
>> > libusb_detach_kernel_driver() are returning error code -12
>> > (LIBUSB_ERROR_NOT_SUPPORTED).
>> >
>> > I found some rather old advice saying that these errors can be
>> > ignored (https://github.com/apple/cups/issues/4088), but then i get an
>> > error -12 from libusb_submit_transfer().
>>
>> There's no support for detaching a kernel USB driver from userland.
>>
>> If the device is attaching to a driver other than ugen, your first is to
>> prevent that and try again. Devices often attach to uhid(4) and libusb
>> functionality is very limited there. But that's an easy case to work around,
>> there's a UQ_BAD_HID quirk (see /usr/src/sys/dev/usb/usb_quirks.c),
>> you can add an entry using that to prevent the vid/pid of your device
>> from attaching and build a new kernel, it is then likely to end up on
>> ugen(4) and then has a better chance to do what you need.
>
> Many thanks for this, i've set up a separate machine for experimenting,
> and built a new kernel as suggested and it all seems to be working now.
>
> I'm still getting -12 from libusb_kernel_driver_active() and
> libusb_detach_kernel_driver() but then things seem to work ok so for
> example i'm seeing correct-looking CO2 measurements from the device.
>
> Here's the diff:
>
> cvs server: Diffing .
> Index: usb_quirks.c
>===================================================================
> RCS file: /cvs/src/sys/dev/usb/usb_quirks.c,v
> retrieving revision 1.78
> diff -u -p -r1.78 usb_quirks.c
> --- usb_quirks.c 24 Mar 2021 02:49:57 -0000 1.78
> +++ usb_quirks.c 11 Aug 2021 22:43:20 -0000
> @@ -161,6 +161,9 @@ const struct usbd_quirk_entry {
> { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER2,
> ANY, { UQ_ALWAYS_OPEN }},
>
> +/* Yoctopuce. */
> + { 0x24e0, 0x008b, ANY, { UQ_BAD_HID }},
> +
> { 0, 0, 0, { 0 } }
> };
>
> I tried adding Yoctopuce as vendor 0x24e0 and 0x008b as CO2V2 (it
> measures CO2 levels etc) to /usr/src/sys/dev/usb/usbdevs but rebuilding
> the kernel didn't seem to force regeneration of
> /usr/src/sys/dev/usb/usbdevs.h for some reason, hence the direct use of
> 0x24e0 and 0x008b in the above patch.

If you run "make" in sys/dev/usb it will generate usbdevs.h etc from
usbdevs, it's not automated.

> Is the device incorrect when it claims to be a Human Interface Device?
> If so i could maybe contact the manufacture.

No it's not incorrect. OpenBSD only gives partial access to usb devices
attached to uhid via libusb (and IIRC none at all for devices attached to
drivers other than ugen or uhid). Things can go badly if you've got a
kernel device driver and a userland "pseudo-driver" talking to the same
device. And since we don't have a way to detach a device from a driver
on-the-fly like other OS using libusb do, the only way is to knock out
the device from being attached to another kernel driver (either UQ_BAD_HID
for HID class devices, or disabling the driver in the kernel, or modifying
the probe function to skip it).

>> > I notice that 'pkg_info -R libusb1' shows just 9 ports depend on
>> > libusb1, so i'm wondering whether the libusb1 port is expected to work
>> > generally on OpenBSD, or whether it be better to try to use the usb(4)
>> > ioctl API?
>>
>> Many more use it via libusb-compat. Support is limited though and there's
>> some resistance to doing anything to help userland control of USB devices
>> so if it still doesn't work I'd suggest controlling it from another OS
>> unless you fancy writing a kernel driver.
>>
>
> Interesting, do you know of somewhere i can read some more about why
> userland control of USB is not recommended? Now i've managed to get this

There are some very different opinions on this. Some people think it's
better if these are handled by kernel drivers; others think that running
some of this code in the kernel is likely to be risky and maybe userland
is a better idea in cases where there aren't more stringent timing
requirements or high data rates. Anyway it seems unlikely to change.

> simple USB device working, i'm vaguely wondering about looking at
> making a USB terrestrial TV receiver work with Kaffeine on OpenBSD. I
> was hoping that doing this in user space might be easier than writing a
> kernel driver, though i guess the data rate might be too high?

That's an example of something that very likely does want to be
in kernel, partly data rates, partly it would want to interface with
the video(4) subsystem (which provides a reasonably V4L2-compatible
API to userland), partly because from what I've seen when trying to
get rtl-sdr to work in the past doing any real amount of io with
these is likely to need async transfers and that doesn't work with
libusb on openbsd.


--
Please keep replies on the mailing list.

No comments:

Post a Comment