Skip to content

fix(bluetooth): recover a controller that wedges across resume on Apple Silicon - #498

Open
n0mahd wants to merge 1 commit into
omacom:quattrofrom
n0mahd:fix/bluetooth-resume-recovery
Open

n0mahd wants to merge 1 commit into
omacom:quattrofrom
n0mahd:fix/bluetooth-resume-recovery

Conversation

@n0mahd

@n0mahd n0mahd commented Sep 22, 2026

Copy link
Copy Markdown

Addresses the resume half of #338 (upstream AsahiLinux/linux#604). The "Bluetooth keyboard cannot wake" half is separate and is not touched here.

Problem

On Apple Silicon Macs the Broadcom Bluetooth firmware can wedge across s2idle. After resume the controller stops answering HCI commands: the kernel logs hci0: command 0x0c01 tx timeout every couple of seconds, every connect fails, and neither the bar toggle nor bluetoothctl power on brings it back. From the user's side, a device that was paired and working yesterday won't connect after the lid is opened. Only unbinding and rebinding hci_bcm4377 clears it.

Fix

omarchy-bluetooth-resume-fix, run by a oneshot service ordered after the sleep targets. It follows the same pattern as fix-wifi-resume.sh for the Wi-Fi half of the same chip.

Testing

  • Shell tests: test/shell.d/bluetooth-resume-fix-test.sh, 8 cases, all pass: no timeouts leaves the controller alone, timeouts trigger a rebind, timeouts logged before the service starts are still counted, falls back when the suspend marker is missing, leaves a blocked or absent radio alone, reports an unbound driver.
  • Hardware: M1 MacBook Air (J313, BCM4378). Pointed at a real resume wedge (79 tx timeouts in one boot), it detected the wedge and the controller was back 0s after the rebind, without a reboot.
  • bin/omarchy commands --check passes, and every bin/omarchy-* passes its syntax check. In ./test/all, the only failures are three tests that need an omarchy-pkgs checkout (package-build-contract, settings-package-units, unowned-system-paths), and they fail the same way on quattro.

Not covered

A wedge that happens while the machine is awake (seen once on the same machine). This only runs after resume.

🤖 Generated with Claude Code

The Broadcom Bluetooth firmware wedges across s2idle: on resume the
controller stops answering HCI commands, every opcode fails with -110,
and neither the bar toggle nor bluetoothctl can power it back on. Only
a driver rebind clears it (omacom#338, upstream AsahiLinux/linux#604).

Recover with omarchy-bluetooth-resume-fix from a service ordered after
the sleep targets, mirroring how fix-wifi-resume.sh recovers the Wi-Fi
half of the same chip. The command rebinds only once the tx timeout
signature appears since the last suspend entry, so it stays a no-op on
machines and kernels where the firmware bug does not bite. It reads
from the entry marker rather than "PM: suspend exit" because the
kernel logs the exit marker after device resume, behind the timeouts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@oliverlukschander

Copy link
Copy Markdown

BCM4388 (14e4:5f72) wedges across resume on its own too — no rfkill involved.

MacBook Pro 16" M2 Pro (t6020), Aurora kernel 7.1.12, stock hci_bcm4377: 2 of the 7 suspends in this machine's journal (09-25, 09-27; s2idle via lid and via F6, sleeps from 15 s to 3 h 50 m) ended with exactly this PR's signature during device resume — hci0: command 0x0c01 tx timeout, then Opcode 0x0c1a / 0x202d / 0x2041 failed: -110 and Unable to disable LL privacy (the hci_resume_sync() sequence), all before PM: suspend exit. The firmware itself was gone (all ten control-ring messages timed out at modprobe -r), and modprobe -r hci_bcm4377 && modprobe hci_bcm4377 brought it back without a reboot, which is what this PR's rebind does. The Wi-Fi function on the same chip (01:00.0) resumed normally each time. One more reason to cover it: the blocked resume callback holds PM: suspend exit back by ~8 s (the four 2 s HCI timeouts), so the whole wake is slower until the rebind.

So the 5f72 exclusion (and the test that asserts it) could go. Happy to test a revision on this machine.

@malik-na

malik-na commented Oct 8, 2026

Copy link
Copy Markdown
Member

Thanks @n0mahd. The Apple Silicon packages moved to omacom/omarchy-mac-pkgs, so this is ported there as omacom/omarchy-mac-pkgs#21, with you as co-author. It also covers BCM4388 after @oliverlukschander's report above. I'll close this one when that merges.

malik-na added a commit to omacom/omarchy-mac-pkgs that referenced this pull request Oct 11, 2026
Port omacom/omarchy-mac#498 into the hardware package, with controller-specific journal recovery and setup that preserves administrator choices.

Co-authored-by: n0mahd <39080654+n0mahd@users.noreply.github.com>
malik-na pushed a commit to omacom/omarchy-mac-pkgs that referenced this pull request Oct 11, 2026
On an M2 Pro (t6020, 14e4:5f72) the controller wedged across 2 of 7
suspends with the same HCI tx timeout signature before PM: suspend exit,
and reloading hci_bcm4377 brought it back, as reported in the review of
omacom/omarchy-mac#498. The source PR left BCM4388 out only because its
one report then was the rfkill path; this adds it to the gate, the setup
tests, the README and the manual.

Co-authored-by: Oliver Lukschander <33756270+oliverlukschander@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants