Skip to content

feat(sbp2): complete SBP-2 login, command transport, and INQUIRY flow#14

Closed
gly11 wants to merge 49 commits into
mrmidi:mainfrom
gly11:feature/sbp2-e2e-asfw
Closed

feat(sbp2): complete SBP-2 login, command transport, and INQUIRY flow#14
gly11 wants to merge 49 commits into
mrmidi:mainfrom
gly11:feature/sbp2-e2e-asfw

Conversation

@gly11

@gly11 gly11 commented May 6, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR brings up the complete SBP-2 initiator stack — login, command transport, and end-to-end INQUIRY — together with the async TX/RX and bus robustness fixes that were developed alongside it.

SBP-2 Protocol

  • Wire formats (Login/Reconnect/Logout ORB, Normal Command ORB, page table, status block, management ORB)
  • Login session state machine with reconnect after bus reset
  • ORB submission via fetch agent + doorbell, chained and immediate modes
  • Page table builder with direct-addressing optimization
  • Address space manager with DMA backing and remote read/write callbacks
  • Session registry for multi-target management
  • SCSI command helpers (INQUIRY, TEST UNIT READY, REQUEST SENSE)
  • SBP-2 unit detection from Config ROM
  • Swift API and debug UI (DriverConnector+SBP2, SBP2DebugView)

Async TX/RX Foundations

  • Read response sender and packet routing
  • Full 16-bit generation for response matching
  • OHCI ACK semantics normalization and OUTPUT_MORE handling

Bus & Diagnostics

  • Re-assert cycleMaster after cycle-too-long and bus reset, short/long reset support
  • PHY contender bit always enabled (matches Linux/Apple defaults)
  • Diagnostics handler for bus state, PHY registers, and bus reset events
  • Bus reset diagnostics with recovery metrics and automated recovery resets

Tests

  • SBP-2 ORB, login session, and session registry tests
  • Address space manager and convergence tests
  • Transaction storage tests

Fixes

  • Management_Agent_Offset key correction, AR DMA byte order, bus reset timing
  • ORB layout validation and submit tightening
  • Timer callback lifetime races eliminated
  • Pre-login path for scanner-first SBP-2 bring-up

Why a single PR

The async infrastructure, bus fixes, and SBP-2 protocol were developed iteratively on one branch — several commits touch both layers. The async response sender and bus robustness work were purpose-built for SBP-2 bring-up rather than standalone improvements. Splitting would require manually reconstructing intermediate states of ~15 shared files without adding value for the reviewer.

If you'd prefer the async/bus foundations and SBP-2 protocol in separate PRs, happy to split — just let me know.

Verification

./build.sh --no-bump
./build.sh --no-bump --test-only

gly11 and others added 30 commits February 13, 2026 19:01
# Conflicts:
#	ASFW/ASFWDriverConnector.swift
#	ASFWDriver/Async/AsyncSubsystem.cpp
#	ASFWDriver/Controller/ControllerCore.cpp
#	ASFWDriver/Controller/ControllerCore.hpp
#	ASFWDriver/Service/DriverContext.cpp
#	ASFWDriver/UserClient/Core/ASFWDriverUserClient.cpp
#	ASFWDriver/UserClient/Core/ASFWDriverUserClient.iig
#	tests/CMakeLists.txt
Call DriverWiring::EnsureSbp2Deps() after FCPResponseRouter setup
to initialize SBP2 AddressSpaceManager and register PacketRouter
handlers for quadlet/block read/write requests (tCode 0x0/0x1/0x4/0x5).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix ARPacketView→BlockWriteRequestView conversion in block write
  handler (was passing raw ARPacketView to RouteBlockWrite)
- Fix FCPResponseRouter constructor: use ControllerCore::Bus() instead
  of GetGenerationTracker() (wrong type, missing IFireWireBusInfo)
- Add missing IFireWireBus.hpp include for derived-to-base conversion
- Add DriverConnector+SBP2.swift with 4 Swift API methods for SBP2
  address space management (allocate, deallocate, read, write)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Per Linux firewire_ohci and Apple IOFireWireController, the contender
bit is always set during init. This is required for proper bus management
(IRM election, cycle-start generation), especially in 2-node topologies.
Delegation policy remains controlled by the experimental flag.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restore explicit PHY bus reset in EnableInterruptsAndStartBus() that was
previously removed — the auto reset from linkEnable alone may not reliably
activate the Config ROM shadow on all controllers.

Add SBP-2 protocol layer ported from Apple IOFireWireSBP2:
- SBP2WireFormats.hpp: big-endian wire structures (LoginORB, LoginResponse,
  ReconnectORB, LogoutORB, NormalORB, PageTableEntry, StatusBlock,
  TaskManagementORB) plus constants and helper functions
- SBP2LoginSession: full login/reconnect/logout state machine with retry
  logic (up to 32 retries), bus reset handling, and address space
  allocation for ORB/response/status buffers

Add SBP2 logging category.

Co-Authored-By: zcode <noreply@zcode.dev>
…r infrastructure

- Fix Reconnect/Logout ORBs using their own meta instead of statusBlockMeta_
  for the status FIFO address. Device would write status blocks to wrong addr.
- Fix kExclusiveLogin bit: 0x2000 (bit 13 per SBP-2 Table 14), not 0x0020.
- Add RemoteWriteCallback to AddressSpaceManager so SBP2LoginSession gets
  notified when device writes status blocks to its address space.
- Fix login response read timing: OnLoginWriteComplete now only ACKs the
  management agent write and waits for the status block callback instead of
  immediately reading the login response (which is empty at that point).
  New OnStatusBlockRemoteWrite dispatches to state-specific handlers.
