Skip to content

feat(hdd): APA and BDM-ATA coexist -- remove the exclusivity policy + real APA retry (HW batch S1/S2) - #249

Merged
NathanNeurotic merged 3 commits into
masterfrom
claude/hdd-coexist
Jul 21, 2026
Merged

feat(hdd): APA and BDM-ATA coexist -- remove the exclusivity policy + real APA retry (HW batch S1/S2)#249
NathanNeurotic merged 3 commits into
masterfrom
claude/hdd-coexist

Conversation

@NathanNeurotic

@NathanNeurotic NathanNeurotic commented Jul 21, 2026

Copy link
Copy Markdown
Owner

APA and ATA are still blocking each other - they should be able to coexist. POPSLoader has them coexisting and populating - we have no excuse.

The triage proved it (verified): the mutual block was 100% our own EE-side policy — there is no driver conflict. Our "ps2atad" is the SDK's ata_bd build: it registers the drive with BDM while exporting the atad library ps2hdd links against. One shared stack already serves both — exactly how wLaunchELF-R3Z3N, NHDDL, and POPSLoader ship it.

Removed (S1): the Device-Settings interlock (seed + live re-grey), the F-12 load-time reconcile that force-zeroed one flag (+ its popup plumbing; the lang label stays — positional/append-only), and the forced APA-disable on ATA boot (the boot-device auto-enable stays). Kept, doctrine: hddDetectNonSonyFileSystem — the per-drive corruption guard that keeps APA off MBR/GPT/exFAT drives — and BDM's own "publish massN: only where a FAT/exFAT partition exists".

Added (S2 — the empty APA page): the APA list was one-shot at boot; a first touch racing drive spin-up (MC boot hits ATA seconds after power-on) left the page empty all session with nothing retrying — and no massN: for BDM-ATA either, which reads on hardware as "they block each other". Now hddUpdateGameList self-heals (idempotent module/support reload before scanning — wLE-R3Z3N parity: latch on success only, retry per use; one toast per failure streak), and xhdd's partition-sector devctl re-probes via sceAtaInit instead of DMA-ing against a dead devinfo.

Known residual (documented): the SDK ata_bd latches its init even on a failed probe; a mid-_start spin-up race can still need a reboot — fully clearing that needs a fork-patched/vendored atad (next PR if HW still shows it). Concurrency caveat carried in the commit: if hybrid-drive instability appears with both stacks live, the fix is a semaphore in that atad patch — never re-adding the exclusivity policy. #241 stays (verified correct; reverting recreates the Vapor poison).

Companion PRs from the same batch: #247 (S4), #248 (S3/S5/S6/S7).

Builds clean. HW-pending: the dual-HDD rig.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added/retained a network notification popup for DHCP-based UDP connections.
  • Bug Fixes
    • Prevented repeated identical HDD support error toasts across consecutive refresh attempts.
    • Added an extra device readiness verification (with a bounded retry) before reading partition sector data.
  • Improvements
    • Notification popups and their timeouts were refined to remove the obsolete HDD reconciliation notification.
    • HDD game list refresh now attempts support-module initialization when support isn’t ready.
    • APA and BDM-HDD settings can now be enabled together without automatic conflict resolution.

… give the APA page real retry (HW batch S1+S2)

Maintainer directive (2026-07-21): "APA and ATA should be able to coexist. POPSLoader has them
coexisting and populating - we have no excuse." Root-caused by the triage workflow (verified): the
mutual block was 100% OUR EE-side policy, not a driver conflict -- OPL's "ps2atad" is the SDK's
ata_bd build, which registers the drive with BDM while exporting the atad library ps2hdd links
against; one shared stack already serves both, exactly like wLaunchELF-R3Z3N, NHDDL and POPSLoader.

REMOVED (S1): the Device-Settings interlock (gui.c seed lines + the guiDeviceUpdater live re-grey),
the #120-audit F-12 load-time reconcile that force-zeroed one flag (opl.c, + its
showHddReconcilePopup plumbing; the _STR_HDD_BACKEND_RECONCILED label STAYS in _base.yml -- labels
are positional and append-only), and the forced APA-disable on an ATA boot (the boot-device
auto-enable stays). Per-DRIVE arbitration is untouched and remains the doctrine:
hddDetectNonSonyFileSystem keeps APA off MBR/GPT/exFAT drives (corruption guard), BDM publishes
massN: only where a FAT/exFAT partition exists.

