# DF-4060 — amr_std_poll_command timeout leaks the slot as permanently busy

**Status: REPRODUCED** (guaranteed follow-on panic via production
`amr_start`; completion callback + status stores into a free-listed command;
rescan_drives livelock precondition) — production-handler KLD dispatch rig
(shared with DF-4059), no MegaRAID hardware needed. Fix validated on a
rebuilt kernel. See `VERDICT.md`.

## What runs

Same rig as DF-4059 (`dfamr_rig.c`, root-only `/dev/dfamr0`): fabricated
post-attach softc with real bus_dma, production command clusters, production
`amr_std_poll_command` / `amr_start` / `amr_alloccmd` / `amr_releasecmd` /
`amr_done` dispatched from the shipped kernel image. The stall condition is
modeled exactly: the virtual card accepts the posted command and never
raises a completion.

## Build

    findings/poc/DF-4060/build.sh        # same rig as DF-4059

## Run (baseline)

    ./dfbsd-qemu/vm.sh run_root 'cd /root/rig && kldload ./dfamr_rig.ko && \
        ./dfamr_ctl prime && ./dfamr_ctl offs && ./dfamr_ctl magic && \
        ./dfamr_ctl tmo 0 && ./dfamr_ctl late'
    # deterministic panic finale (last, guest dies):
    ./dfbsd-qemu/vm.sh run_root 'cd /root/rig && ./dfamr_ctl tmo 1'

## Expected results

* baseline `tmo 0`: poll_err=EIO after ~103 ticks; after timeout
  BUSY still set, busycmd[slot]==ac, busyslots==1; after the caller's
  releasecmd the still-busy command is the freelist head; 100x amr_done
  never drains busyslots (rescan_drives amr.c:460 livelock precondition);
  the next amr_alloccmd returns the same command
* baseline `tmo 1`: `panic: amr: slot 2 busy?` at amr_start+0x18b
  (amr.c:1742-1743) — guest dead
* baseline `late`: production amr_done completes the stale id into the
  free-listed command: status 0x77 stored, completion callback fired while
  the command is still on amr_freecmds (two owners)
* patched (fix.diff): timeout detaches the slot (busyslots=0, busycmd
  cleared, BUSY cleared); `tmo 1` returns start_err=0, no panic; late
  completion tolerated as "bad slot 2 completed"; guest alive

## Fix

`fix.diff` (shared with the DF-4059 pack): detach the slot under
amr_hw_lock on the `amr_std_poll_command` timeout path (guarded on
`busycmd[slot] == ac`) and clear AMR_CMD_BUSY.
