-
Notifications
You must be signed in to change notification settings - Fork 425
Add hidraw backend for FreeBSD #730
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
base: master
Are you sure you want to change the base?
Conversation
Currently, some stuff like the Report Descriptor parser and error registry routine are copied from Linux and I think they are platform independent. Can we create a common directory or hidraw directory in code then put them inside? Have tested by the hidtest program. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No more comments
49a7a62
to
6e7a25a
Compare
Thanks for @Youw your review:). Then, What is your opinion about this?
|
I thinjk that is a good idea, but I don't think it really is nesessary to do so in scope of this PR. |
Nice. This will address the following issue. |
Oops. I forget we have udev-devd stuff. Maybe we should use udev also? |
I lost context here. What for? Seem like you have all the functionality implemented already. Aren't you? |
Yes, all functionality is fully implemented. I am just thinking if we should use libudev make hidapi more portable. |
First test under FreeBSD 14.1 Release, under a physical machine (Chuwi mini PC, Intel J4125 CPU, 8GB RAM, 256GB SSD) There are a few compiler warnings.
|
Fix it:). Forget to fix the warning. |
Somehow hidtest-hidraw will seg fault with the Microchip Simple HID example.
|
Thanks. The compiler warnings are gone. The Segfault issue is still there though. |
Somehow it still does not work.
|
return -1; | ||
} | ||
|
||
bytes_written = write(dev->device_handle, data, length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strip leading zero for unnumbered reports. See write
section of FreeBSD hidraw(4) man.
Don't forget to account for this byte in return value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HIDRAW_GET_REPORT and HIDRAW_SET_REPORT callers should strip leading zero for unnumbered reports too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wulf7 are you sure?
I believe this entire implementation should be about hidraw
, not uhid
, and according to https://man.freebsd.org/cgi/man.cgi?hidraw(4)
In the hidraw mode, the first byte should be set to 0 and the report data itself should begin at the second byte.
I.e. - no strip.
if (hid_get_name_from_mib(mib, items, name_buffer, sizeof(name_buffer)) == 0) | ||
return -1; | ||
|
||
return sscanf(name_buffer, "dev.hidraw.%d", &result) == 1 ? result : -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you may add "dev.uhid.%d" nodes here too as they are compatible with hidraw(4) in uhid mode on binary level.
Sorry about the confusing code. I would like to clarify first that I think using hidraw mode is better for supporting non-usb hid device (e.g. iichid). I clean up the code so that there is hidraw mode only. |
uhid mode supports non-USB HID devices too. Both modes are comparable. |
If they are compatible, then what point of using both? HIDAPI is intended to be as thin wrapper as possible for HID device drivers (libusb backend is a different story, of course), with uniform API across platforms. Do I miss something about uhid worth mentioning in this scope? |
They are comparable but not compatible. uhid API may be used with old uhid(4) driver. FreeBSD hidraw(4) supports both. Choose one you prefer but do not mix them. |
Now after switching to hidraw mode, it is better to replace all remaining HIDRAW_* ioctls with HIDIOC* ones. |
Ooops. FreeBSD hidraw API is outdated. It misses HIDIOCSOUTPUT and HIDIOCGINPUT ioctls. |
Hmm, what about FreeBSD 15.0-Current? Does it have the two IOCTLs you mentioned? @aokblast is indeed using FreeBSD 15.0-Current for testing. |
Not yet. I made a patch with both ioctls(). It is only compile tested. I'll commit after one has tested it. |
The IOCTLs have been added to FreeBSD on 27-April-2025.
|
Can I do it seperately? I think it needs some version check code to enable it. BTW, thought I don't buy the chip you have, I found 1 stm32f103 in my bedroom yesterday. Then I try to reproduce your environment. I have the following questions: Is the wMaxPacket under 64bytes with multiple transport of blocks or wMaxPacket > 64? Is your condition as following?
If so, I can reproduce it throught stm32f103 as I set the Input Descriptor to 1023 bytes. Or
|
Also, they have been merged to 14-STABLE today. |
Yes. That can be another follow-up PR.
Yes, STM32 MCU is a good one to use.
No matter the wMaxPacket number, but rather the HID report length (Input report or Output report in my test, not so sure about Feature report). BTW, my device is a high speed USB device (Cypress EZ-USB FX2LP). But it does not matter.
HID report length greater than 64 bytes will cause issus to this PR. The current libusb backend also got the issue. I am using hidapitester to carry out the test so it is not that easy to differentiate the two cases you mentioned. In any case, it is good that you can at least reproduce the issue (first case). You can also try to change 1023 to something like 80, 128 or 512 to see if the issue still exist. Then you can try to debug the issue to see if it is related to FreeBSD hidraw implementation or your PR. |
FreeBSD support hidraw in Kernel from 13.0. By using libusb only, we can only see the HID device from usb. To address this, we implement hidraw backend for FreeBSD. Just like Linux use libudev to handle usb specified HID stuff (like Manufacture), we use libusb to handle it. Sponsored-by: FreeBSD Foundation Sponsored-by: Framework Laptop. Inc
Oops, I thought you are using FULL speed device (64byte packets) with hid descriptor larger than 64byte. That is why I ask you what is the value of wMaxPakcet. Because I though you are using an device unable to configure from stm32cubemx(If you type you want to configure packet size higher than 64, you needs to be the HIGH speed device) So you are using the HIGH speed? If so, I needs extra hardware to test it. HIGH speed needs MCU have clock higher than 120Mhz. It is impossible for stm32f103. I am trying to find an available stm32f405 to test it. In the current modification, I support HIDIOC family ioctl for all and use ifdef to provide backward support, you can test it with the new 14-STABLE or 15-CURRENT but I thought they will have the same result. Besides, I make hidtest compiles hidtest_hidraw and hidtest_libusb. |
My FW is based on this one, with Cypress EZ-USB FX2LP. USB Descriptors
Full source codes and binaries: |
Using FreeBSD 15 Current snapshot 1-May-2025. So we can see that the hidraw backend does not work from this PR. But at least it does not have regression on the libusb backend since the problem is the same as current hidapi git in terms of libusb backend.
|
Now I am clean of the fault, it is the same as what you see. No timeout, immediately exit.
|
Ok, I see. I should take some time to get a device able to afford USB HIGH speed |
Are you saying that you no longer have issuses with your own full speed STM32 MCU implementation if the HID Input/Output report length are larger than 64 Bytes? Or you still have the issue? If possible, please post the USB descriptors of your device and the test results. Thanks. |
More about the test device.
|
Forcing the device to run in Full Speed mode and now this PR works.
|
@aokblast @wulf7 |
Yes, hid full speed with larger than 64 byte report works. Code and result:
usbconfig -d0.3 dump_all_desc:
Report Descriptor: |
FreeBSD support hidraw in Kernel from 13.0.
By using libusb only, we can only see the HID device from usb. To address this, we implement hidraw backend for FreeBSD.
Just like Linux use libudev to handle usb specified HID stuff (like Manufacture), we use libusb to handle it.
Sponsored-by: FreeBSD Foundation