ADDED (S2, the empty-APA-page session): the APA list was ONE-SHOT at boot -- an hddInitModules first
touch that raced drive spin-up (MC boot touches ATA seconds after power-on) left the page empty with
NOTHING retrying for the whole session (and no massN: for BDM-ATA either, which reads on HW as "they
block each other"). Now:
- hddUpdateGameList self-heals: if the support stack is not loaded, re-run hddLoadModulesReady() +
  hddLoadSupportModules() before scanning (both idempotent; the failed-load count is retryable
  post-#241) -- wLaunchELF-R3Z3N parity: latch only on success, retry per use. One toast per failure
  streak (hddSupportErrToasted), reset on recovery.
- xhdd's READ_PARTITION_SECTOR devctl (the EE side's readiness probe) re-probes via sceAtaInit before
  the transfer instead of DMA-ing against a dead devinfo -- a latched no-op on healthy paths.

KNOWN RESIDUAL (documented, next PR if HW still shows it): the SDK ata_bd latches its device-info
init even on a failed probe, so an in-flight spin-up race at _start can still need a reboot to clear
-- fully fixing that needs a fork-vendored/patched atad (same .patch mechanism as the mmceman fixes).
The retries above cover every post-probe failure; ship and see what HW says. Concurrency note carried
from the review: with both stacks live, pfs and bdmfs reads can interleave ATA commands (the three
reference implementations never issue concurrent IO) -- if hybrid-drive instability appears, the fix
is a semaphore in the atad patch, NOT re-adding the exclusivity policy.

Do NOT revert #241 (BUSYLOADING-as-failure verified correct; reverting recreates the Vapor poison).

Builds clean (make opl.elf, exit 0). HW-pending: Nathan's dual-HDD rig.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a0516173-f78c-46a3-855f-4716a70d3585

📥 Commits

Reviewing files that changed from the base of the PR and between b74cd26 and f9676ad.

📒 Files selected for processing (2)
  • modules/hdd/xhdd/xhdd.c
  • src/hddsupport.c
📜 Recent review details
⏰ Context from checks skipped due to timeout. (20)
  • GitHub Check: build-debug (iopcore_ppctty_debug, :v20250725-2)
  • GitHub Check: build-lang
  • GitHub Check: build-debug (iopcore_debug, :v20250725-2)
  • GitHub Check: build-debug-ps2dev-latest (iopcore_ppctty_debug)
  • GitHub Check: build-debug (eesio_debug, :v20250725-2)
  • GitHub Check: build-debug-ps2dev-latest (ingame_debug)
  • GitHub Check: build-debug (DTL_T10000=1, :v20250725-2)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=0, PADEMU=1)
  • GitHub Check: build-debug-ps2dev-latest (eesio_debug)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=1, PADEMU=1)
  • GitHub Check: build-debug-ps2dev-latest (iopcore_debug)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=0, PADEMU=0)
  • GitHub Check: build-debug-ps2dev-latest (ingame_ppctty_debug)
  • GitHub Check: build-debug-ps2dev-latest (DTL_T10000=1)
  • GitHub Check: build-variants (EXTRA_FEATURES=1, PADEMU=1)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=1, PADEMU=0)
  • GitHub Check: build-variants (EXTRA_FEATURES=1, PADEMU=0)
  • GitHub Check: build-variants (EXTRA_FEATURES=0, PADEMU=1)
  • GitHub Check: build
  • GitHub Check: build-ps2dev-latest
🔇 Additional comments (2)
src/hddsupport.c (1)

38-41: LGTM!

Also applies to: 338-343, 352-381, 587-600

modules/hdd/xhdd/xhdd.c (1)

55-66: LGTM!


📝 Walkthrough

Walkthrough

The changes remove APA/BDM-HDD interlock and reconciliation notifications, rate-limit HDD support errors, retry failed support-module initialization, and verify ATA device presence before partition-sector DMA reads.

Changes

HDD coexistence and notification updates

Layer / File(s) Summary
APA/BDM coexistence and notification cleanup
include/opl.h, src/opl.c, src/gui.c
APA and BDM-HDD settings are no longer normalized against each other. The reconciliation popup flag and related notification handling are removed, and both device controls remain enabled.
HDD support failure recovery
src/hddsupport.c
Failure toasts are limited to one per failure streak, reset after successful loading, and support modules are retried when game-list updates find them unavailable.
ATA partition read validation
modules/hdd/xhdd/xhdd.c
ATA partition reads reinitialize the device and return -ENODEV when it is unavailable before beginning DMA.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the PR's main change: removing APA/BDM-ATA exclusivity and adding retry logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/hdd-coexist

