feat: unify Bluetooth support and add ZLP quirk

This commit is contained in:
Shen Mintao
2026-07-25 15:49:53 +08:00
parent 6550131e18
commit 13baa9b0b1
14 changed files with 267 additions and 101 deletions
+75 -81
View File
@@ -1,104 +1,100 @@
# Issue #63: standard `btusb` ZLP companion-module test
# Issue #63: standard `btusb` ACL ZLP support
This experiment keeps the normal `aic_load_fw + system btusb` architecture.
It does not install or bind the vendor `aic_btusb` transport, and it does not
replace the distribution's `btusb.ko`.
The `aic_zlp_quirk` companion module supplies the Bluetooth ACL bulk TX
zero-length-packet behavior confirmed in
[issue #63](https://github.com/shenmintao/aic8800d80/issues/63). It is now part
of the normal `aic8800` DKMS build rather than a replacement for the
distribution's Bluetooth driver.
The underlying ZLP behavior was confirmed in
[issue #63](https://github.com/shenmintao/aic8800d80/issues/63): AAC playback
that previously stalled after about one minute remained stable for more than
one hour with the standard `btusb` ZLP patch, including after the obsolete
`aic_btusb` module was removed.
The validated failure was specific and reproducible: AAC playback through USB
device `368b:8d81` stalled after about one minute, while SBC remained stable.
Adding `URB_ZERO_PACKET` to the ACL bulk OUT URBs kept AAC connected for more
than one hour. The standalone module was then verified with the system
`btusb`, no loaded `aic_btusb`, and 2,113 observed ZLP injections.
The small `aic_zlp_quirk.ko` module first tries to attach a kretprobe to the
standard `btusb` function that allocates Bluetooth ACL bulk OUT URBs. The
target is module-qualified as `btusb:alloc_bulk_urb`, avoiding similarly named
symbols in unrelated USB drivers.
## Architecture and scope
Some distribution builds inline that private `btusb` function. When the
preferred hook is unavailable, the same module falls back to the stable
`usb_submit_urb` entry point. The fallback requires all of the following before
changing an URB:
The module first tries to attach a kretprobe to the standard `btusb` function
that allocates ACL bulk OUT URBs. The target is module-qualified as
`btusb:alloc_bulk_urb`, avoiding similarly named symbols in unrelated USB
drivers.
- USB device `368b:8d81`;
- bulk OUT transfer;
- endpoint declared by Bluetooth interface 0 (`e0/01/01`).
Some distribution builds inline that private function. When the preferred hook
is unavailable, the module falls back to the stable `usb_submit_urb` entry
point. The fallback changes an URB only when all of these checks pass:
Both paths add `URB_ZERO_PACKET` before the USB core submits the transfer. The
Wi-Fi interface and unrelated USB devices are left unchanged.
- USB device is exactly `368b:8d81`;
- the transfer is bulk OUT;
- the endpoint belongs to Bluetooth interface 0 (`e0/01/01`).
The hook fails closed: if neither probe can be installed or kprobes are
disabled, the companion module refuses to load and the system `btusb` remains
unchanged.
Both paths add only `URB_ZERO_PACKET`. Wi-Fi interfaces and unrelated USB
devices are unchanged. If neither probe can be installed or kprobes are
disabled, the module refuses to load and system `btusb` remains unchanged.
## Before installing
The module carries a USB modalias for `368b:8d81`, so it is inactive on other
hardware and normally autoloads only when the validated device appears.
First remove the earlier patched-`btusb` diagnostic build, if installed:
## Install from the unified branch
```bash
cd ../issue63-btusb-zlp
sudo ./btusb-zlp-test.sh remove
git fetch origin
git switch test/unified-wifi-bt-zlp
git pull --ff-only
sudo ./install.sh
sudo reboot
```
An obsolete `aic_btusb` installation must also be unloaded and removed before
this test. Verify that the AIC Bluetooth interfaces use the system driver:
The installer removes the earlier `btusb-aic-zlp/0.1` and
`aic-zlp-quirk/0.1` diagnostic DKMS packages when present. To remove them
manually before installation, use:
```bash
sudo dkms remove btusb-aic-zlp/0.1 --all
sudo dkms remove aic-zlp-quirk/0.1 --all
sudo depmod -a
```
The unified installer also removes active configuration left by the obsolete
custom `aic_btusb` transport.
## Verify
Confirm that system `btusb` owns Bluetooth interfaces 0/1 and that the quirk is
loaded:
```bash
lsusb -t
lsmod | grep -E '^(btusb|aic_btusb)\b'
lsmod | grep -E '^(btusb|aic_zlp_quirk|aic_btusb)\b'
modinfo -n btusb
modinfo -n aic_zlp_quirk
cat /sys/module/aic_zlp_quirk/parameters/hook
cat /sys/module/aic_zlp_quirk/parameters/injections
sudo ./diagnose_bt.sh
```
## Install
Install the normal build dependencies. For Fedora:
```bash
sudo dnf install dkms gcc make kernel-devel-$(uname -r)
```
Then install and load the companion module:
```bash
cd tests/issue63-zlp-quirk
sudo ./aic-zlp-quirk-test.sh install
./aic-zlp-quirk-test.sh status
```
Expected status includes:
Expected results include:
```text
quirk loaded: yes
active hook: btusb:alloc_bulk_urb
legacy aic_btusb: not loaded
AIC BT driver: btusb
Bluetooth interfaces 0/1: btusb
aic_btusb: not loaded
aic_zlp_quirk: loaded
active hook: btusb:alloc_bulk_urb
```
`active hook: usb_submit_urb` is also valid when the distribution compiler
inlined the preferred private `btusb` function.
`active hook: usb_submit_urb` is also valid when the compiler inlined the
preferred function. During Bluetooth traffic, the `injections` value must
increase.
Select AAC and play audio for at least one hour:
For the promotion test, select AAC and play audio for at least one hour while
also confirming that Wi-Fi scan, association, DHCP, and real traffic remain
working.
```bash
bluetoothctl scan off
pactl set-card-profile bluez_card.28_6F_40_46_AB_B1 a2dp-sink-aac
```
## Isolated retest helper
While audio is playing, the `ZLP injections` counter should increase:
```bash
./aic-zlp-quirk-test.sh status
sudo dmesg | grep -i aic_zlp_quirk
```
## Remove
```bash
sudo ./aic-zlp-quirk-test.sh remove
./aic-zlp-quirk-test.sh status
```
Removal unloads only `aic_zlp_quirk.ko`. The distribution `btusb.ko` was never
overwritten and remains the Bluetooth transport throughout the test.
`aic-zlp-quirk-test.sh` remains available only for isolated issue #63 retests.
It builds the same canonical source from
`drivers/aic8800/aic_zlp_quirk/aic_zlp_quirk.c` as a separate DKMS package. A
normal installation should use the repository-level `install.sh` instead.
## Kernel requirements
@@ -108,8 +104,6 @@ overwritten and remains the Bluetooth transport throughout the test.
`usb_submit_urb` symbol;
- a valid module signature when Secure Boot policy requires one.
The `alloc_bulk_urb` function is present with the same signature in Linux
5.15, 6.1, 6.6, 6.12, 6.18, and 7.1.3, although compilers may inline it. The
fallback avoids depending on that implementation detail. DKMS compiles a
separate binary for each installed kernel while the repository maintains one
small source file.
The preferred function has the same signature in Linux 5.15, 6.1, 6.6, 6.12,
6.18, and 7.1.3, although compilers may inline it. DKMS builds one module for
each installed kernel from the single canonical source file.