mirror of
https://github.com/shenmintao/aic8800d80.git
synced 2026-09-26 17:44:16 +00:00
feat: unify Bluetooth support and add ZLP quirk
This commit is contained in:
+2
-3
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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 ==="
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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
|
||||
+2
-1
@@ -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
@@ -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}"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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}/"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user