Force-rebind bound-but-broken USB WiFi drivers in reprobe
This commit is contained in:
parent
c82551723e
commit
1668ff73d8
1 changed files with 44 additions and 14 deletions
|
|
@ -8,26 +8,56 @@
|
|||
# leaving the hardware driverless or degraded. Run from init at post-fs
|
||||
# (i.e. after /vendor is mounted) via init.tart.wifi.rc, this script:
|
||||
#
|
||||
# 1. Re-probes every driverless USB interface, so a USB WiFi adapter that
|
||||
# was plugged in at power-on (and whose driver probe failed on the
|
||||
# missing firmware) gets a second probe that can now load firmware.
|
||||
# 1. Force-rebinds known WiFi USB drivers, so a USB WiFi adapter that was
|
||||
# plugged in at power-on (and whose firmware request failed on the
|
||||
# missing /vendor mount) gets a second, working probe. Confirmed on
|
||||
# hardware (2026-07-13) that mt76-family drivers do NOT fail probe() on
|
||||
# a missing-firmware error -- they bind "successfully" and then loop
|
||||
# forever retrying an MCU handshake that can never succeed, so a plain
|
||||
# driverless-only reprobe (the previous version of this script) never
|
||||
# touches them. Unbind+rebind is required regardless of bound state.
|
||||
# 2. Rebinds the Broadcom Bluetooth serdev device, so hci_bcm reloads its
|
||||
# .hcd patch firmware (e.g. brcm/SYN43711A0.hcd). Without the patch the
|
||||
# .hcd patch firmware (e.g. brcm/BCM.hcd). Without the patch the
|
||||
# controller runs with unpatched defaults, which cripples TX power/range.
|
||||
# Confirmed on hardware: firmware build version goes 0000 -> 1000 after
|
||||
# this rebind.
|
||||
#
|
||||
# Both operations are idempotent and safe: already-bound USB interfaces are
|
||||
# skipped, and the BT rebind simply re-registers hci0 before the Bluetooth
|
||||
# stack starts.
|
||||
# Both operations are idempotent and safe to run more than once.
|
||||
|
||||
# 1. USB: ask the kernel to re-run driver matching for unbound interfaces
|
||||
# (directories like 1-1:1.0 without a "driver" symlink). Two passes with a
|
||||
# delay: a probe that was already in flight (started just before /vendor
|
||||
# finished mounting) can still fail after the first pass runs; the second
|
||||
# pass catches the interface it leaves behind.
|
||||
# List of built-in USB WiFi driver names from tart_defconfig (see
|
||||
# CONFIG_WLAN_VENDOR_MEDIATEK/_REALTEK/_ATH/_RALINK/_ZYDAS/CONFIG_MWIFIEX).
|
||||
WIFI_USB_DRIVERS="mt7601u mt76x0u mt76x2u mt7921u mt7925u \
|
||||
rt2500usb rt73usb rt2800usb \
|
||||
rtl8187 rtl8xxxu rtw_8822bu rtw_8822cu rtw_8723du rtw_8821cu \
|
||||
ath9k_htc carl9170 ar5523 \
|
||||
zd1211rw mwifiex_usb"
|
||||
|
||||
is_wifi_driver() {
|
||||
for d in $WIFI_USB_DRIVERS; do
|
||||
[ "$d" = "$1" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# USB: for interfaces already bound to a known WiFi driver, force an
|
||||
# unbind+rebind (their probe "succeeded" despite the firmware failure, so a
|
||||
# driverless-only reprobe never reaches them). For genuinely unbound
|
||||
# interfaces, just ask the kernel to re-run driver matching. Two passes with
|
||||
# a delay: a probe already in flight when /vendor finished mounting can still
|
||||
# fail after the first pass runs; the second pass catches what it leaves
|
||||
# behind.
|
||||
reprobe_usb() {
|
||||
for intf in /sys/bus/usb/devices/*:*; do
|
||||
[ -e "$intf/driver" ] && continue
|
||||
echo "${intf##*/}" > /sys/bus/usb/drivers_probe 2>/dev/null
|
||||
name="${intf##*/}"
|
||||
if [ -e "$intf/driver" ]; then
|
||||
drv="$(basename "$(readlink -f "$intf/driver")")"
|
||||
if is_wifi_driver "$drv"; then
|
||||
echo "$name" > "$intf/driver/unbind" 2>/dev/null
|
||||
echo "$name" > /sys/bus/usb/drivers_probe 2>/dev/null
|
||||
fi
|
||||
else
|
||||
echo "$name" > /sys/bus/usb/drivers_probe 2>/dev/null
|
||||
fi
|
||||
done
|
||||
}
|
||||
reprobe_usb
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue