Page MenuHomeFreeBSD

LinuxKPI: usb: de-couple parts from native USB and update implementation
Needs ReviewPublic

Authored by bz on Jan 30 2026, 10:47 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Mar 2, 12:21 PM
Unknown Object (File)
Sun, Mar 1, 4:14 PM
Unknown Object (File)
Sun, Mar 1, 5:54 AM
Unknown Object (File)
Sat, Feb 28, 11:18 PM
Unknown Object (File)
Fri, Feb 20, 1:32 AM
Unknown Object (File)
Thu, Feb 19, 10:28 AM
Unknown Object (File)
Thu, Feb 19, 10:28 AM
Unknown Object (File)
Wed, Feb 18, 3:14 PM
Subscribers

Details

Reviewers
None
Group Reviewers
linuxkpi
USB
Summary

In order to update the LinuxKPI USB implementation and use it with
modern device drivers, such as wireless drivers, we need to embed
LinuxKPI struct device into two USB structs. Doing so in the native
implementation is unfeasible due to dependencies.
Factor out the two structs into an internal name, and then use
an anonymous struct to include it in the actual struct. While in
the native implementation we add a (still conditional) space for
LinuxKPI variables, in LinuxKPI we include the LinuxKPI-specifc
memrber fields from a second struct giving us the same memory layout
on both sides but hiding the actual LinuxKPI fields from the native
implementation entirely.
We use CTASSERT to make sure the array sizes in the native
implementation stay large enough.

Using this update the LinuxKPI USB implementation. It is largely based
on the previous (some parts removed), properly typed, some hacks removed,
and updated forward by 10-15 years. There is also a clear separation
between what is a public KPI and what is internal (helper) code.
URBs are now reference counted, and we populate some dev/kobj bits.

In order to distinguish the change we also move the implementation
from linux_usb.c to linuxkpi_usb.c.

This has been an ongoing (side) effort for several years.
It lacks any kind of review or guidance from a professional USB developer
and has only been undergone basic testing using a LinuxKPI-based wireless
driver, at least passing packets now.

At this point no consumers of the old implementation are still known.
Should there be any we will have to see if bringing back missing
functionality or non-official KPI will help without updating the old
code.

Sponsored by: The FreeBSD Foundation
MFC after: 3 days

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 70261
Build 67144: arc lint + arc unit

Event Timeline

bz requested review of this revision.Jan 30 2026, 10:47 PM

Remove some #if 0 leftovers not properly squashed out.

sys/dev/usb/usbdi.h
187

I beleive this line will currently give a conflict; once D54878 is approved I'll rebase and it should go away.

sys/compat/linuxkpi/common/src/linuxkpi_usb.c
1514

There is a "shutdown" problem somewhere (somewhere in here or in rtw88), which only now started to show up.
I'll be more than happy to debug this but depends on how review goes make it a separate fix.

All buffers synced.  
...                                                     
Uptime: 18h6m24s 
...                                         
rtw880: status -54                                                                                                                                                                                                                                                                                                           
rtw880: status -54                                                                                                                                                                                                                                                                                                           
rtw880: status -54                                                                                                                                                                                                                                                                                                           
wiphy_unregister:1763: XXX LKPI80211 TODO 
rtw880: write register 0x610 failed with -32
rtw880: write register 0x611 failed with -32
rtw880: write register 0x612 failed with -32
rtw880: write register 0x613 failed with -32
rtw880: read register 0x100 failed with -32
rtw880: read register 0x550 failed with -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: read register 0xfe58 failed with -32
rtw880: read register 0x80 failed with -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32
rtw880: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -32


panic: vm_fault_lookup: fault on nofault entry, addr: 0xfffffe00d014e000
cpuid = 3
time = 1769822737
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00b09b3910
vpanic() at vpanic+0x136/frame 0xfffffe00b09b3a40
panic() at panic+0x43/frame 0xfffffe00b09b3aa0
vm_fault() at vm_fault+0x1c0f/frame 0xfffffe00b09b3c20
vm_fault_trap() at vm_fault_trap+0x65/frame 0xfffffe00b09b3c60
trap_pfault() at trap_pfault+0x26a/frame 0xfffffe00b09b3cd0
calltrap() at calltrap+0x8/frame 0xfffffe00b09b3cd0
--- trap 0xc, rip = 0xffffffff8313d515, rsp = 0xfffffe00b09b3da0, rbp = 0xfffffe00b09b3dd0 ---
rtw_usb_read_port_complete() at rtw_usb_read_port_complete+0x15/frame 0xfffffe00b09b3dd0
lkpi_usb_complete() at lkpi_usb_complete+0x30/frame 0xfffffe00b09b3e00
lkpi_usb_non_isoc_callback() at lkpi_usb_non_isoc_callback+0x12d/frame 0xfffffe00b09b3e40
usbd_callback_wrapper() at usbd_callback_wrapper+0x87e/frame 0xfffffe00b09b3e80
usb_command_wrapper() at usb_command_wrapper+0x99/frame 0xfffffe00b09b3ea0
usb_callback_proc() at usb_callback_proc+0x8e/frame 0xfffffe00b09b3ec0
usb_process() at usb_process+0xf0/frame 0xfffffe00b09b3ef0
fork_exit() at fork_exit+0x82/frame 0xfffffe00b09b3f30
fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe00b09b3f30
--- trap 0, rip = 0, rsp = 0, rbp = 0 ---