diff --git a/.gitattributes b/.gitattributes index 4c3b043..b6a4e28 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/INSTALL_SCRIPT.md b/INSTALL_SCRIPT.md index 90017c9..8ed3c41 100644 --- a/INSTALL_SCRIPT.md +++ b/INSTALL_SCRIPT.md @@ -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 diff --git a/README.md b/README.md index c12a507..41beec4 100644 --- a/README.md +++ b/README.md @@ -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. + diff --git a/bazzite/README.md b/bazzite/README.md index 5d56e68..6efd2b0 100644 --- a/bazzite/README.md +++ b/bazzite/README.md @@ -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. diff --git a/bazzite/aic8800d80.spec b/bazzite/aic8800d80.spec index 68ecc81..464d61a 100644 --- a/bazzite/aic8800d80.spec +++ b/bazzite/aic8800d80.spec @@ -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* diff --git a/diagnose_bt.sh b/diagnose_bt.sh index c7ff142..ef0e200 100644 --- a/diagnose_bt.sh +++ b/diagnose_bt.sh @@ -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 ===" diff --git a/dkms.conf b/dkms.conf index ca060ed..4332d39 100644 --- a/dkms.conf +++ b/dkms.conf @@ -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" diff --git a/drivers/aic8800/Makefile b/drivers/aic8800/Makefile index 54e658f..ee68eee 100644 --- a/drivers/aic8800/Makefile +++ b/drivers/aic8800/Makefile @@ -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/ diff --git a/drivers/aic8800/aic_zlp_quirk/Makefile b/drivers/aic8800/aic_zlp_quirk/Makefile new file mode 100644 index 0000000..8595f58 --- /dev/null +++ b/drivers/aic8800/aic_zlp_quirk/Makefile @@ -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 diff --git a/tests/issue63-zlp-quirk/aic_zlp_quirk.c b/drivers/aic8800/aic_zlp_quirk/aic_zlp_quirk.c similarity index 98% rename from tests/issue63-zlp-quirk/aic_zlp_quirk.c rename to drivers/aic8800/aic_zlp_quirk/aic_zlp_quirk.c index f3fc322..122bb68 100644 --- a/tests/issue63-zlp-quirk/aic_zlp_quirk.c +++ b/drivers/aic8800/aic_zlp_quirk/aic_zlp_quirk.c @@ -224,5 +224,6 @@ module_exit(aic_zlp_quirk_exit); MODULE_AUTHOR("Shen Mintao "); 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*"); diff --git a/install.sh b/install.sh index ce2a4f1..4ddad4c 100755 --- a/install.sh +++ b/install.sh @@ -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}" diff --git a/tests/issue63-zlp-quirk/README.md b/tests/issue63-zlp-quirk/README.md index 444cc6a..7d62b3c 100644 --- a/tests/issue63-zlp-quirk/README.md +++ b/tests/issue63-zlp-quirk/README.md @@ -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. diff --git a/tests/issue63-zlp-quirk/aic-zlp-quirk-test.sh b/tests/issue63-zlp-quirk/aic-zlp-quirk-test.sh index acd64ac..1e69fa4 100755 --- a/tests/issue63-zlp-quirk/aic-zlp-quirk-test.sh +++ b/tests/issue63-zlp-quirk/aic-zlp-quirk-test.sh @@ -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}/" } diff --git a/tests/unified-wifi-bt/README.md b/tests/unified-wifi-bt/README.md index 46bf4fd..dc74a5b 100644 --- a/tests/unified-wifi-bt/README.md +++ b/tests/unified-wifi-bt/README.md @@ -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 ```