Repository navigation
MacBookAir9,1: t2bce_vhci desync after rapid S3 suspend/resume cycles — 'Unhandled system event: 50' on resume, internal keyboard dead, next suspend wedges (linux-t2 7.1.8) #24
Description
Summary
After several lid-close/lid-open S3 suspend/resume cycles in quick succession on a
MacBookAir9,1, one resume completes with t2bce_vhci: Unhandled system event: 50.
The next lid close (~24 s later) never reaches S3: the VHCI command channel
desyncs (Possible desync, cmd cancel timed out), the internal keyboard and
trackpad stop responding at the lock screen, a udev worker hangs indefinitely on
the trackpad evdev node, and the suspend request wedges. The machine had to be
forcibly powered off.
This uses the newer t2bce stack (v0.06), not legacy apple-bce.
Unlike #22 (hibernate/S4 resume failure followed by kernel GP faults), this is
plain S3 suspend, there is no oops, and the failure is preceded by the
Unhandled system event: 50 message — the VHCI simply desyncs and everything
that touches it hangs.
Hardware
- Model: MacBookAir9,1
- Board: Mac-0CFF9C7C2B63DF8D
- Firmware: BIOS 2103.100.6.0.0, iBridge 23.16.15067.0.0
- T2 Bridge Controller: PCI
0000:74:00.1(106b:1801)
Software
- Distribution: Omarchy / Arch Linux
- Kernel:
7.1.8-arch1-Watanare-T2-3-t2(linux-t2 7.1.8.arch1-3) - t2bce driver stack: v0.06 (
drivers/staging/t2bce) - systemd 261.2-1, Hyprland 0.56.2-1
/sys/power/mem_sleep:s2idle [deep]— all sleeps below are S3 deep
Steps to reproduce
- Boot normally, log in to the graphical session.
- Close and open the lid several times over ~20 minutes (five S3 cycles here).
- On an eventually-unlucky resume, the kernel logs
t2bce_vhci: Unhandled system event: 50 s=0 p1=0 p2=0shortly after the
internal keyboard re-enumerates. - Close the lid again within ~30 seconds.
- The VHCI desyncs; internal keyboard/trackpad are dead at the lock screen and
the suspend never enters S3. Only a forced power-off recovers.
Reproducibility is timing-dependent: four earlier cycles in the same boot —
including one where the lid was closed only 16 s after resume — survived. The
fatal cycle is the only one where Unhandled system event: 50 was logged.
Timeline (journal from the affected boot)
Suspend/resume cycles leading up to the failure:
14:24:26 PM: suspend exit
14:32:21 PM: suspend entry (deep)
14:33:04 PM: suspend exit
14:36:50 PM: suspend entry (deep)
14:39:04 PM: suspend exit
14:39:20 PM: suspend entry (deep) <- 16 s after resume, survived
14:44:32 PM: suspend exit
14:44:58 PM: suspend entry (deep)
14:45:31 PM: suspend exit <- fatal cycle's resume
The final resume looks normal at first (keyboard re-enumerates as usb 5-5
device 18), then the unhandled event arrives:
14:45:29.647 t2bce_core: suspend: exit status=0 stateful_valid=1 no_state_resume=0 no_state_fallback=0
14:45:29.655 t2bce_core: resume: exit status=0 path=stateful stateful_valid=0 no_state_resume=0 no_state_fallback=0
14:45:29.662 t2bce_vhci: stateful resume exit status=0
14:45:29.662 t2bce_vhci: bus_resume exit status=0 no_state_resume=0
14:45:29.727 usb 5-5: new high-speed USB device number 18 using t2bce_core
14:45:30.012 apple 0003:05AC:0280.003C: input,hiddev98,hidraw3: USB HID v1.01 Keyboard [Apple Inc. Apple Internal Keyboard / Trackpad] on usb-t2bce_vhci-5/input1
14:45:30.823 t2bce_vhci: Unhandled system event: 50 s=0 p1=0 p2=0
14:45:31.140 PM: suspend exit
Lid closed again at 14:45:55; the suspend request then wedges and the VHCI
desyncs:
14:45:55.321 systemd-logind: Suspending...
14:46:03.552 t2bce_vhci: Possible desync, cmd cancel timed out
14:46:06.624 t2bce_vhci: Possible desync, cmd cancel timed out
14:46:09.695 t2bce_vhci: Possible desync, cmd cancel timed out
14:46:10.498 systemd-logind: Delay lock is active (UID 0/root, PID 782/NetworkManager) but inhibitor timeout is reached.
14:46:10.502 systemd[1]: Starting System Suspend...
14:46:30.815 (udev-worker): event7: Spawned process '/usr/lib/udev/libinput-fuzz-to-zero /sys/devices/pci0000:00/.../t2bce_vhci/usb5/5-5/5-5:1.2/0003:05AC:0280.003D/input/input35/event7' is taking longer than 59s to complete.
14:46:40.928 t2bce_vhci: Possible desync, cmd cancel timed out
No PM: suspend entry ever follows the 14:46:10 suspend start — the freeze is
blocked on the hung VHCI — and the journal ends at 14:46:56 with the forced
power-off.
Other observations
- Keyboard/trackpad input was dead the entire time; the power button (ACPI/EC
path) still woke the display, which is how the lock screen cursor could be
toggled while the keyboard stayed unresponsive. - No oops, no memory pressure, no NVMe/filesystem errors in the same window.
- The user-session sleep-lock service (
omarchy-sleep-lock.service) crash-looped
with "Failed to inhibit: The operation inhibition has been requested for is
already running" throughout — downstream symptom of the wedged suspend, not a
cause. - After the forced reboot the driver behaves normally again.
Questions / suggestions
- What is system event 0x50? The
Unhandled system event: 50 s=0 p1=0 p2=0
message 0.3 s beforePM: suspend exitis the only observable difference
between this resume and the four healthy ones, so it looks like the T2 was
already signalling a state the driver did not track. - Could
t2bce_vhcirecover from a command-cancel timeout instead of staying
permanently desynced — e.g. tear down and re-enumerate the virtual bus (the
equivalent of the "HC died" path), so the keyboard comes back without a
forced power-off? As it stands the hang also blocks the next suspend, which
turns a driver glitch into an unclean shutdown.
Happy to provide the full journal for the affected boot or test patches.
Activity
xzedx commentedon Sep 2, 2026
Confirming this on a MacBookPro16,1 with the same stack, and adding a second, silent variant of what looks like the same underlying desync — plus a strong correlation with the Touch Bar being in its DRM USB configuration.
Setup
linux-t2 7.1.8.arch1-3(7.1.8-arch1-Watanare-T2-3-t2), t2bce v0.06mem_sleep: deep (S3),pm_async=offhid-appletb-kbd) or DRM mode (config 2,appletbdrmbound, tiny-dfr daemon)Variant A — exactly this issue (event 50 at resume)
2026-09-01 21:19, resume from a 36-min S3 sleep, config 2. Keyboard re-enumerates, then:
Internal keyboard/trackpad dead; forced power-off 8 s later.
Variant B — same desync, no event-50 prodrome (hit twice)
Twice (2026-08-31 21:51 and 2026-09-01 16:02) the resume itself looked completely clean — no
Unhandled system event, nocommand timed out req=anywhere in the boot — but the next suspend entry failed:bridgeOS answers
SAVE_STATE_AND_SLEEP_REJECTED, the no-state fallback tears the VHCI down mid-suspend, every cancel times out, and after the (successful-looking) wake the whole internal USB bus is gone — keyboard/trackpad dead, forced power-off. It reads like the T2 was already silently out of sync since the previous resume, and the rejected stateful payload is just where it finally surfaces.Note: after a Variant-B failure the T2 is not wedged — the next boot suspends fine, no SMC reset needed.
Correlation with Touch Bar mode (same machine, same kernel, interleaved over 3 days)
appletbdrm+ tiny-dfr)PM: suspend entryappletbdrm)Not correlated with: pre-sleep teardown hooks (failures both with
systemctl stop tiny-dfr/modprobe -r appletbdrmhooks and with none at all), time since previous resume (failures at 2.5–11 min; successes at 16 s–77 min), or sleep length. Config 2 adds appletbdrm's bulk endpoints plus the touch HID interface, i.e. more transfer queues in play, which would fit a cancellation/resume race being more likely to hit.Question for @deqrocks
deqrocks/t2bce
a973d53("t2bce_vhci: resume endpoint before cancelled URB giveback", 2026-08-10) and unmerged PR deqrocks/t2bce#5 both target this race, but the vendored snapshot in linux-t2-patches (1001-Add-t2bce-driver-stack.patch, last updated 2026-08-07) still has the old giveback-before-resume ordering — so 7.1.8 and 7.2.2 builds all ship without it. Isa973d53expected to cover both variants above, and could the snapshot be refreshed? Happy to test a rebuilt t2bce out of tree — with the config-2 correlation above this reproduces within a day of normal use.Full journals for all cycles available on request.
deqrocks commentedon Sep 2, 2026
The repo I offer contains the code which I think is stable. When T2linux still uses older code this is their decision. Also not sure here about Omarchy. I will not support DHH/Omarchy community since they are vibe coding the living snot out of my code. Nobody knows what's going on there and I don't wanna know. Your comment even is vibe coded. Leave me alone with your shit.