Fix for SATA drives (especially newer models like WD Red Plus) that disappear after a soft reboot on Mac Pro 5,1 (and potentially other systems using the Intel ICH10 AHCI controller) running macOS Sequoia via OpenCore Legacy Patcher.
After a soft reboot (sudo reboot), certain SATA drives connected to the ICH10 AHCI controller (PCI 00:1F.2, device-id 0x3a22) fail to appear in macOS. The drive only works after a full shutdown + power-on or an SMC reset.
This affects drives in the Mac Pro's optical bay and potentially other ICH10 ports. The issue does not affect drives on the secondary AHCI controller (0B:00.0) which has native hot-plug support.
The failure is a three-link chain in Apple's AppleAHCIPort kext:
The ICH10 controller's AHCI ports lack the AHCI Port Hot Plug capability flag. Without this, AppleAHCIPort never creates background hot-plug monitoring threads for these ports.
The Mac Pro 5,1 does not fully cut SATA bus power during a soft reboot. The SATA PHY link remains established (PxSSTS DET=3) from the previous boot session. The drive is technically "connected" at the physical layer but hasn't completed a fresh initialization handshake.
In EnablePortOperation, the driver enables FIS Receive (SetFRE(true)) then checks WaitForLinkPresent(). If a link is already present (DET=3), it skips HandleComReset() and goes directly to ScanForDevices(). But since the link is stale:
- PxSIG (Port Signature) contains garbage/stale data from the previous session
ScanForDeviceschecks PxSIG — if it's not0x00000101(ATA) or0xEB140101(ATAPI), it silently skips device creation- No
IOAHCIDeviceis published → no disk visible to macOS
After a full power cycle, the drive sends a fresh D2H Register FIS during link-up, populating PxSIG correctly. That's why cold boot always works.
Three components, all configured via OpenCore:
An ACPI SSDT that runs at early boot (_INI method) and takes ICH10 Port 1 offline:
- Reads the AHCI Base Address Register (ABAR) from PCI config space
- Checks if a stale link is present (DET=3)
- Stops the command engine (clears CMD.ST, waits for CMD.CR to clear)
- Takes the port offline (SCTL.DET=4), waits 100ms
- Returns to listen mode (SCTL.DET=0)
This breaks the stale link so the driver finds DET=0, triggering its own HandleComReset() with FIS Receive properly enabled.
Source: ACPI/SSDT-COMRESET.dsl
Compiled: ACPI/SSDT-COMRESET.aml
Patches AppleAHCIPort to create hot-plug monitoring threads on all AHCI ports, regardless of the controller's Hot Plug capability flag.
| Field | Value |
|---|---|
| Identifier | com.apple.driver.AppleAHCIPort |
| Comment | Force SATA Hot-Plug thread creation (Sequoia) |
| Find | F6836D010000 44 7446 |
| Replace | F6836D010000 44 9090 |
| Find (Base64) | 9oNtAQAARHRG |
| Replace (Base64) | 9oNtAQAARJCQ |
| MinKernel | 24.0.0 |
| Count | 1 |
What it does: NOPs a je (jump-if-equal) instruction that skips hot-plug thread creation when the port lacks the Hot Plug capability bit. After patching, all ports get threads.
Patches AppleAHCIPort to always call HandleComReset() during port initialization, even when a SATA link is already present.
| Field | Value |
|---|---|
| Identifier | com.apple.driver.AppleAHCIPort |
| Comment | Force HandleComReset on all AHCI ports (Sequoia) |
| Find | A801 7433 8BB388000000 |
| Replace | A801 9090 8BB388000000 |
| Find (Base64) | qAF0M4uziAAAAA== |
| Replace (Base64) | qAGQkIuziAAAAA== |
| MinKernel | 24.0.0 |
| Count | 1 |
What it does: NOPs a je instruction in EnablePortOperation that normally skips HandleComReset() when WaitForLinkPresent() succeeds. After patching, HandleComReset() always runs, ensuring a fresh COMRESET + D2H FIS exchange with FRE enabled.
- Mac Pro 5,1 (or similar system with ICH10 AHCI controller)
- macOS Sequoia (kernel 24.x) via OpenCore Legacy Patcher
- iasl (only if recompiling the SSDT)
-
Mount your EFI partition:
sudo diskutil mount disk<N>s1 # your boot disk's EFI partition
-
Copy the SSDT:
cp ACPI/SSDT-COMRESET.aml /Volumes/EFI/EFI/OC/ACPI/
-
Register the SSDT in
config.plistunderACPI → Add:<dict> <key>Comment</key> <string>COMRESET ICH10 Port 1 - break stale SATA link</string> <key>Enabled</key> <true/> <key>Path</key> <string>SSDT-COMRESET.aml</string> </dict>
-
Add the kernel patches in
config.plistunderKernel → Patch. Seeconfig-sample.plistfor the full XML snippets. -
Validate and reboot:
plutil -lint /Volumes/EFI/EFI/OC/config.plist sudo reboot
After reboot, check that the drive appeared:
diskutil list | grep -i "WD\|backup"Check kernel logs for COMRESET activity on the port:
log show --last boot --predicate 'sender == "AppleAHCIPort"' --info | grep "001F0210"You should see HandleComReset activity and IOAHCIDevice creation for the port.
The SSDT targets Port 1 (AHCI offset 0x180). To target a different ICH10 port, modify the OperationRegion offset in the DSL:
| Port | Offset |
|---|---|
| 0 | 0x100 |
| 1 | 0x180 |
| 2 | 0x200 |
| 3 | 0x280 |
| 4 | 0x300 |
| 5 | 0x380 |
Recompile with: iasl ACPI/SSDT-COMRESET.dsl
- Tested on: Mac Pro 5,1, macOS 15.x Sequoia, OpenCore Legacy Patcher
- Kernel: Darwin 24.x (set
MinKernelaccordingly for other versions) - Controller: Intel ICH10 AHCI (device-id
0x3a22) — may work with other Intel AHCI controllers lacking native hot-plug
Note: The kernel patch byte sequences are specific to macOS Sequoia (kernel 24.x). Other macOS versions will have different byte patterns and require re-analysis of the
AppleAHCIPortbinary.
Warm-reboot-only AHCI failures, including repeated IOAHCIBlockStorage CommandTimeout/WatchdogTimeout errors on probe commands like 0xEC and 0xF5, are not specific to a stale link or a skipped HandleComReset(); power, cabling, device, and controller faults can produce similar symptoms. Treat the stale-link path as a hypothesis, and confirm mechanism-specific evidence (such as DET=3 with stale PxSIG and the driver skipping HandleComReset()) before attempting invasive kernel patches.
Use the exact AppleAHCIPort binary from the target OS (for example Ventura 13.7.x), then re-derive offsets in disassembly:
- Copy the target binary:
cp /System/Library/Extensions/AppleAHCIPort.kext/Contents/MacOS/AppleAHCIPort ~/Desktop/AppleAHCIPort-target - Open in Hopper/Ghidra/IDA and find
EnablePortOperation(or the block that callsWaitForLinkPresent()andHandleComReset()). - If analysis confirms that this conditional jump skips
HandleComReset()in the affected case, patch only that jump (typically toNOP NOP). - Locate the hot-plug capability gate (
AHCI Port Hot Plugbit test) in the port-init path, and patch the jump that skips hot-plug thread creation. - Only after confirming the relevant mechanism and target-build control flow, build OpenCore
Find/Replacesignatures using surrounding bytes (not absolute offsets), withCount=1and kernel-range limits (MinKernel/MaxKernel) for that OS version.
Practical safety checks:
- Ensure each
Findpattern matches exactly once. - If a pattern matches multiple locations, include more neighboring bytes until unique.
- Bring patches up one at a time to isolate regressions.
The PHY-level stale-link break (PxSCTL.DET = 4 then 0) is AHCI-spec behavior and often portable across Intel AHCI controllers.
Platform-specific parts that must be revalidated:
- ACPI device path (
_SB.PCI0.SATAvsSAT0, etc.) - PCI BAR/ABAR access method in ACPI
- Actual port base offset (verify whether the
0x100 + port * 0x80formula applies) - Timing margins (
Sleep()values)
Avoid whole-device _PS0/_PS3 power-cycling unless validated on your board/firmware, since that path is much more platform-dependent and can boot-loop.
| Version | Approach | Failure |
|---|---|---|
| v1–v3 | COMRESET from ACPI with various delays | PxSIG never updated (FRE was off) |
| v4 | COMRESET + early exit if DET=3 | Skipped on soft reboot — DET was always 3 |
| v5 | Full SUD power cycle + COMRESET + long waits | FRE was off → D2H FIS lost → PxSIG remained stale |
| v6 | Break stale link only (DET=4→0) | Works — driver handles COMRESET with FRE enabled |
The key insight: ACPI runs before the driver enables FIS Receive. Any COMRESET done from ACPI will succeed at the PHY layer (link re-established, DET=3), but the drive's D2H Register FIS response is silently dropped because there's no FIS receive buffer to catch it. The driver then sees DET=3, assumes the existing link is valid, and reads stale PxSIG.
The solution is to not do COMRESET from ACPI. Instead, break the stale link and let the driver do its own COMRESET through HandleComReset(), which properly enables FRE first.
SSDT _INI: DET=4 (offline) → DET=0 (listen)
↓
Driver EnablePortOperation:
SetFRE(true) ← FIS Receive now enabled
WaitForLinkPresent → DET=0, no link
HandleComReset:
CMD.ST=0 ← Stop command engine
SCTL.DET=1 ← Issue COMRESET
sleep 1ms
SCTL.DET=0 ← Return to normal
WaitForLinkPresent → Drive re-links → DET=3
WritePxSERR(0xFFFFFFFF) ← Clear errors
↓
ScanForDevices:
PxSIG = 0x101 ← Fresh D2H FIS received (FRE was on!)
→ CreateDevice ← IOAHCIDevice published
↓
IOAHCIBlockStorage → disk appears in macOS
MIT