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
+2 -3
View File
@@ -1,7 +1,6 @@
/.gitattributes text eol=lf
tests/issue63-btusb-zlp/*.patch -whitespace
tests/issue63-btusb-zlp/*.sh text eol=lf
tests/issue63-zlp-quirk/*.c text eol=lf
drivers/aic8800/aic_zlp_quirk/*.c text eol=lf
drivers/aic8800/aic_zlp_quirk/Makefile text eol=lf
tests/issue63-zlp-quirk/*.conf text eol=lf
tests/issue63-zlp-quirk/*.md text eol=lf
tests/issue63-zlp-quirk/*.sh text eol=lf
+4 -1
View File
@@ -4,13 +4,16 @@
This automated installation script (`install.sh`) installs the AIC8800 Wi-Fi
driver and firmware loader on Linux systems. Wi-Fi/Bluetooth combo adapters use
the standard kernel `btusb` driver after firmware initialization.
the standard kernel `btusb` driver after firmware initialization. For USB
device `368b:8d81`, it also installs a device-scoped ACL bulk TX ZLP companion
module without replacing the distribution's `btusb.ko`.
- Automatic Secure Boot detection
- Automatic dependency installation
- Automatic driver compilation and installation
- Automatic module loading on boot
- Automatic cleanup of obsolete `aic_btusb` configuration
- Automatic `aic_zlp_quirk` handling for the validated `368b:8d81` device
- Wi-Fi-only and Wi-Fi/Bluetooth combo adapter support from the same branch
- Comprehensive error handling
- Colored output and logging
+23 -3
View File
@@ -10,8 +10,8 @@ This driver is for the AIC8800D80 chipset, supported by devices such as the Tend
> to avoid the deterministic firmware upload timeout at `0x170400`. Use
> `main` when `chip_mcu_id=0` or when the MCU revision is unknown.
>
> Hardware revision takes precedence over the Bluetooth feature branch. MCU1
> devices should remain on `legacy-mcu1`, which initializes Bluetooth for the
> Hardware revision determines the firmware branch. MCU1 devices should use
> `legacy-mcu1`, which also initializes Bluetooth for the
> kernel's standard `btusb` driver. After switching branches, rerun
> `sudo ./install.sh` and reboot; switching the Git branch alone does not
> replace the firmware already installed under `/lib/firmware`.
@@ -25,6 +25,13 @@ adapters. On combo devices, `aic_load_fw` uploads the AIC firmware and the
standard Linux `btusb` driver handles the Bluetooth HCI interface. The obsolete
custom `aic_btusb` module is not used.
USB device `368b:8d81` also uses the bundled `aic_zlp_quirk` companion module.
It adds the Bluetooth ACL bulk TX zero-length-packet behavior validated in
[issue #63](https://github.com/shenmintao/aic8800d80/issues/63), while leaving
the distribution's original `btusb.ko` installed and bound to the device. The
quirk is filtered to that VID:PID and fails closed when the required kernel
probe support is unavailable.
### Disclaimer
I did not develop this software, The code is sourced from the Tenda U11 driver. I only made some modifications to the code to adapt it to newer kernel versions. Apart from compilation issues, I am unable to address other problems.
@@ -126,7 +133,7 @@ interface, so the Bluetooth path remains inactive.
Verify the expected modules and controller with:
```bash
lsmod | grep -E 'aic_load_fw|aic8800_fdrv|btusb'
lsmod | grep -E 'aic_load_fw|aic8800_fdrv|aic_zlp_quirk|btusb'
lsusb -t
bluetoothctl list
```
@@ -152,3 +159,16 @@ The installer removes active references to the retired `aic_btusb` integration.
It does not force-load `btusb` or globally change the Bluetooth rfkill state;
normal kernel device matching and the user's system policy remain in control.
For `368b:8d81`, verify the ZLP hook and its injection counter while Bluetooth
traffic is active:
```bash
cat /sys/module/aic_zlp_quirk/parameters/hook
cat /sys/module/aic_zlp_quirk/parameters/injections
```
The Wi-Fi-reset recovery behavior tracked in
[issue #53](https://github.com/shenmintao/aic8800d80/issues/53) remains a known
limitation: after an airplane-mode or hotspot reset, Bluetooth may require a
physical unplug/replug of the adapter.
+3 -1
View File
@@ -58,7 +58,9 @@ sudo systemctl reboot
After reboot, the Wi-Fi module and firmware loader will be available. On combo
adapters, Bluetooth is handled by the standard `btusb` kernel module after
firmware initialization.
firmware initialization. USB device `368b:8d81` also autoloads the packaged
`aic_zlp_quirk` companion module for its required Bluetooth ACL bulk TX zero
packet behavior; the distribution's `btusb` module is not replaced.
This RPM is built for the kernel reported by `uname -r`. Rebuild and reinstall
it after a Bazzite kernel upgrade.
+9 -2
View File
@@ -5,7 +5,7 @@
Name: aic8800d80
Version: %{shortcommit}
Release: 1%{?dist}
Summary: AIC8800 USB Wi-Fi and Bluetooth firmware driver
Summary: AIC8800 USB Wi-Fi, Bluetooth firmware, and ZLP quirk driver
License: GPL-2.0-only
URL: https://github.com/shenmintao/aic8800d80
@@ -24,7 +24,9 @@ Requires(postun): /usr/sbin/depmod
%description
Out-of-tree AIC8800 USB driver with Wi-Fi support, Bluetooth firmware loading,
udev mode-switch rules, and all firmware variants shipped by the upstream
repository. Combo adapters use the standard Linux btusb transport driver.
repository. Combo adapters use the standard Linux btusb transport driver. A
device-scoped companion module supplies the required ACL bulk TX ZLP behavior
for USB device 368b:8d81 without replacing the distribution btusb module.
%prep
%autosetup -n %{name}-%{commit}
@@ -44,6 +46,10 @@ install -Dpm0644 \
drivers/aic8800/aic_load_fw/aic_load_fw.ko \
%{buildroot}/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic_load_fw.ko
install -Dpm0644 \
drivers/aic8800/aic_zlp_quirk/aic_zlp_quirk.ko \
%{buildroot}/usr/lib/modules/%{kver}/kernel/drivers/bluetooth/aic8800/aic_zlp_quirk.ko
install -Dpm0644 \
aic.rules \
%{buildroot}/usr/lib/udev/rules.d/90-aic8800-mode-switch.rules
@@ -65,6 +71,7 @@ cp -a fw/aic8800* %{buildroot}/usr/lib/firmware/
%dir /usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800
/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic8800_fdrv.ko
/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic_load_fw.ko
/usr/lib/modules/%{kver}/kernel/drivers/bluetooth/aic8800/aic_zlp_quirk.ko
/usr/lib/udev/rules.d/90-aic8800-mode-switch.rules
%config(noreplace) /etc/usb_modeswitch.d/1111:1111
/usr/lib/firmware/aic8800*
+32 -3
View File
@@ -19,6 +19,7 @@ echo ""
echo "2. USB interfaces and bound drivers:"
bt_interface_found=false
btusb_bound=false
zlp_target_found=false
for dev in /sys/bus/usb/devices/*; do
[ -f "$dev/idVendor" ] || continue
[ -f "$dev/idProduct" ] || continue
@@ -31,6 +32,9 @@ for dev in /sys/bus/usb/devices/*; do
esac
echo " Device: $vid:$pid"
if [ "$vid" = "368b" ] && [ "$pid" = "8d81" ]; then
zlp_target_found=true
fi
for intf in "$dev"/*:*; do
[ -d "$intf" ] || continue
class=$(cat "$intf/bInterfaceClass" 2>/dev/null)
@@ -50,7 +54,7 @@ done
echo ""
echo "3. Relevant kernel modules (combo expectation: aic_load_fw + btusb):"
lsmod | grep -E '^(aic_load_fw|aic8800_fdrv|aic_btusb|btusb|bluetooth)[[:space:]]' || \
lsmod | grep -E '^(aic_load_fw|aic8800_fdrv|aic_zlp_quirk|aic_btusb|btusb|bluetooth)[[:space:]]' || \
echo " No related module is currently loaded"
echo ""
@@ -64,8 +68,8 @@ else
fi
echo ""
echo "5. Firmware, btusb, and HCI log messages:"
dmesg 2>/dev/null | grep -iE 'fw_patch|fw_adid|aicbt|bluetooth|btusb|hci' | tail -80 || true
echo "5. Firmware, btusb, ZLP quirk, and HCI log messages:"
dmesg 2>/dev/null | grep -iE 'fw_patch|fw_adid|aicbt|aic_zlp_quirk|bluetooth|btusb|hci' | tail -80 || true
echo ""
echo "6. Bluetooth rfkill state:"
@@ -110,6 +114,27 @@ if [ "$legacy_refs_found" = false ]; then
fi
echo ""
echo "8. Device-scoped Bluetooth ACL ZLP quirk:"
if [ "$zlp_target_found" = true ]; then
if [ -d /sys/module/aic_zlp_quirk ]; then
zlp_hook="unknown"
zlp_injections="unavailable"
[ -r /sys/module/aic_zlp_quirk/parameters/hook ] && \
zlp_hook=$(cat /sys/module/aic_zlp_quirk/parameters/hook)
[ -r /sys/module/aic_zlp_quirk/parameters/injections ] && \
zlp_injections=$(cat /sys/module/aic_zlp_quirk/parameters/injections)
echo " Target 368b:8d81 present"
echo " aic_zlp_quirk loaded: yes"
echo " active hook: $zlp_hook"
echo " ZLP injections: $zlp_injections"
else
echo " Target 368b:8d81 present, but aic_zlp_quirk is not loaded"
fi
else
echo " Target 368b:8d81 not present; quirk is not required"
fi
echo ""
echo "=== Assessment ==="
if ! lsmod | awk '{print $1}' | grep -qx 'aic_load_fw'; then
echo "- aic_load_fw is not loaded; run: sudo modprobe aic8800_fdrv"
@@ -125,5 +150,9 @@ fi
if [ "$bt_interface_found" = false ]; then
echo "- No Bluetooth HCI USB interface was found. This is normal for a Wi-Fi-only adapter."
fi
if [ "$zlp_target_found" = true ] && [ ! -d /sys/module/aic_zlp_quirk ]; then
echo "- Device 368b:8d81 requires the ACL ZLP quirk, but the module is not loaded."
echo " Try: sudo modprobe aic_zlp_quirk"
fi
echo "=== Diagnostics complete ==="
+5
View File
@@ -13,4 +13,9 @@ BUILT_MODULE_NAME[1]="aic_load_fw"
BUILT_MODULE_LOCATION[1]="drivers/aic8800/aic_load_fw"
DEST_MODULE_LOCATION[1]="/updates/dkms"
# Device-scoped standard-btusb ACL bulk TX ZLP quirk (368b:8d81 only)
BUILT_MODULE_NAME[2]="aic_zlp_quirk"
BUILT_MODULE_LOCATION[2]="drivers/aic8800/aic_zlp_quirk"
DEST_MODULE_LOCATION[2]="/updates/dkms"
AUTOINSTALL="yes"
+7
View File
@@ -1,8 +1,10 @@
CONFIG_AIC_LOADFW_SUPPORT := m
CONFIG_AIC8800_WLAN_SUPPORT := m
CONFIG_AIC_ZLP_QUIRK := m
obj-$(CONFIG_AIC_LOADFW_SUPPORT) += aic_load_fw/
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
obj-$(CONFIG_AIC_ZLP_QUIRK) += aic_zlp_quirk/
########## config option ##########
export CONFIG_USE_FW_REQUEST = n
@@ -51,6 +53,7 @@ KVER ?= $(shell uname -r)
KDIR ?= /lib/modules/$(KVER)/build
PWD = $(shell pwd)
MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
BTMODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/bluetooth/aic8800
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/ -e s/loongarch64/loongarch/ -e s/loong64/loongarch/ -e s/riscv64/riscv/)
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
@@ -78,16 +81,20 @@ modules:
install:
mkdir -p $(MODDESTDIR)
mkdir -p $(BTMODDESTDIR)
install -p -m 644 aic_load_fw/aic_load_fw.ko $(MODDESTDIR)/
install -p -m 644 aic8800_fdrv/aic8800_fdrv.ko $(MODDESTDIR)/
install -p -m 644 aic_zlp_quirk/aic_zlp_quirk.ko $(BTMODDESTDIR)/
/sbin/depmod -a ${KVER}
uninstall:
rm -rfv $(MODDESTDIR)/aic_load_fw.ko
rm -rfv $(MODDESTDIR)/aic8800_fdrv.ko
rm -rfv $(BTMODDESTDIR)/aic_zlp_quirk.ko
/sbin/depmod -a ${KVER}
clean:
cd aic_load_fw/;make clean;cd ..
cd aic8800_fdrv/;make clean;cd ..
cd aic_zlp_quirk/;make clean;cd ..
rm -rf modules.order Module.symvers .modules.order.cmd .Module.symvers.cmd .tmp_versions/
+18
View File
@@ -0,0 +1,18 @@
ifneq ($(KERNELRELEASE),)
obj-m += aic_zlp_quirk.o
else
KVER ?= $(shell uname -r)
KDIR ?= /lib/modules/$(KVER)/build
.PHONY: all clean
all:
$(MAKE) -C $(KDIR) M=$(CURDIR) modules
clean:
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
endif
@@ -224,5 +224,6 @@ module_exit(aic_zlp_quirk_exit);
MODULE_AUTHOR("Shen Mintao <cx330.shen@autocore.ai>");
MODULE_DESCRIPTION("AIC 8800D80 standard btusb ACL bulk TX ZLP quirk");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.1");
MODULE_VERSION("1.0");
MODULE_SOFTDEP("pre: btusb");
MODULE_ALIAS("usb:v368Bp8D81d*dc*dsc*dp*ic*isc*ip*in*");
+64
View File
@@ -326,6 +326,7 @@ check_kernel_build_tree() {
cleanup_legacy_bluetooth_config() {
local legacy_conf="/etc/modprobe.d/aic8800-bt.conf"
local legacy_udev="/etc/udev/rules.d/90-aic8800-mode-switch.rules"
local legacy_package
local changed=false
if [ -f "$legacy_conf" ] && grep -Eq '^[[:space:]]*(softdep|alias)[^#]*aic_btusb([[:space:]]|$)' "$legacy_conf"; then
@@ -358,6 +359,21 @@ cleanup_legacy_bluetooth_config() {
fi
fi
# Remove the two issue #63 diagnostic DKMS packages before the production
# quirk is installed as part of aic8800/1.0.0. A patched btusb may remain
# active in memory until reboot, but DKMS restores the distribution module
# on disk when its test package is removed.
for legacy_package in "btusb-aic-zlp/0.1" "aic-zlp-quirk/0.1"; do
if dkms status 2>/dev/null | grep -q "^${legacy_package},"; then
print_info "Removing superseded test package ${legacy_package}..."
if dkms remove "$legacy_package" --all >> "$LOG_FILE" 2>&1; then
changed=true
else
print_warning "Could not remove ${legacy_package}; remove it manually before reboot."
fi
fi
done
if [ "$changed" = true ]; then
print_success "Legacy Bluetooth configuration cleaned up."
fi
@@ -460,6 +476,11 @@ BUILT_MODULE_NAME[1]="aic_load_fw"
BUILT_MODULE_LOCATION[1]="drivers/aic8800/aic_load_fw"
DEST_MODULE_LOCATION[1]="/updates/dkms"
# Quirk ZLP para Bluetooth ACL bulk TX (somente 368b:8d81)
BUILT_MODULE_NAME[2]="aic_zlp_quirk"
BUILT_MODULE_LOCATION[2]="drivers/aic8800/aic_zlp_quirk"
DEST_MODULE_LOCATION[2]="/updates/dkms"
AUTOINSTALL="yes"
EOF
@@ -569,6 +590,20 @@ refresh_initramfs() {
# Module Loading
#############################################################################
aic_zlp_target_present() {
local device
for device in /sys/bus/usb/devices/*; do
[ -r "$device/idVendor" ] || continue
[ -r "$device/idProduct" ] || continue
[ "$(cat "$device/idVendor")" = "368b" ] || continue
[ "$(cat "$device/idProduct")" = "8d81" ] || continue
return 0
done
return 1
}
load_module() {
print_step "Loading kernel modules..."
@@ -611,6 +646,19 @@ load_module() {
fi
print_info "Combo adapters use the standard btusb driver when their Bluetooth interface appears."
# The module has a USB alias and normally autoloads when 368b:8d81 appears.
# Explicitly load it here as well when that device was already present before
# DKMS installation and therefore did not generate a new modalias event.
if aic_zlp_target_present; then
print_info "Loading the 368b:8d81 Bluetooth ACL ZLP quirk..."
if modprobe aic_zlp_quirk >> "$LOG_FILE" 2>&1; then
print_success "Device-scoped Bluetooth ZLP quirk is active."
else
print_warning "The ZLP quirk could not attach; system btusb remains unchanged."
print_info "Check CONFIG_KPROBES, Secure Boot, and: sudo dmesg | grep aic_zlp_quirk"
fi
fi
}
#############################################################################
@@ -643,6 +691,20 @@ verify_installation() {
print_info "No Bluetooth controller is present (normal for Wi-Fi-only adapters or when no combo adapter is connected)."
fi
if aic_zlp_target_present; then
if lsmod | awk '{print $1}' | grep -qx 'aic_zlp_quirk'; then
local zlp_hook="unknown"
if [ -r /sys/module/aic_zlp_quirk/parameters/hook ]; then
zlp_hook=$(cat /sys/module/aic_zlp_quirk/parameters/hook)
fi
print_success "Bluetooth ACL ZLP quirk is loaded (hook: $zlp_hook)."
else
print_warning "USB device 368b:8d81 is present but aic_zlp_quirk is not loaded."
fi
else
print_info "Bluetooth ZLP quirk is installed but inactive (no 368b:8d81 device present)."
fi
echo ""
print_info "Loaded AIC modules:"
lsmod | grep aic || echo " (none)"
@@ -690,6 +752,7 @@ show_final_instructions() {
echo ""
echo "✓ Wi-Fi driver and firmware loader installed via DKMS"
echo "✓ Combo adapters use the standard Linux btusb driver"
echo "✓ Device-scoped Bluetooth ACL ZLP quirk installed for 368b:8d81"
echo "✓ Automatic rebuild enabled for kernel updates"
echo "✓ Firmware installed in /lib/firmware/"
echo ""
@@ -721,6 +784,7 @@ show_final_instructions() {
echo ""
echo "• Check loaded modules:"
echo " ${BLUE}lsmod | grep -E 'aic|btusb'${NC}"
echo " ${BLUE}cat /sys/module/aic_zlp_quirk/parameters/{hook,injections}${NC}"
echo ""
echo "• Manually load the Wi-Fi module and firmware loader:"
echo " ${BLUE}sudo modprobe aic8800_fdrv${NC}"
+74 -80
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
Bluetooth interfaces 0/1: btusb
aic_btusb: not loaded
aic_zlp_quirk: loaded
active hook: btusb:alloc_bulk_urb
legacy aic_btusb: not loaded
AIC BT driver: btusb
```
`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.
@@ -9,6 +9,8 @@ KERNEL_BUILD_DIR="/lib/modules/${KERNEL_RELEASE}/build"
SOURCE_DIR="/usr/src/${PACKAGE_NAME}-${PACKAGE_VERSION}"
MODULES_LOAD_FILE="/etc/modules-load.d/${PACKAGE_NAME}.conf"
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../.." && pwd)"
QUIRK_SOURCE="${REPO_ROOT}/drivers/aic8800/aic_zlp_quirk/aic_zlp_quirk.c"
log() {
printf '[aic-zlp-quirk-test] %s\n' "$*"
@@ -53,7 +55,7 @@ patched_btusb_installed() {
copy_sources() {
install -d "${SOURCE_DIR}"
install -m 0644 "${SCRIPT_DIR}/aic_zlp_quirk.c" "${SOURCE_DIR}/"
install -m 0644 "${QUIRK_SOURCE}" "${SOURCE_DIR}/"
install -m 0644 "${SCRIPT_DIR}/Makefile" "${SOURCE_DIR}/"
install -m 0644 "${SCRIPT_DIR}/dkms.conf" "${SOURCE_DIR}/"
}
+20 -5
View File
@@ -1,9 +1,10 @@
# Unified Wi-Fi and Bluetooth branch test
# Unified Wi-Fi, Bluetooth, and ZLP branch test
This branch tests replacing the separate `main` and `bluetooth` branches with
one driver and installer. The kernel driver, firmware, and DKMS configuration
were already identical on both branches. This test unifies their installer,
migration, diagnostics, packaging description, and documentation.
one driver and installer. The Wi-Fi driver and firmware were already identical
on both branches. This test unifies their installer, migration, diagnostics,
packaging, and documentation, and adds the device-scoped ZLP fix from issue
#63 as a third DKMS module.
The expected architecture is:
@@ -13,6 +14,9 @@ The expected architecture is:
the standard Linux `btusb` driver binds through normal USB device matching.
- A Wi-Fi-only adapter exposes no HCI interface and does not need `btusb`.
- The retired custom `aic_btusb` module is never installed or used.
- USB device `368b:8d81` autoloads `aic_zlp_quirk`, which adds
`URB_ZERO_PACKET` only to its Bluetooth ACL bulk OUT transfers.
- The distribution's original `btusb.ko` is never replaced.
The installer deliberately does not force-load `btusb` and does not globally
unblock Bluetooth through rfkill.
@@ -21,7 +25,7 @@ unblock Bluetooth through rfkill.
```bash
git fetch origin
git switch test/unified-wifi-bt
git switch test/unified-wifi-bt-zlp
git pull --ff-only
sudo ./install.sh
sudo reboot
@@ -46,6 +50,16 @@ Confirm that:
4. `bluetoothctl` can power on, scan, pair, and exchange real traffic.
5. No `aic_btusb` module, alias, soft dependency, or udev binding rule remains.
## Test the `368b:8d81` ZLP path
In addition to the combo-adapter checks, confirm that:
1. `aic_zlp_quirk` loads automatically and system `btusb` owns interfaces 0/1.
2. `hook` reports `btusb:alloc_bulk_urb` or `usb_submit_urb`.
3. The `injections` counter increases during Bluetooth audio traffic.
4. AAC playback remains connected for at least one hour.
5. Wi-Fi scan, association, and traffic remain unaffected during the test.
## Collect results
```bash
@@ -55,6 +69,7 @@ lsusb -t
lsmod | grep -E 'aic|btusb|bluetooth'
iw dev
bluetoothctl list
cat /sys/module/aic_zlp_quirk/parameters/{hook,injections} 2>/dev/null || true
sudo ./diagnose_bt.sh | tee unified-wifi-bt-diagnostic.log
sudo journalctl -k -b --no-pager | tee unified-wifi-bt-kernel.log
```