# DF-4841 — post-reset OBFL refill is a no-op: `sense_bufs[].posted` survives the soft reset, leaving the firmware with zero response frames

sys/dev/raid/tws/tws_hdm.c:118-148 (`tws_init_obfl_q`) + the reset/recovery
path tws_cam.c:1198-1266.

## What

`sense_bufs[i].posted` tracks "this response frame is currently in the
firmware's outbound free list". At attach, `tws_init_reqs()` clears all
flags (tws.c:620) and `tws_init_ctlr()` → `tws_init_obfl_q()`
(tws_hdm.c:111) posts all 256 frames.

The reset recovery path (`tws_reset` → `tws_reset_cb` → `tws_reinit`,
tws_cam.c:1198-1266) exists precisely because a soft reset reinitializes
the controller's message unit — the firmware's copy of the free list is
gone. `tws_reinit()` resets `obfl_q_overrun`, re-runs
`tws_init_connect()` and calls `tws_init_obfl_q()` (tws_cam.c:1262-1266)
to refill the queue. **But `posted` is still true for every frame** —
nothing on the reset path clears it (grep: cleared only at attach,
tws.c:620, and on an OBFL-overrun repost failure, tws_cam.c:543). The
"refill" loop

```c
tws_hdm.c:127-144
    while ( i < tws_queue_depth ) {
        if ( !sc->sense_bufs[i].posted ) {   /* never taken */
            ... post frame ...
            sc->sense_bufs[i].posted = true;
```

posts nothing. The firmware is left with **zero** outbound free frames:

- `tws_init_connect()` itself polls up to 60 s (TWS_POLL_TIMEOUT) for a
  response it can never receive → recovery burns a full minute then
  fails (and per DF-1926 also leaks the internal request slot).
- Even if recovery "completes", every subsequent command submission
  cannot be answered — all I/O to the adapter times out permanently.
  The adapter and everything on it is dead until reboot.

One reset — triggered by any controller error that reaches `tws_reset()`
(bus reset, firmware fault, the unguarded re-entry of DF-4401, DF-4590's
callout storm) — converts a recoverable hiccup into a permanent hang of
the storage path.

## Verification status

**Not reproduced on the audit guest — hardware-gated.** The audit guest
has no LSI/AVC 3ware 9750 PCI device, QEMU does not emulate one, and tws
is compiled into X86_64_GENERIC with nothing attached
(guest_probe.log: `NO_3WARE_PCI`, `dev.tws` absent). The defect is
certain from the driver's own code shape: the recovery path resets
`obfl_q_overrun` and re-runs the refill function *intending* to
re-post, while the state that makes the refill a no-op is left
untouched — the two cannot both be correct, and if the flags were
correct as-is (queue survives reset) the refill call would be pointless.

## Fix

`fix.diff` — clear the `posted` flags on the reset path
(`tws_reset_obfl_q()` in tws_hdm.c, called from `tws_reinit()` before
`tws_init_obfl_q()`). Deliberately NOT done inside
`tws_init_obfl_q()` itself: its other caller (`tws_submit_command()` on
OBFL overrun, tws_hdm.c:282-284) must not double-post frames still
queued. git-apply clean; not runtime-testable (no controller).

## Run (for a maintainer with hardware)

1. Put the adapter into reset recovery (e.g. `camcontrol reset` on the
   tws sim, or a controller fault).
2. Stock kernel: watch the recovery spin in `tws_init_connect`'s poll
   for TWS_POLL_TIMEOUT, then all I/O hang (`iostat` flatlines, every
   ccb times out).
3. Patched kernel: recovery completes and I/O resumes.
