# DF-5027 — ipsd_dump() reports fake success when the poll never completes (ips_disk.c)

**File:** `sys/dev/raid/ips/ips_disk.c` (pass 2)
**Lines:** 249-271 (dump loop), 261-264 (COMMAND_ERROR on a zeroed status),
326-336 (completion callback that never runs on copperhead)
**Class:** crash-dump integrity / silent data loss (CWE-252 / CWE-754);
sibling of DF-4616 (morpheus poll-window), distinct mechanism (copperhead
poll is a stub) and distinct file.

## Mechanism (source, deterministic on copperhead)

1. `ips_get_free_cmd()` hands out a command with `status` bzero'd
   (ips.c:232), so `COMMAND_ERROR(&command->status)` (basic_status 0 < 2)
   can never fire until a completion fills it.
2. `ipsd_dump_map_sg` issues the command and calls
   `sc->ips_poll_cmd(command)` (ips_disk.c:321-322).
3. On copperhead adapters `ips_poll_cmd` = `ips_copperhead_poll` — an
   **unimplemented stub that only kprintfs** (ips.c:810-814). No completion
   is ever delivered; `ipsd_dump_block_complete` (which would unload the
   map) never runs.
4. `ipsd_dump` then checks only `COMMAND_ERROR` (ips_disk.c:261-264) — sees
   the zeroed status, judges success, and loops: re-issuing into a command
   slot the adapter may still own and re-`bus_dmamap_load`ing a map that was
   never unloaded (undefined per bus_dma(9)).
5. Result: a copperhead crash dump can be an empty/interleaved-corrupt file
   while every block reported success — forensics/dump confidentiality-
   relevant integrity loss, silently.

## Why not reproduced at runtime

Dump path needs an IPS adapter (absent — env.txt) AND a crash dump. The code
chain is unconditional (no timing): stub → zeroed status → false success.

## Fix

`fix.diff`: `ipsd_dump_block_complete` sets `command->completed = 1`;
the dump loop requires `completed != 0` (else EIO + break) and resets the
flag per iteration. Copperhead dumps now fail loudly (EIO) instead of lying;
morpheus dumps are unaffected (poll delivers the completion). Compile-
validated in the patched ips.ko build (`-Werror` clean).