Comment @coderabbitai help to get the list of available commands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request removes the mutual exclusivity between APA and BDM-ATA HDD modes, allowing them to coexist, and implements self-healing retry logic for support-module loading to handle boot-time drive spin-up races. The review feedback highlights two main improvements: guarding the support-module loading with a check on the base module readiness to prevent redundant error toasts, and refactoring nested conditional assignments in xhdd.c to improve code readability.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/hddsupport.c
Comment on lines +591 to +594
if (!hddSupportModulesLoaded) {
hddLoadModulesReady();
hddLoadSupportModules();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The return value of hddLoadModulesReady() is ignored here. If the base modules fail to load, calling hddLoadSupportModules() unconditionally will trigger a second, redundant error toast (ERROR_HDD_NOT_DETECTED on top of ERROR_HDD_IF_NOT_DETECTED). You should guard the call to hddLoadSupportModules() with a check on hddLoadModulesReady().

Suggested change
if (!hddSupportModulesLoaded) {
hddLoadModulesReady();
hddLoadSupportModules();
}
if (!hddSupportModulesLoaded) {
if (hddLoadModulesReady()) {
hddLoadSupportModules();
}
}

Comment thread modules/hdd/xhdd/xhdd.c Outdated
Comment on lines +60 to +62
if ((devinfo = sceAtaInit(fd->unit)) == NULL || !devinfo->exists)
if ((devinfo = sceAtaInit(fd->unit)) == NULL || !devinfo->exists)
return -ENODEV;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The nested if statements without braces and with assignments inside the conditions are hard to read and prone to errors. It is highly recommended to separate the assignment from the condition and use explicit braces for nested blocks to improve readability and maintainability.

            devinfo = sceAtaInit(fd->unit);
            if (devinfo == NULL || !devinfo->exists) {
                devinfo = sceAtaInit(fd->unit);
                if (devinfo == NULL || !devinfo->exists) {
                    return -ENODEV;
                }
            }

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/hddsupport.c`:
- Around line 338-341: Reset hddSupportErrToasted when the non-Sony probe
succeeds in the nonSony > 0 path, so a later APA failure can display a new error
toast. Preserve the existing failure handling for nonSony < 0 and only clear the
latch on a valid successful probe.
- Around line 585-595: Update the retry block around hddLoadModulesReady() so
hddLoadSupportModules() is called only when hddLoadModulesReady() reports
readiness. Preserve the existing hddSupportModulesLoaded guard and retry
behavior, but do not probe xhdd0: while the lower-level modules are still
loading or have failed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b16d3332-40e3-4523-bcca-76cf167d054e

📥 Commits

Reviewing files that changed from the base of the PR and between 6348662 and 3827e0c.

📒 Files selected for processing (5)
  • include/opl.h
  • modules/hdd/xhdd/xhdd.c
  • src/gui.c
  • src/hddsupport.c
  • src/opl.c
💤 Files with no reviewable changes (1)
  • include/opl.h
📜 Review details
⏰ Context from checks skipped due to timeout. (10)
  • GitHub Check: build-debug-ps2dev-latest (iopcore_ppctty_debug)
  • GitHub Check: build-debug-ps2dev-latest (ingame_ppctty_debug)
  • GitHub Check: build-debug-ps2dev-latest (ingame_debug)
  • GitHub Check: build-debug-ps2dev-latest (eesio_debug)
  • GitHub Check: build-variants (EXTRA_FEATURES=0, PADEMU=1)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=1, PADEMU=1)
  • GitHub Check: build-variants (EXTRA_FEATURES=0, PADEMU=0)
  • GitHub Check: build
  • GitHub Check: build-lang
  • GitHub Check: build-ps2dev-latest
🔇 Additional comments (9)
src/opl.c (3)

198-198: LGTM!


1706-1713: LGTM!


1805-1807: LGTM!

src/gui.c (3)

305-358: LGTM!


1227-1228: LGTM!


1282-1283: LGTM!

src/hddsupport.c (2)

38-41: LGTM!


350-379: LGTM!

modules/hdd/xhdd/xhdd.c (1)

55-63: LGTM!

Comment thread src/hddsupport.c
Comment thread src/hddsupport.c
… definitive probe + xhdd retry braces (bot sweep of #249 -- all vetted)

- hddUpdateGameList retry now gates hddLoadSupportModules on hddLoadModulesReady() -- a failed base
  load no longer double-toasts on its first pass (Gemini high + CodeRabbit major, same finding).
- A SUCCESSFUL non-Sony probe (genuine MBR/GPT) clears hddSupportErrToasted -- a later, different
  failure is new news and deserves its own toast (CodeRabbit minor).
- xhdd re-probe restructured with explicit braces, assignment out of the condition (Gemini style).

Builds clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@NathanNeurotic
NathanNeurotic merged commit 8ac163f into master Jul 21, 2026
61 checks passed
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.

1 participant