- Wire SubmitDelayedCallback to IODispatchQueue (DispatchAsync + IOSleep
  pattern matching BusResetCoordinator), replacing the no-op placeholder.
…cture

Add Normal Command ORB (SBP2CommandORB) with prepare-for-execution,
page table binding, and chain management. Port SBP2PageTable from
Apple IOFireWireSBP2ORB scatter-gather logic with direct-address
optimization for single-PTE cases. Extend SBP2LoginSession with
SubmitORB, fetch agent write, doorbell ring, and ORB completion
via status block dispatch.
Delete .bak/.bak2 documentation files and fixlog.sh that were
left over from bus reset development.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
IEEE 1394 generation values range 0–16383 (14 bits), which overflows
uint8_t. Use the 16-bit accessor to avoid truncation after generation
128+.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…t short/long bus reset

OHCI hardware auto-clears cycleMaster when cycleTooLong fires (OHCI
§6.2.1). Per Linux irq_handler, re-assert it immediately to keep
cycle-start packets flowing — devices like Nikon SAA7356HL depend on
them for firmware download.

Also re-assert in StepRearming (per Linux bus_reset_work) and
implement HardwareInterface::InitiateBusReset with proper short
(IEEE 1394a PHY reg 5 SBR) and long (PHY reg 1 IBR) reset paths.

Add ControllerCore diagnostic accessors and BusResetCoordinator::
RequestUserReset for UserClient-initiated resets.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… reset UserClient methods

New handler exposes three methods (selectors 50–52):
- GetBusStateDiagnostics: OHCI registers, topology, PHY, FSM state
- ReadPhyRegister: direct PHY register read (addr 0–7)
- InitiateBusReset: user-initiated short/long bus reset

Includes BusStateWire packed struct (64 bytes) and full lifecycle
wiring in UserClientRuntimeState.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…, fix CBA offsets

- Add SBP2ManagementORB for AbortTask/AbortTaskSet/LogicalUnitReset/TargetReset
  with per-ORB status FIFO, timeout via IODispatchQueue, BE wire conversion
- Fix CBA register offsets to match Apple (AgentReset=+0x04, FetchAgent=+0x08,
  Doorbell=+0x10, UnsolicitedStatusEnable=+0x14)
- Add ResetFetchAgent() for error recovery via CBA quadlet write
- Add EnableUnsolicitedStatus() with deferred-enable after login/reconnect
- Compute CBA-derived addresses once at login, not per-ORB
- Unsolicited status auto-re-enables and is consumed after reconnect
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
SBP2CommandORB::inProgress_ and SBP2ManagementORB::inProgress_/timerActive_
were plain bools accessed from both the IODispatchQueue timer thread and
caller/destructor threads. Use std::atomic<bool> with relaxed ordering to
avoid undefined behavior while the existing generation counter handles
logical synchronization.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Added SubmitSBP2Command and GetSBP2CommandResult methods to SBP2Handler for command submission and result retrieval.
- Introduced SBP2CommandWireFormats.hpp to define wire formats for SBP-2 command requests and results.
- Extended DeviceDiscoveryWireFormats to include management agent offset, LUN, unit characteristics, and fast start fields.
- Created SBP2SessionRegistryTests to validate command submission and response handling.
- Updated documentation to reflect the current state and goals of the SBP-2 scanner integration.
…r signature

CompletionCallback was changed to void(int, uint8_t) but test lambdas
still used the old void(int) signature, causing build failures.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
gly11 and others added 19 commits April 22, 2026 21:50
…d bus reset timing

SBP-2 Management_Agent_Offset now uses the combined IEEE 1212 CSR key
0x54 (keyType=1, keyId=0x14) matching real devices like Nikon, with 0x38
retained as a legacy fallback. AR DMA test helpers now correctly use
little-endian byte order matching OHCI hardware. Bus reset discovery
always applies a 100ms baseline delay matching Apple ScanBus behavior.
Cycle master is disabled by default; explicit PHY bus reset removed in
favor of linkEnable auto reset.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- fix OHCI AR DMA block data-length decoding and copy misaligned request payloads into aligned scratch buffers
- encode local-bus 16-bit node IDs in SBP-2 login, management, command, and page-table ORB embedded addresses
- release owner-bound SBP-2 address-space resources on user client Stop/free to avoid stale allocation conflicts
- add host coverage for address-space writes, FCP parsing, and SBP-2 ORB layout/address encoding, and sync the roadmap with current verification status
@gly11 gly11 marked this pull request as ready for review May 6, 2026 04:54
@gly11

gly11 commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

I split this larger PR into smaller stacked PRs so each layer can be reviewed independently:

I also prepared a few follow-up slices locally, but have not pushed them yet pending review:

  • controller/OHCI bring-up defaults
  • Swift SBP-2 connector API
  • unaligned bus-reset capture handling

Local debug UI, diagnostic handlers, install helpers, scripts, and documentation experiments are intentionally excluded from the remote PR stack.

@mrmidi

mrmidi commented May 27, 2026

Copy link
Copy Markdown
Owner

I split this larger PR into smaller stacked PRs so each layer can be reviewed independently:

I also prepared a few follow-up slices locally, but have not pushed them yet pending review:

  • controller/OHCI bring-up defaults
  • Swift SBP-2 connector API
  • unaligned bus-reset capture handling

Local debug UI, diagnostic handlers, install helpers, scripts, and documentation experiments are intentionally excluded from the remote PR stack.

Thanks!

@gly11 gly11 closed this May 31, 2026
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.

2 participants