# DF-4867 — latent NULL `ctlr->setmode` call: `ata_intel_chipinit` treats any non-ENXIO return of `ata_ahci_chipinit` as AHCI success

- File: `sys/dev/disk/nata/chipsets/ata-intel.c`
- Severity: Info (hardening / fragile error-contract), confidence: certain (shape) / latent (reachability)
- Verdict: **not_reproduced** — traced dead on this tree (see VERDICT.md). Not a bug today; one refactor away from a boot-time NULL function-pointer call.

## What the finding is

`ata_intel_chipinit()` (ata-intel.c:177-180) probes for AHCI mode:

```c
if ((ctlr->chip->cfg1 == INTEL_AHCI) &&
    (pci_read_config(dev, 0x90, 1) & 0xc0) &&
    (ata_ahci_chipinit(dev) != ENXIO))
    return 0;
```

Any return value that is not exactly `ENXIO` — including **any other error code** — is
treated as AHCI success and `chipinit` returns 0 immediately, skipping the compat-mode
fallback at ata-intel.c:182-189 that is the only remaining place `ctlr->setmode`
gets assigned on this path.

`ata_ahci_chipinit()` (ata-ahci.c:71-122) has three failure exits:
- BAR(5) alloc failure → `ENXIO` (ata-ahci.c:82)
- interrupt setup failure → `ENXIO` (ata-ahci.c:88)
- `ata_ahci_ctlr_reset()` failure → `return (error)` — **propagated verbatim** (ata-ahci.c:95-98)

All of `ctlr->reset/dmainit/allocate/setmode` and `ctlr->channels` are assigned only
*after* that point (ata-ahci.c:101-108). So if `ata_ahci_ctlr_reset()` ever returns
anything other than `ENXIO` (it currently returns only `ENXIO`/`0`, but its error is
propagated as a variable), `ata_intel_chipinit` returns 0 with:

- `ctlr->setmode == NULL` (compat block skipped, AHCI assignments never reached)
- controller attach continues; channel attach then runs
  `ata_pcichannel_setmode()` (ata-pci.c:857-866) → `ctlr->setmode(dev, ATA_PIO_MAX)`
  at ata-pci.c:863 → **NULL function-pointer call → kernel panic during boot/attach**
  (sink chain: ata-all.c:525 / ata-disk.c:436 → ATA_SETMODE method).

## Fix

Take the AHCI path only on explicit success — see `fix.diff`:

```diff
-    (ata_ahci_chipinit(dev) != ENXIO))
+    (ata_ahci_chipinit(dev) == 0))
```

## Pack contents

- `VERDICT.md` — full narrative + line-level trace + what was live-verified
- `dmesg.txt` — guest boot evidence: the audited ata-intel path runs on every boot
- `env.txt` — guest uname, PCI config dump of atapci0 (PIIX3), device id
- `collect_live.sh` — exact commands to re-collect the evidence
- `fix.diff` — git-apply-able one-line hardening
- `manifest.json` / `verdict.json`

## How to re-run the live evidence

```
dfbsd-qemu/vm.sh up          # if down
./collect_live.sh            # or: dfbsd-qemu/vm.sh run_root 'dmesg | grep -E "atapci0|ata[01]:"'
```

Expected: `atapci0: <Intel PIIX3 WDMA2 controller>` + `ata0/ata1` channels — proving
`ata_intel_ident` → `ata_intel_chipinit` → non-SATA branch → `ata_intel_new_setmode`
(timing tables, `ata_mode2idx`) executed in-bounds at boot with no anomaly.
