Skip to content

Add hidraw backend for FreeBSD#730

Open
aokblast wants to merge 4 commits intolibusb:masterfrom
aokblast:use_hid_raw
Open

Add hidraw backend for FreeBSD#730
aokblast wants to merge 4 commits intolibusb:masterfrom
aokblast:use_hid_raw

Conversation

@aokblast
Copy link
Copy Markdown

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

@aokblast
Copy link
Copy Markdown
Author

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.

@Youw Youw self-requested a review March 27, 2025 10:33
@Youw Youw added enhancement New feature or request bsd FreeBSD, NetBSD, OpenBSD, etc labels Mar 27, 2025
Comment thread freebsd/Makefile-manual
Comment thread libusb/Makefile.in Outdated
Comment thread src/CMakeLists.txt Outdated
Comment thread freebsd/CMakeLists.txt Outdated
Comment thread freebsd/hid.c Outdated
Comment thread freebsd/hid.c Outdated
Comment thread freebsd/hid.c Outdated
Copy link
Copy Markdown
Member

@Youw Youw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No more comments

@aokblast aokblast force-pushed the use_hid_raw branch 4 times, most recently from 49a7a62 to 6e7a25a Compare March 27, 2025 14:16
@aokblast
Copy link
Copy Markdown
Author

Thanks for @Youw your review:).

Then, What is your opinion about this?

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.

@Youw
Copy link
Copy Markdown
Member

Youw commented Mar 27, 2025

Thanks for @Youw your review:).

Then, What is your opinion about this?

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.

I thinjk that is a good idea, but I don't think it really is nesessary to do so in scope of this PR.
There are really lots of stuff which I'd like to share among beckends, and I think it is going to be some refactoring after all.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Mar 28, 2025

Nice. This will address the following issue.

@aokblast
Copy link
Copy Markdown
Author

Oops. I forget we have udev-devd stuff. Maybe we should use udev also?

@Youw
Copy link
Copy Markdown
Member

Youw commented Mar 28, 2025

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?

@aokblast
Copy link
Copy Markdown
Author

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.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Mar 30, 2025

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.

mcuee@freebsd14:~/build/hidapi_pr730 $ uname -a
FreeBSD freebsd14 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64

mcuee@freebsd14:~/build/hidapi_pr730 $ cc -v
FreeBSD clang version 18.1.5 (https://github.com/llvm/llvm-project.git llvmorg-18.1.5-0-g617a15a9eac9)
Target: x86_64-unknown-freebsd14.1
Thread model: posix
InstalledDir: /usr/bin

mcuee@freebsd14:~/build/hidapi_pr730 $ make
make  all-recursive
Making all in freebsd
  CC       hid.lo
hid.c:396:24: warning: passing 'uint8_t[255]' (aka 'unsigned char[255]') to parameter of type 'const char *' converts between pointers to integer types where one is of the unique plain 'char' type and the other is not [-Wpointer-sign]
  396 |                 mbstowcs(namebuffer, buffer, sizeof(namebuffer));
      |                                      ^~~~~~
/usr/include/stdlib.h:107:64: note: passing argument to parameter here
  107 | size_t   mbstowcs(wchar_t * __restrict , const char * __restrict, size_t);
      |                                                                 ^
hid.c:603:1: warning: non-void function does not return a value [-Wreturn-type]
  603 | }
      | ^
hid.c:937:7: warning: passing 'const char *' to parameter of type 'void *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
  937 |         free(dev->device_path);
      |              ^~~~~~~~~~~~~~~~
/usr/include/stdlib.h:101:18: note: passing argument to parameter here
  101 | void     free(void *);
      |                     ^
3 warnings generated.
  CCLD     libhidapi-hidraw.la
Making all in libusb
  CC       hid.lo
  CCLD     libhidapi-libusb.la
Making all in hidtest
  CC       test.o
  CCLD     hidtest-libusb
  CCLD     hidtest-hidraw

@aokblast
Copy link
Copy Markdown
Author

Fix it:). Forget to fix the warning.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Mar 30, 2025

Somehow hidtest-hidraw will seg fault with the Microchip Simple HID example.

mcuee@freebsd14:~/build/hidapi_pr730 $ sudo ./hidtest/hidtest-hidraw
hidapi test/example tool. Compiled with hidapi version 0.15.0, runtime version 0.15.0.
Compile-time version matches runtime version of hidapi.

Segmentation fault
mcuee@freebsd14:~/build/hidapi_pr730 $ sudo ./hidtest/hidtest-libusb
hidapi test/example tool. Compiled with hidapi version 0.15.0, runtime version 0.15.0.
Compile-time version matches runtime version of hidapi.

Device Found
  type: 04f2 0760
  path: 0-3:1.0
  serial_number: (null)
  Manufacturer: Chicony
  Product:      USB Keyboard
  Release:      100
  Interface:    0
  Usage (page): 0x0 (0x0)
  Bus type: 1 (USB)

  Report Descriptor: (65 bytes)
0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0, 
0x29, 0xe7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 
0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x03, 
0x75, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x91, 0x02, 
0x95, 0x05, 0x75, 0x01, 0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 
0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 0x07, 0x19, 0x00, 0x2a, 
0xff, 0x00, 0x81, 0x00, 0xc0, 
Device Found
  type: 04f2 0760
  path: 0-3:1.1
  serial_number: (null)
  Manufacturer: Chicony
  Product:      USB Keyboard
  Release:      100
  Interface:    1
  Usage (page): 0x0 (0x0)
  Bus type: 1 (USB)

  Report Descriptor: (127 bytes)
0x06, 0x01, 0x00, 0x09, 0x80, 0xa1, 0x01, 0x85, 0x01, 0x19, 
0x81, 0x29, 0x83, 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 
0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01, 0xc0, 
0x05, 0x0c, 0x09, 0x01, 0xa1, 0x01, 0x85, 0x03, 0x15, 0x00, 
0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x19, 0xb5, 0x29, 0xb8, 
0x09, 0xcd, 0x09, 0xe2, 0x09, 0xe9, 0x09, 0xea, 0x81, 0x02, 
0x0a, 0x83, 0x01, 0x0a, 0x8a, 0x01, 0x0a, 0x92, 0x01, 0x0a, 
0x94, 0x01, 0x0a, 0x21, 0x02, 0x1a, 0x23, 0x02, 0x2a, 0x25, 
0x02, 0x81, 0x02, 0x0a, 0x26, 0x02, 0x0a, 0x27, 0x02, 0x0a, 
0x2a, 0x02, 0x95, 0x03, 0x81, 0x02, 0x95, 0x05, 0x81, 0x01, 
0xc0, 0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x85, 0x02, 
0x25, 0x01, 0x15, 0x00, 0x75, 0x01, 0x95, 0x08, 0x1a, 0xf1, 
0x00, 0x2a, 0xf8, 0x00, 0x81, 0x02, 0xc0, 
Device Found
  type: 1ea7 0064
  path: 0-4:1.0
  serial_number: (null)
  Manufacturer: (null)
  Product:      2.4G Mouse
  Release:      200
  Interface:    0
  Usage (page): 0x0 (0x0)
  Bus type: 1 (USB)

  Report Descriptor: (105 bytes)
