aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/zz-bluetooth-resume23
1 files changed, 16 insertions, 7 deletions
diff --git a/scripts/zz-bluetooth-resume b/scripts/zz-bluetooth-resume
index 4273339..4b51dae 100755
--- a/scripts/zz-bluetooth-resume
+++ b/scripts/zz-bluetooth-resume
@@ -5,13 +5,16 @@
# A systemd-sleep hook. Two things break bluetooth across sleep on a TLP
# laptop, and nothing else on the machine fixes either one.
#
-# 1. The rfkill soft-block is not restored. systemd-rfkill would do it, and
+# 1. The rfkill soft-block is not cleared. systemd-rfkill would do it, and
# it is masked here deliberately -- it fights TLP's radio handling, so
# configure_tlp_power masks it and TLP owns radios instead. TLP's own
-# sleep hook runs `tlp resume`, but its setting is
-# DEVICES_TO_ENABLE_ON_STARTUP: startup, not resume. TLP has no ON_RESUME
-# at all, so the resume edge has no owner. WiFi survives only because
-# NetworkManager unblocks itself; bluetooth has no equivalent.
+# sleep hook runs `tlp resume`, but that only puts bluetooth back where
+# it was at suspend and applies no policy: its enable setting is
+# DEVICES_TO_ENABLE_ON_STARTUP, startup not resume, and TLP has no
+# ON_RESUME at all. So a block present at suspend stays, and so does one
+# that a controller re-probed after that replay comes up with. WiFi
+# survives only because NetworkManager unblocks itself; bluetooth has no
+# equivalent.
#
# 2. The controller comes back wedged from a hibernate. It reports powered
# and unblocked while scanning finds nothing whatever -- zero devices
@@ -28,8 +31,14 @@
# A machine whose TLP config does not ask for bluetooth keeps it off, which is
# what stops this from overriding a deliberate block at every wakeup.
#
-# The zz- prefix orders it after TLP's own hook, so `tlp resume` has finished
-# before this runs.
+# The zz- prefix buys no ordering: systemd-sleep runs every hook here in
+# parallel (man systemd-sleep), so `tlp resume` may still be running when
+# this starts, and its first act is to replay the rfkill state it saved at
+# suspend. On a hibernate-class wake the settle between unload and load below
+# usually lands the final unblock after that replay. A plain suspend has no
+# settle and unblocks at once, so that race is open. The tell is `rfkill list
+# bluetooth` reading "Soft blocked: yes" after a suspend cycle that was entered
+# with bluetooth already blocked (a hook that never ran reads the same way).
#
# Test seams: BTR_RFKILL, BTR_MODPROBE, BTR_TLP_CONF, BTR_TLP_CONF_DIR,
# BTR_SETTLE (seconds to wait between driver unload and load).