0x06, 0xb5, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x85, 0xb5, 0x09, 
0x02, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x07, 
0x81, 0x02, 0x09, 0x02, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 
0x08, 0x95, 0x07, 0x91, 0x02, 0xc0, 0x05, 0x01, 0x09, 0x02, 
0xa1, 0x01, 0x85, 0x02, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 
0x19, 0x01, 0x29, 0x08, 0x15, 0x00, 0x25, 0x01, 0x95, 0x08, 
0x75, 0x01, 0x81, 0x02, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 
0x16, 0x01, 0xf8, 0x26, 0xff, 0x07, 0x75, 0x0c, 0x95, 0x02, 
0x81, 0x06, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 
0x95, 0x01, 0x81, 0x06, 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x95, 
0x01, 0x81, 0x06, 0xc0, 0xc0, 
Device Found
  type: 04d8 003f
  path: 0-2:1.0
  serial_number: (null)
  Manufacturer: Microchip Technology Inc.
  Product:      Simple HID Device Demo
  Release:      2
  Interface:    0
  Usage (page): 0x0 (0x0)
  Bus type: 1 (USB)

  Report Descriptor: (28 bytes)
0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x19, 0x01, 0x29, 
0x40, 0x15, 0x01, 0x25, 0x40, 0x75, 0x08, 0x95, 0x40, 0x81, 
0x00, 0x19, 0x01, 0x29, 0x40, 0x91, 0x00, 0xc0, 
Manufacturer String: Microchip Technology Inc.
Product String: Simple HID Device Demo
Unable to read serial number string
Serial Number String: (0) 
  Report Descriptor: (28 bytes)
0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x19, 0x01, 0x29, 
0x40, 0x15, 0x01, 0x25, 0x40, 0x75, 0x08, 0x95, 0x40, 0x81, 
0x00, 0x19, 0x01, 0x29, 0x40, 0x91, 0x00, 0xc0, 
Device Found
  type: 04d8 003f
  path: 0-2:1.0
  serial_number: (null)
  Manufacturer: Microchip Technology Inc.
  Product:      Simple HID Device Demo
  Release:      2
  Interface:    0
  Usage (page): 0x1 (0xff00)
  Bus type: 1 (USB)

Indexed String 1: Microchip Technology Inc.
Unable to send a feature report: hid_error is not implemented yet
Unable to get a feature report: hid_error is not implemented yet
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
read() timeout

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Mar 30, 2025

Fix it:). Forget to fix the warning.

Thanks. The compiler warnings are gone.

The Segfault issue is still there though.

@aokblast
Copy link
Copy Markdown
Author

@aokblast

Just wondering if you have any updates on this PR. Thanks.

Sorry that I was super busy in previous 6 months. I am back now and will start to setup the hardware for usb development on next monday.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new FreeBSD HIDRAW backend to HIDAPI so FreeBSD (13.0+) can enumerate and access HID devices via /dev/hidraw*, while still leveraging libusb for USB-specific metadata (e.g., manufacturer string).

Changes:

  • Introduce a new freebsd/ backend implementation (hid.c) and integrate it into both CMake and Autotools builds.
  • Update build/test targets to build both hidraw and libusb variants on FreeBSD (hidtest + testgui).
  • Adjust FreeBSD libusb build artifacts naming to match the -libusb convention.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 18 comments.

Show a summary per file
File Description
testgui/Makefile.am Build FreeBSD testgui against both freebsd hidraw and libusb backends.
src/CMakeLists.txt Add FreeBSD platform branch to build/export the hidraw backend from freebsd/.
libusb/Makefile.freebsd Rename manual FreeBSD libusb targets to *-libusb naming.
libusb/Makefile.am Rename FreeBSD libusb Automake library target to libhidapi-libusb.la.
hidtest/Makefile.am Build both hidtest-hidraw and hidtest-libusb on FreeBSD.
hidtest/CMakeLists.txt Enable building hidtest_hidraw on FreeBSD when hidapi::hidraw exists.
freebsd/hid.c New FreeBSD hidraw backend implementation (enumeration, IO, descriptors, strings).
freebsd/Makefile.am Automake build for freebsd hidraw library.
freebsd/Makefile-manual Manual makefile to build the FreeBSD hidraw backend.
freebsd/CMakeLists.txt CMake target for FreeBSD hidraw backend and pkg-config generation.
freebsd/.gitignore Ignore build artifacts under freebsd/.
configure.ac Switch FreeBSD Autotools backend to freebsd and add FreeBSD Makefile/config vars.
Makefile.am Add freebsd/ subdir and install FreeBSD pkg-config files for hidraw+libusb.
CMakeLists.txt Add FreeBSD options for building hidraw and libusb implementations.
Comments suppressed due to low confidence (1)

configure.ac:249

  • Autotools config only generates pc/hidapi-hidraw.pc and pc/hidapi-libusb.pc when os == linux, but the top-level Makefile.am now installs those pc files for FreeBSD as well. This will break make/make install on FreeBSD because the .pc files won't be configured/generated. Update this conditional to include FreeBSD (or generate the correct pc files based on OS_FREEBSD).
if test "x$os" = xlinux; then
	AC_CONFIG_FILES([pc/hidapi-hidraw.pc])
	AC_CONFIG_FILES([pc/hidapi-libusb.pc])
else
	AC_CONFIG_FILES([pc/hidapi.pc])
fi

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread freebsd/hid.c Outdated
Comment on lines +506 to +513
hid_get_udev_location_from_hidraw_idx(idx,&bus,
&addr,&info->interface_number);
handler = hid_find_device_handle_by_bus_and_port(bus, addr);
if (!handler)
break;
device = libusb_get_device(handler);
if (libusb_get_device_descriptor(device, &desc)) {
libusb_close(handler);
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the BUS_USB branch, the return value of hid_get_udev_location_from_hidraw_idx() is ignored, but bus/addr are then used even if the lookup failed (they're uninitialized). Also, on libusb_get_device_descriptor() failure the handle is closed but the code continues and uses handler afterward. Check both errors and bail out before using bus/addr or a closed handle.

Suggested change
hid_get_udev_location_from_hidraw_idx(idx,&bus,
&addr,&info->interface_number);
handler = hid_find_device_handle_by_bus_and_port(bus, addr);
if (!handler)
break;
device = libusb_get_device(handler);
if (libusb_get_device_descriptor(device, &desc)) {
libusb_close(handler);
if (hid_get_udev_location_from_hidraw_idx(idx, &bus,
&addr, &info->interface_number) != 0)
break;
handler = hid_find_device_handle_by_bus_and_port(bus, addr);
if (!handler)
break;
device = libusb_get_device(handler);
if (libusb_get_device_descriptor(device, &desc)) {
libusb_close(handler);
break;

Copilot uses AI. Check for mistakes.
Comment thread freebsd/hid.c Outdated
Comment on lines +516 to +520
if (len == 0) {
libusb_close(handler);
break;
}
mbstowcs(namebuffer, (char *)buffer, sizeof(namebuffer));
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libusb_get_string_descriptor_ascii() returns a negative libusb error code on failure, not 0. The current len == 0 check will miss errors. Also, mbstowcs(..., sizeof(namebuffer)) passes a byte count instead of the number of wchar_t elements and can overflow namebuffer. Validate len > 0 and pass the correct element count (and ensure null-termination) before wcsdup().

Suggested change
if (len == 0) {
libusb_close(handler);
break;
}
mbstowcs(namebuffer, (char *)buffer, sizeof(namebuffer));
if (len <= 0) {
libusb_close(handler);
break;
}
if ((size_t) len >= sizeof(buffer))
len = sizeof(buffer) - 1;
buffer[len] = '\0';
{
size_t converted;
size_t namebuffer_len = sizeof(namebuffer) / sizeof(namebuffer[0]);
converted = mbstowcs(namebuffer, (char *)buffer, namebuffer_len - 1);
if (converted == (size_t)-1)
namebuffer[0] = L'\0';
else
namebuffer[converted] = L'\0';
}

Copilot uses AI. Check for mistakes.
Comment thread freebsd/hid.c Outdated
Comment on lines +565 to +577
template = malloc(sizeof(struct hid_device_info));
template->path = strdup(devpath);
template->vendor_id = devinfo.hdi_vendor;
template->product_id = devinfo.hdi_product;
mbstowcs(namebuffer, devinfo.hdi_uniq, sizeof(namebuffer));
template->serial_number = strlen(devinfo.hdi_uniq) ? wcsdup(namebuffer) : NULL;
template->release_number = devinfo.hdi_version;
mbstowcs(namebuffer, devinfo.hdi_name, sizeof(namebuffer));
template->product_string = strlen(devinfo.hdi_name) ? wcsdup(namebuffer) : NULL;
template->interface_number = -1;
template->manufacturer_string = NULL;
template->next = NULL;
hid_device_handle_bus_dependent(&devinfo, template, idx);
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template is allocated with malloc() and then partially initialized. Any fields not explicitly set (e.g., usage_page, usage, bus_type, etc.) remain uninitialized and may be copied later. Prefer calloc() (or memset) and check for allocation failures before dereferencing template.

Copilot uses AI. Check for mistakes.
Comment thread freebsd/hid.c Outdated
Comment on lines +569 to +573
mbstowcs(namebuffer, devinfo.hdi_uniq, sizeof(namebuffer));
template->serial_number = strlen(devinfo.hdi_uniq) ? wcsdup(namebuffer) : NULL;
template->release_number = devinfo.hdi_version;
mbstowcs(namebuffer, devinfo.hdi_name, sizeof(namebuffer));
template->product_string = strlen(devinfo.hdi_name) ? wcsdup(namebuffer) : NULL;
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both mbstowcs(namebuffer, ..., sizeof(namebuffer)) calls pass a byte size instead of the number of wchar_t elements. This can overflow namebuffer (256 elements) because sizeof(namebuffer) is typically 1024 bytes. Use sizeof(namebuffer)/sizeof(namebuffer[0]) (and handle truncation / ensure termination) before wcsdup().

Suggested change
mbstowcs(namebuffer, devinfo.hdi_uniq, sizeof(namebuffer));
template->serial_number = strlen(devinfo.hdi_uniq) ? wcsdup(namebuffer) : NULL;
template->release_number = devinfo.hdi_version;
mbstowcs(namebuffer, devinfo.hdi_name, sizeof(namebuffer));
template->product_string = strlen(devinfo.hdi_name) ? wcsdup(namebuffer) : NULL;
if (strlen(devinfo.hdi_uniq)) {
size_t converted = mbstowcs(namebuffer, devinfo.hdi_uniq,
(sizeof(namebuffer) / sizeof(namebuffer[0])) - 1);
if (converted != (size_t)-1) {
namebuffer[converted] = L'\0';
template->serial_number = wcsdup(namebuffer);
} else {
template->serial_number = NULL;
}
} else {
template->serial_number = NULL;
}
template->release_number = devinfo.hdi_version;
if (strlen(devinfo.hdi_name)) {
size_t converted = mbstowcs(namebuffer, devinfo.hdi_name,
(sizeof(namebuffer) / sizeof(namebuffer[0])) - 1);
if (converted != (size_t)-1) {
namebuffer[converted] = L'\0';
template->product_string = wcsdup(namebuffer);
} else {
template->product_string = NULL;
}
} else {
template->product_string = NULL;
}

Copilot uses AI. Check for mistakes.
Comment thread freebsd/hid.c
Comment on lines +1182 to +1187
if (act_len < buf_size)
buf_size = act_len;

memcpy(buf, desc.value, buf_size);
return buf_size;
}
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hid_get_report_descriptor() returns buf_size (a size_t) from a function returning int. This can trigger warnings and truncation on large descriptors. Follow the pattern used by other backends: clamp to INT_MAX if needed and return (int)buf_size after copying.

Copilot uses AI. Check for mistakes.
Comment thread freebsd/hid.c Outdated
register_global_error_format("Unable to find the device with bus:%2d and addr:%2d", bus, addr);
}

libusb_free_device_list(list, 0);
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libusb_free_device_list(list, 0) does not unref the devices in the list and can leak references. The rest of the codebase uses libusb_free_device_list(..., 1) after enumeration; do the same here.

Suggested change
libusb_free_device_list(list, 0);
libusb_free_device_list(list, 1);

Copilot uses AI. Check for mistakes.
Comment thread freebsd/hid.c
Comment on lines +479 to +483
snprintf(buff, sizeof(buff), "dev.hidbus.%d.%%parent", idx);
len = sizeof(buff);
if (sysctlbyname(buff, buff, &len, NULL, 0))
return 0;
buff[len] = '\0';
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hid_get_udev_location_from_hidraw_idx() writes buff[len] = '\0' after sysctlbyname(). If the returned len equals sizeof(buff), this writes 1 byte past the buffer. Guard len (or ensure null termination by reserving a byte / clamping).

Copilot uses AI. Check for mistakes.
Comment thread freebsd/hid.c
int oid[CTL_MAXNAME] = {0};
size_t buf_len, oid_items = CTL_MAXNAME;
struct hid_sysctl_iter iter;

Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hid_enumerate() doesn't call hid_init(), but the enumeration path can call into libusb (via hid_device_handle_bus_dependent() -> hid_find_device_handle_by_bus_and_port()). Without initializing libusb first, libusb_get_device_list() may fail/behave unexpectedly. Call hid_init() early in hid_enumerate() (as other backends do) and handle/init errors appropriately.

Suggested change
if (hid_init() != 0)
return NULL;

Copilot uses AI. Check for mistakes.
Comment thread freebsd/hid.c Outdated
if (cur_dev->vendor_id == vendor_id &&
cur_dev->product_id == product_id) {
if (serial_number) {
if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a serial_number is provided, wcscmp(serial_number, cur_dev->serial_number) will crash if cur_dev->serial_number is NULL (which can happen when hdi_uniq is empty). Add a null check before calling wcscmp() and only compare when a serial is present.

Suggested change
if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
if (cur_dev->serial_number &&
wcscmp(serial_number, cur_dev->serial_number) == 0) {

Copilot uses AI. Check for mistakes.
Comment thread freebsd/hid.c
@cederom
Copy link
Copy Markdown

cederom commented Apr 19, 2026

@Youw
Just wondering if it is worth asking Github Copilot to review this PR.

Although some reluctance it seems to provide reasonable and constructive review at least there will be some hints :-)

@aokblast
Copy link
Copy Markdown
Author

I don't see any huge change over behavior. The comments from AI are just missing boundary checks.

@aokblast
Copy link
Copy Markdown
Author

Forcing the device to run in Full Speed mode and now this PR works.


mcuee@freebsd15vboxvm:~/build/hidapitester $ sudo usbconfig

ugen0.1: <OHCI root HUB Apple> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=SAVE (0mA)

ugen0.2: <EZ-USB FX2 HID USBHIDIO Lakeview Research> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (80mA)



mcuee@freebsd15vboxvm:~/build/hidapitester $ sudo lsusb

Bus /dev/usb Device /dev/ugen0.2: ID 0925:1234 Lakeview Research 

Bus /dev/usb Device /dev/ugen0.1: ID 0000:0000  



mcuee@freebsd15vboxvm:~/build/hidapitester $ sudo lsusb -vvv -d 0925:1234



Bus /dev/usb Device /dev/ugen0.2: ID 0925:1234 Lakeview Research 

Device Descriptor:

  bLength                18

  bDescriptorType         1

  bcdUSB               1.10

  bDeviceClass            0 (Defined at Interface level)

  bDeviceSubClass         0 

  bDeviceProtocol         0 

  bMaxPacketSize0        64

  idVendor           0x0925 Lakeview Research

  idProduct          0x1234 

  bcdDevice            0.00

  iManufacturer           1 CYPRESS

  iProduct                2 EZ-USB FX2 HID USBHIDIO

  iSerial                 0 

  bNumConfigurations      1

  Configuration Descriptor:

    bLength                 9

    bDescriptorType         2

    wTotalLength           41

    bNumInterfaces          1

    bConfigurationValue     1

    iConfiguration          3 

    bmAttributes         0x80

      (Bus Powered)

    MaxPower               80mA

    Interface Descriptor:

      bLength                 9

      bDescriptorType         4

      bInterfaceNumber        0

      bAlternateSetting       0

      bNumEndpoints           2

      bInterfaceClass         3 Human Interface Device

      bInterfaceSubClass      0 No Subclass

      bInterfaceProtocol      0 None

      iInterface              0 

        HID Device Descriptor:

          bLength                 9

          bDescriptorType        33

          bcdHID               1.10

          bCountryCode            0 Not supported

          bNumDescriptors         1

          bDescriptorType        34 Report

          wDescriptorLength      52

          Report Descriptor: (length is 52)

            Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440

                            (null)

            Item(Local ): Usage, data= [ 0x01 ] 1

                            (null)

            Item(Main  ): Collection, data= [ 0x01 ] 1

                            Application

            Item(Local ): Usage, data= [ 0x02 ] 2

                            (null)

            Item(Main  ): Collection, data= [ 0x00 ] 0

                            Physical

            Item(Global): Usage Page, data= [ 0xa1 0xff ] 65441

                            (null)

            Item(Local ): Usage, data= [ 0x03 ] 3

                            (null)

            Item(Local ): Usage, data= [ 0x04 ] 4

                            (null)

            Item(Global): Logical Minimum, data= [ 0x80 ] 128

            Item(Global): Logical Maximum, data= [ 0x7f ] 127

            Item(Global): Physical Minimum, data= [ 0x00 ] 0

            Item(Global): Physical Maximum, data= [ 0xff ] 255

            Item(Global): Report Size, data= [ 0x08 ] 8

            Item(Global): Report Count, data= [ 0x80 ] 128

            Item(Main  ): Input, data= [ 0x02 ] 2

                            Data Variable Absolute No_Wrap Linear

                            Preferred_State No_Null_Position Non_Volatile Bitfield

            Item(Local ): Usage, data= [ 0x05 ] 5

                            (null)

            Item(Local ): Usage, data= [ 0x06 ] 6

                            (null)

            Item(Global): Logical Minimum, data= [ 0x80 ] 128

            Item(Global): Logical Maximum, data= [ 0x7f ] 127

            Item(Global): Physical Minimum, data= [ 0x00 ] 0

            Item(Global): Physical Maximum, data= [ 0xff ] 255

            Item(Global): Report Size, data= [ 0x08 ] 8

            Item(Global): Report Count, data= [ 0x80 ] 128

            Item(Main  ): Output, data= [ 0x02 ] 2

                            Data Variable Absolute No_Wrap Linear

                            Preferred_State No_Null_Position Non_Volatile Bitfield

            Item(Main  ): End Collection, data=none

            Item(Main  ): End Collection, data=none

      Endpoint Descriptor:

        bLength                 7

        bDescriptorType         5

        bEndpointAddress     0x81  EP 1 IN

        bmAttributes            3

          Transfer Type            Interrupt

          Synch Type               None

          Usage Type               Data

        wMaxPacketSize     0x0040  1x 64 bytes

        bInterval               5

      Endpoint Descriptor:

        bLength                 7

        bDescriptorType         5

        bEndpointAddress     0x01  EP 1 OUT

        bmAttributes            3

          Transfer Type            Interrupt

          Synch Type               None

          Usage Type               Data

        wMaxPacketSize     0x0040  1x 64 bytes

        bInterval               5

Device Status:     0x0002

  (Bus Powered)

  Remote Wakeup Enabled



mcuee@freebsd15vboxvm:~/build/hidapitester $ sudo ./hidapitester_freebsd_libusb_pr730 --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input

Opening device, vid/pid: 0x0925/0x1234

Writing output report of 129-bytes...wrote 129 bytes:

 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F

 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F

 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F

 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F

 80

Reading up to 129-byte input report, 250 msec timeout...read 64 bytes:

 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20

 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40

 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 00

Closing device

mcuee@freebsd15vboxvm:~/build/hidapitester $ sudo ./hidapitester_freebsd_hidraw_pr730 --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input

Opening device, vid/pid: 0x0925/0x1234

Writing output report of 129-bytes...wrote 129 bytes:

 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F

 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F

 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F

 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F

 80

Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:

 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20

 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40

 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60

 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80

 00

Closing device



Hi. I just take a look at this again. Could you please try to make your payload 128bytes?

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 24, 2026

Hi. I just take a look at this again. Could you please try to make your payload 128bytes?

@aokblast

Yes, I will try to carry out some tests over the weekend and report the results from FreeBSD 15.0 release.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Here are the latest test results under FreeBSD 15.0 release.

mcuee@freebsdvm:~/build/hidapitester $ gmake -f Makefile_pr730 clean
rm -f ../hidapi_pr730/freebsd/hid.o hidapitester.o
rm -f hidapitester
mcuee@freebsdvm:~/build/hidapitester $ gmake -f Makefile_pr730
cc -I/usr/local/include -I ../hidapi_pr730/hidapi -DHIDAPITESTER_VERSION=\"""v0.5""\" -c ../hidapi_pr730/freebsd/hid.c -o ../hidapi_pr730/freebsd/hid.o
cc -I/usr/local/include -I ../hidapi_pr730/hidapi -DHIDAPITESTER_VERSION=\"""v0.5""\" -c hidapitester.c -o hidapitester.o
cc -I/usr/local/include -I ../hidapi_pr730/hidapi -DHIDAPITESTER_VERSION=\"""v0.5""\" ../hidapi_pr730/freebsd/hid.o hidapitester.o -o hidapitester -L/usr/local/lib -lusb -liconv -pthread
mcuee@freebsdvm:~/build/hidapitester $ cp ./hidapitester ./hidapitester_pr730_hidraw

mcuee@freebsdvm:~/build/hidapitester $ diff -u Makefile_pr730 Makefile_pr730_libusb
--- Makefile_pr730      2026-04-25 11:50:25.193243000 +0800
+++ Makefile_pr730_libusb       2026-04-25 12:09:01.784542000 +0800
@@ -80,11 +80,11 @@

 endif

-########### FreeBSD (hidraw)
+########### FreeBSD (libusb)
 ifeq "$(OS)" "freebsd"

 CFLAGS += -I/usr/local/include
-OBJS = $(HIDAPI_DIR)/freebsd/hid.o
+OBJS = $(HIDAPI_DIR)/libusb/hid.o
 LIBS += -L/usr/local/lib -lusb -liconv -pthread
 EXE=

mcuee@freebsdvm:~/build/hidapitester $ gmake -f Makefile_pr730_libusb clean
rm -f ../hidapi_pr730/libusb/hid.o hidapitester.o
rm -f hidapitester
mcuee@freebsdvm:~/build/hidapitester $ gmake -f Makefile_pr730_libusb
cc -I/usr/local/include -I ../hidapi_pr730/hidapi -DHIDAPITESTER_VERSION=\"""v0.5""\" -c ../hidapi_pr730/libusb/hid.c -o ../hidapi_pr730/libusb/hid.o
cc -I/usr/local/include -I ../hidapi_pr730/hidapi -DHIDAPITESTER_VERSION=\"""v0.5""\" -c hidapitester.c -o hidapitester.o
cc -I/usr/local/include -I ../hidapi_pr730/hidapi -DHIDAPITESTER_VERSION=\"""v0.5""\" ../hidapi_pr730/libusb/hid.o hidapitester.o -o hidapitester -L/usr/local/lib -lusb -liconv -pthread
mcuee@freebsdvm:~/build/hidapitester $ cp hidapitester hidapitester_pr730_libusb

mcuee@freebsdvm:~/build/hidapitester $ uname -a
FreeBSD freebsdvm 15.0-RELEASE-p4 FreeBSD 15.0-RELEASE-p4 releng/15.0-n281010-8ef0ed690df2 GENERIC amd64

mcuee@freebsd15vboxvm:~/build/hidapitester $ sudo sysctl hw.usb.usbhid.enable=1
Password:
hw.usb.usbhid.enable: 0 -> 1

mcuee@freebsd15vboxvm:~/build/hidapitester $ sudo kldunload uhid

mcuee@freebsdvm:~/build/hidapitester $ sudo kldload hidraw

mcuee@freebsdvm:~/build/hidapitester $ ls -la /dev/hidraw0
crw-------  1 root operator 0x66 Apr 25 11:52 /dev/hidraw0

mcuee@freebsdvm:~/build/hidapitester $ sudo chmod 666 /dev/hidraw0

mcuee@freebsdvm:~/build/hidapitester $ ./hidapitester_pr730_hidraw --list
0925/1234: (null) - CYPRESS EZ-USB FX2 HID USBHIDIO
mcuee@freebsdvm:~/build/hidapitester $ ./hidapitester_pr730_hidraw --vidpid 0925:1234 --list
0925/1234: (null) - CYPRESS EZ-USB FX2 HID USBHIDIO
mcuee@freebsdvm:~/build/hidapitester $ ./hidapitester_pr730_hidraw --vidpid 0925:1234 --list-detail
0925/1234: (null) - CYPRESS EZ-USB FX2 HID USBHIDIO
  vendorId:      0x0925
  productId:     0x1234
  usagePage:     0xFFA0
  usage:         0x0001
  serial_number: (null)
  interface:     0
  path: /dev/hidraw0

mcuee@freebsdvm:~/build/hidapitester $ sudo usbconfig
ugen1.1: <EHCI root HUB Intel> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.1: <OHCI root HUB Apple> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=SAVE (0mA)
ugen1.2: <EZ-USB FX2 HID USBHIDIO Lakeview Research> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (80mA)

mcuee@freebsdvm:~/build/hidapitester $ sudo lsusb -vvv -d 0925:1234

Bus /dev/usb Device /dev/ugen1.2: ID 0925:1234 Lakeview Research
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x0925 Lakeview Research
  idProduct          0x1234
  bcdDevice            0.00
  iManufacturer           1 CYPRESS
  iProduct                2 EZ-USB FX2 HID USBHIDIO
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          3
    bmAttributes         0x80
      (Bus Powered)
    MaxPower               80mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      52
          Report Descriptor: (length is 52)
            Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
                            (null)
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Local ): Usage, data= [ 0x02 ] 2
                            (null)
            Item(Main  ): Collection, data= [ 0x00 ] 0
                            Physical
            Item(Global): Usage Page, data= [ 0xa1 0xff ] 65441
                            (null)
            Item(Local ): Usage, data= [ 0x03 ] 3
                            (null)
            Item(Local ): Usage, data= [ 0x04 ] 4
                            (null)
            Item(Global): Logical Minimum, data= [ 0x80 ] 128
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x80 ] 128
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x05 ] 5
                            (null)
            Item(Local ): Usage, data= [ 0x06 ] 6
                            (null)
            Item(Global): Logical Minimum, data= [ 0x80 ] 128
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x80 ] 128
            Item(Main  ): Output, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         4
  bNumConfigurations      1
can't get debug descriptor: Input/output error
Device Status:     0x0002
  (Bus Powered)
  Remote Wakeup Enabled

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_git_libusb --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,
9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58
,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,
106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 64 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00
Closing device

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr728_libusb --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,
8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,
58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,10
5,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_libusb --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,
8,9,10
58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,10
5,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 64 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00
Closing device

mcuee@freebsdvm:~/build/hidapitester $ ./hidapitester_pr730_hidraw --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 0 bytes:
Closing device

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Summary of the above test for the EZ-USB FX2LP modified Generic HID example with 128 Bytes report size (high speed USB device).

  1. libusb backend from git (same for PR Add hidraw backend for FreeBSD #730) will only be able to get 64 bytes Input Report. This is a known issue.
  1. PR Properly determine libusb read size for large reports (Fixes #274) #728 fixed the above issue and it is able to read back 128 bytes Input Report
  1. Somehow FreeBSD hidraw backend does not work in this case.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Sanity check under Windows, with latest hidapi git.

PS C:\work\libusb\hidapitester> .\hidapitester_git_winapi.exe --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

PS C:\work\libusb\hidapitester> .\hidapitester_git_libusb.exe --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 64 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00
Closing device

PS C:\work\libusb\hidapitester> .\hidapitester_pr728_libusb_new.exe --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

@aokblast
Copy link
Copy Markdown
Author

Sanity check under Windows, with latest hidapi git.

PS C:\work\libusb\hidapitester> .\hidapitester_git_winapi.exe --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

PS C:\work\libusb\hidapitester> .\hidapitester_git_libusb.exe --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 64 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00
Closing device

PS C:\work\libusb\hidapitester> .\hidapitester_pr728_libusb_new.exe --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

Does output of payload less than 128 bytes work? FreeBSD check if the device can handle the report by checking the size in report descriptor. You report descriptor shows that we can only handle 128 bytes.

@wulf7
Copy link
Copy Markdown

wulf7 commented Apr 25, 2026

Does output of payload less than 128 bytes work? FreeBSD check if the device can handle the report by checking the size in report descriptor. You report descriptor shows that we can only handle 128 bytes.

usbhid allocates internal buffers based on report size. They are 128 bytes long in that case. 129 bytes wont fit them.

There is a difference between input and output unnumbered reports.
In Linux and hidraw after than leading byte of output unnumbered report is stripped so it becomes a 128 byte. But input reports still go AS IS.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Does output of payload less than 128 bytes work? FreeBSD check if the device can handle the report by checking the size in report descriptor. You report descriptor shows that we can only handle 128 bytes.

This is under Linux.

Linux hidraw backend does not work if I send 64 bytes payload.
Linux libusb backend does work if I send 64 bytes payload.

mcuee  ~/build/cypress  16:48  cyusb_linux
QSocketNotifier: Can only be used with threads started with QThread

(cyusb_linux:26002): Gdk-CRITICAL **: 16:48:33.678: gdk_wayland_window_set_dbus_properties_libgtk_only: assertion 'GDK_IS_WAYLAND_WINDOW (window)' failed
Found Hex format file
Releasing FX2 CPU from reset

mcuee  …/hidapitester   main ?    v15.2.0  16:54  sudo ./hidapitester_git_hidraw --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

mcuee  …/hidapitester   main ?    v15.2.0  16:54  sudo ./hidapitester_git_hidraw --vidpid 0925:1234 --open --buflen 256 -l 65 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 65-bytes...wrote 65 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40
Reading up to 65-byte input report, 250 msec timeout...read 0 bytes:
Closing device

mcuee  …/hidapitester   main ?    v15.2.0  16:54  sudo ./hidapitester_git_libusb --vidpid 0925:1234 --open --buflen 256 -l 65 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 65-bytes...wrote 65 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40
Reading up to 65-byte input report, 250 msec timeout...read 64 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 00
Closing device

@wulf7
Copy link
Copy Markdown

wulf7 commented Apr 25, 2026

Ouch. It seems that input is really 128 bytes no 129.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Ouch. It seems that input is really 128 bytes no 129.

That should be the correct one.

The report ID 00 for the output report is not really on the wire. It is more needed because of Windows native HID API.
The report ID 00 is also not on the wire.

@wulf7
Copy link
Copy Markdown

wulf7 commented Apr 25, 2026

Strange. I have just tested FreeBSD hidraw on MBP8,1 with USB touchpad. Touching of surface with all 10 fingers gave me 338bytes packets successfully received.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Strange. I have just tested FreeBSD hidraw on MBP8,1 with USB touchpad. Touching of surface with all 10 fingers gave me 338bytes packets successfully received.

Good one. Do you have any High Speed USB HID device?

As I mentioned before, "forcing the device to run in Full Speed mode and now this PR works". So your device is most likely a Full Speed USB device.

Latest version of VirtualBox does not seem to allow me to disable EHCI support so I can not carry out the test. I am not so sure if I still have working USB 1.1 Hub to try.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

On the other hand, High Speed USB HID device is probably rare. In that case, we may still want to merge this PR first and then debug the issue later.

Maybe it has nothing to do with this PR but rather the hidraw (usbhid driver) of FreeBSD.

@wulf7
Copy link
Copy Markdown

wulf7 commented Apr 25, 2026

Good one. Do you have any High Speed USB HID device?

It is Full Speed device.

@wulf7
Copy link
Copy Markdown

wulf7 commented Apr 25, 2026

Latest version of VirtualBox does not seem to allow me to disable EHCI support so I can not carry out the test. I am not so sure if I still have working USB 1.1 Hub to try.

man ehci tells us about hw.usb.ehci.no_hs loader tunable that disables High Speed.
Try to add hw.usb.ehci.no_hs="1" to /boot/loader.conf and reboot after than

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Going back to original FX2HID example from Jan Axelson, this PR still does not work.
http://janaxelson.com/hidpage.htm
http://janaxelson.com/files/fx2hid.zip
fx2hid.zip

No issues under Windows.

PS C:\work\libusb\hidapitester> .\hidapitester_git_winapi.exe --vidpid 0925:1234 --open --buflen 64 -l 3 --send-output 0,1,2  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
 00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 2 bytes:
 01 02 00
Closing device

No issues under FreeBSD with the libusb backend.

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_libusb --vidpid 0925:1234 --open --buflen 64 -l 3 --send-output 0,1,2  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
 00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 2 bytes:
 01 02 00
Closing device

This PR still does not work.

mcuee@freebsdvm:~/build/hidapitester $ sudo kldload hidraw

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_hidraw --list
0925/1234: CYPRESS - CYPRESS EZ-USB FX2 HID USBHIDIO

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_hidraw --vidpid 0925:1234 --open --buflen 64 -l 3 --send-output 0,1,2  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
 00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 0 bytes:
Closing device

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_hidraw --vidpid 0925:1234 --open --buflen 64 -l 2 --sen
d-output 1,2  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 2-bytes...wrote 2 bytes:
 01 02
Reading up to 2-byte input report, 250 msec timeout...read 0 bytes:
Closing device

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Latest version of VirtualBox does not seem to allow me to disable EHCI support so I can not carry out the test. I am not so sure if I still have working USB 1.1 Hub to try.

man ehci tells us about hw.usb.ehci.no_hs loader tunable that disables High Speed. Try to add hw.usb.ehci.no_hs="1" to /boot/loader.conf and reboot after than

Thanks for the tip. I will try this soon.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

man ehci tells us about hw.usb.ehci.no_hs loader tunable that disables High Speed. Try to add hw.usb.ehci.no_hs="1" to /boot/loader.conf and reboot after than

Somehow this does not work. The device is still enumerated as a high speed USB device.

mcuee@freebsdvm:~/build/hidapitester $ sudo cat /boot/loader.conf
kern.geom.label.disk_ident.enable="0"
kern.geom.label.gptid.enable="0"
zfs_load="YES"
hw.usb.ehci.no_hs="1"

mcuee@freebsdvm:~/build/hidapitester $ sudo reboot
Connection to 127.0.0.1 closed by remote host.
Connection to 127.0.0.1 closed.

PS C:\work> ssh mcuee@127.0.0.1 -p 3224
(mcuee@127.0.0.1) Password for mcuee@freebsdvm:
Last login: Sat Apr 25 19:58:23 2026 from 10.0.2.2
FreeBSD 15.0-RELEASE-p4 (GENERIC) releng/15.0-n281010-8ef0ed690df2

Welcome to FreeBSD!
...
...

mcuee@freebsdvm:~ $ cd build/

mcuee@freebsdvm:~/build $ cd hidapitester/

mcuee@freebsdvm:~/build/hidapitester $ sudo kldload hidraw

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_hidraw --list
0925/1234: CYPRESS - CYPRESS EZ-USB FX2 HID USBHIDIO

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_libusb --vidpid 0925:1234 --open --buflen 64 -l 3 --sen
d-output 0,1,2  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
 00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 2 bytes:
 01 02 00
Closing device

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_hidraw --vidpid 0925:1234 --open --buflen 64 -l 3 --sen
d-output 0,1,2  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
 00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 0 bytes:
Closing device

mcuee@freebsdvm:~/build/hidapitester $ sudo usbconfig list
ugen1.1: <EHCI root HUB Intel> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.1: <OHCI root HUB Apple> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=SAVE (0mA)
ugen1.2: <EZ-USB FX2 HID USBHIDIO Lakeview Research> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (80mA)

Bus /dev/usb Device /dev/ugen1.2: ID 0925:1234 Lakeview Research
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x0925 Lakeview Research
  idProduct          0x1234
  bcdDevice            0.00
  iManufacturer           1 CYPRESS
  iProduct                2 EZ-USB FX2 HID USBHIDIO
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          3
    bmAttributes         0x80
      (Bus Powered)
    MaxPower               80mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      52
          Report Descriptor: (length is 52)
            Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
                            (null)
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Local ): Usage, data= [ 0x02 ] 2
                            (null)
            Item(Main  ): Collection, data= [ 0x00 ] 0
                            Physical
            Item(Global): Usage Page, data= [ 0xa1 0xff ] 65441
                            (null)
            Item(Local ): Usage, data= [ 0x03 ] 3
                            (null)
            Item(Local ): Usage, data= [ 0x04 ] 4
                            (null)
            Item(Global): Logical Minimum, data= [ 0x80 ] 128
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x05 ] 5
                            (null)
            Item(Local ): Usage, data= [ 0x06 ] 6
                            (null)
            Item(Global): Logical Minimum, data= [ 0x80 ] 128
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Main  ): Output, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         4
  bNumConfigurations      1
can't get debug descriptor: Input/output error
Device Status:     0x0002
  (Bus Powered)
  Remote Wakeup Enabled

Bus /dev/usb Device /dev/ugen0.1: ID 0000:0000
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         0 Full speed (or root) hub
  bMaxPacketSize0        64
  idVendor           0x0000
  idProduct          0x0000
  bcdDevice            1.00
  iManufacturer           1 Apple
  iProduct                2 OHCI root HUB
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           25
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x40
      (Missing must-be-set bit!)
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0 Full speed (or root) hub
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval             255
Hub Descriptor:
  bLength              10
  bDescriptorType      41
  nNbrPorts            12
  wHubCharacteristic 0x0002
    No power switching (usb 1.0)
    Ganged overcurrent protection
  bPwrOn2PwrGood        0 * 2 milli seconds
  bHubContrCurrent      0 milli Ampere
  DeviceRemovable    0x00 0x00
  PortPwrCtrlMask    0x00 0x00
 Hub Port Status:
   Port 1: 0000.0100 power
   Port 2: 0000.0100 power
   Port 3: 0000.0100 power
   Port 4: 0000.0100 power
   Port 5: 0000.0100 power
   Port 6: 0000.0100 power
   Port 7: 0000.0100 power
   Port 8: 0000.0100 power
   Port 9: 0000.0100 power
   Port 10: 0000.0100 power
   Port 11: 0000.0100 power
   Port 12: 0000.0100 power
Device Status:     0x0001
  Self Powered

Bus /dev/usb Device /dev/ugen1.1: ID 0000:0000
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         1 Single TT
  bMaxPacketSize0        64
  idVendor           0x0000
  idProduct          0x0000
  bcdDevice            1.00
  iManufacturer           1 Intel
  iProduct                2 EHCI root HUB
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           25
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x40
      (Missing must-be-set bit!)
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0 Full speed (or root) hub
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval             255
Hub Descriptor:
  bLength              10
  bDescriptorType      41
  nNbrPorts            12
  wHubCharacteristic 0x0002
    No power switching (usb 1.0)
    Ganged overcurrent protection
    TT think time 8 FS bits
  bPwrOn2PwrGood      200 * 2 milli seconds
  bHubContrCurrent      0 milli Ampere
  DeviceRemovable    0x00 0x00
  PortPwrCtrlMask    0x00 0x00
 Hub Port Status:
   Port 1: 0000.0501 highspeed power connect
   Port 2: 0000.0500 highspeed power
   Port 3: 0000.0500 highspeed power
   Port 4: 0000.0500 highspeed power
   Port 5: 0000.0500 highspeed power
   Port 6: 0000.0500 highspeed power
   Port 7: 0000.0500 highspeed power
   Port 8: 0000.0500 highspeed power
   Port 9: 0000.0500 highspeed power
   Port 10: 0000.0500 highspeed power
   Port 11: 0000.0500 highspeed power
   Port 12: 0000.0500 highspeed power
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         0 Full speed (or root) hub
  bMaxPacketSize0         0
  bNumConfigurations      0
can't get debug descriptor: Input/output error
Device Status:     0x0001
  Self Powered

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

The following command seems to disable EHCI driver completely, but then somehow I cannot attach the FX2LP USB HID device. Only a generic Atmel STK600 can be attached.

mcuee@freebsdvm:~/build/hidapitester $ sudo cat /boot/loader.conf
kern.geom.label.disk_ident.enable="0"
kern.geom.label.gptid.enable="0"
zfs_load="YES"
hint.ehci.0.disabled="1"
hint.ehci.1.disabled="1"

mcuee@freebsdvm:~/build/hidapitester $ sudo reboot
Connection to 127.0.0.1 closed by remote host.
Connection to 127.0.0.1 closed.

PS C:\work> ssh mcuee@127.0.0.1 -p 3224
(mcuee@127.0.0.1) Password for mcuee@freebsdvm:
Last login: Sat Apr 25 20:26:59 2026 from 10.0.2.2
FreeBSD 15.0-RELEASE-p4 (GENERIC) releng/15.0-n281010-8ef0ed690df2

Welcome to FreeBSD!
...
...
mcuee@freebsdvm:~ $ sudo usbconfig list
ugen0.1: <OHCI root HUB Apple> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=SAVE (0mA)
ugen0.2: <STK600 development board Atmel Corp.> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (500mA)

mcuee@freebsdvm:~ $ sudo dmesg | grep usb
usbus0 on ohci0
usbus0: 12Mbps Full Speed USB v1.0
ugen0.1: <Apple OHCI root HUB> at usbus0
uhub0 on usbus0
uhub0: <Apple OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus0
ugen0.2: <ATMEL STK600> at usbus0

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Okay, this seems to work.

PS C:\Program Files\Oracle\VirtualBox> .\VBoxManage modifyvm "freebsd" --usb-ohci on --usb-ehci off --usb-xhci off

Now it seems to work.

mcuee@freebsdvm:~/build/hidapitester $ sudo usbconfig list
ugen0.1: <OHCI root HUB Apple> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=SAVE (0mA)
ugen0.2: <EZ-USB FX2 HID USBHIDIO Lakeview Research> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (80mA)

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_hidraw --vidpid 0925:1234 --open --buflen 64 -l 3 --send-output 0,1,2  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
 00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 2 bytes:
 01 02 00
Closing device

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_libusb --vidpid 0925:1234 --open --buflen 64 -l 3 --sen
d-output 0,1,2  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 3-bytes...wrote 3 bytes:
 00 01 02
Reading up to 3-byte input report, 250 msec timeout...read 2 bytes:
 01 02 00
Closing device

mcuee@freebsdvm:~/build/hidapitester $ sudo lsusb -d 0925:1234 -vvv

Bus /dev/usb Device /dev/ugen0.2: ID 0925:1234 Lakeview Research
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x0925 Lakeview Research
  idProduct          0x1234
  bcdDevice            0.00
  iManufacturer           1 CYPRESS
  iProduct                2 EZ-USB FX2 HID USBHIDIO
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          3
    bmAttributes         0x80
      (Bus Powered)
    MaxPower               80mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      52
          Report Descriptor: (length is 52)
            Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
                            (null)
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Local ): Usage, data= [ 0x02 ] 2
                            (null)
            Item(Main  ): Collection, data= [ 0x00 ] 0
                            Physical
            Item(Global): Usage Page, data= [ 0xa1 0xff ] 65441
                            (null)
            Item(Local ): Usage, data= [ 0x03 ] 3
                            (null)
            Item(Local ): Usage, data= [ 0x04 ] 4
                            (null)
            Item(Global): Logical Minimum, data= [ 0x80 ] 128
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x05 ] 5
                            (null)
            Item(Local ): Usage, data= [ 0x06 ] 6
                            (null)
            Item(Global): Logical Minimum, data= [ 0x80 ] 128
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Main  ): Output, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
Device Status:     0x0002
  (Bus Powered)
  Remote Wakeup Enabled

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

Going back to the device with HID Input/Output report size of 128 bytes.

It seems to this PR will work fine as well.

Good thing -- PR #728 also works fine.

mcuee@freebsdvm:~/build/hidapitester $ sudo usbconfig list
ugen0.1: <OHCI root HUB Apple> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=SAVE (0mA)
ugen0.2: <EZ-USB FX2 HID USBHIDIO Lakeview Research> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (80mA)
mcuee@freebsdvm:~/build/hidapitester $ sudo lsusb -d 0925:1234 -vvv

Bus /dev/usb Device /dev/ugen0.2: ID 0925:1234 Lakeview Research
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x0925 Lakeview Research
  idProduct          0x1234
  bcdDevice            0.00
  iManufacturer           1 CYPRESS
  iProduct                2 EZ-USB FX2 HID USBHIDIO
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          3
    bmAttributes         0x80
      (Bus Powered)
    MaxPower               80mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      52
          Report Descriptor: (length is 52)
            Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
                            (null)
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Local ): Usage, data= [ 0x02 ] 2
                            (null)
            Item(Main  ): Collection, data= [ 0x00 ] 0
                            Physical
            Item(Global): Usage Page, data= [ 0xa1 0xff ] 65441
                            (null)
            Item(Local ): Usage, data= [ 0x03 ] 3
                            (null)
            Item(Local ): Usage, data= [ 0x04 ] 4
                            (null)
            Item(Global): Logical Minimum, data= [ 0x80 ] 128
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x80 ] 128
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x05 ] 5
                            (null)
            Item(Local ): Usage, data= [ 0x06 ] 6
                            (null)
            Item(Global): Logical Minimum, data= [ 0x80 ] 128
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x80 ] 128
            Item(Main  ): Output, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
Device Status:     0x0002
  (Bus Powered)
  Remote Wakeup Enabled

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr730_hidraw --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

mcuee@freebsdvm:~/build/hidapitester $ sudo ./hidapitester_pr728_libusb --vidpid 0925:1234 --open --buflen 256 -l 129 --
send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,3
9,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,7
9,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,11
4,115
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading up to 129-byte input report, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

@aokblast @wulf7 and @cederom

So basically this PR works with Full Speed USB HID device, but somehow it does not work with High Speed USB HID device. It may not be an issue with this PR, but rather the hidraw driver issue under FreeBSD.

@mcuee
Copy link
Copy Markdown
Member

mcuee commented Apr 25, 2026

@Youw

I am still in favour of merging this PR after your review. The reason is that High Speed USB HID devices are not that common. But you can decide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bsd FreeBSD, NetBSD, OpenBSD, etc enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants