# DF-4539 — cs4281 attach ignores mixer_init()/pcm_addchan() failures; half-attached device NULL-derefs on suspend/resume

## What this is
`cs4281_pci_attach()` ignores three return values and advertises success
unconditionally:

* `mixer_init(dev, ...)` at **cs4281.c:845** — return ignored. If it
  fails, `snddev->mixer_dev` stays NULL, yet attach succeeds.
* `pcm_addchan(dev, PCMDIR_PLAY, ...)` (**cs4281.c:850**) and
  `pcm_addchan(dev, PCMDIR_REC, ...)` (**cs4281.c:851**) — returns
  ignored. `pcm_addchan` fails (sound.c:1125-1141) when `chn_init` →
  `cs4281chan_init` fails, which happens when `sndbuf_alloc()` fails
  (**cs4281.c:326-328**). That early return leaves the embedded
  `sc->pch`/`sc->rch` with `ch->parent == NULL`, `ch->channel == NULL`
  (set only at **cs4281.c:329-330/337**, after the failure return).

The driver then calls `pcm_setstatus` and reports the device healthy.

## Consequences (both root-gated: ACPI suspend/resume)
* `cs4281_pci_resume()` (**cs4281.c:941-949**) unconditionally invokes
  `cs4281chan_setspeed(NULL, &sc->rch, ...)` etc. → `adcdac_go(ch, 0)`
  (**cs4281.c:474-479**) → `cs4281_rd(sc, ...)` with `sc = ch->parent ==
  NULL` → NULL-pointer dereference panic.
* `cs4281_pci_resume` → `mixer_reinit(dev)` (**cs4281.c:935**) →
  mixer.c:828-829: `pdev = mixer_get_devt(dev)` returns
  `snddev->mixer_dev` (NULL after the ignored `mixer_init` failure,
  mixer.c:118-124) and is derefenced `pdev->si_drv1` without a check →
  NULL-pointer dereference panic.

No unprivileged trigger: suspend/resume requires root. Severity Low
(robustness/DoS under resource pressure at attach + later suspend).

## Build / run
```
./build.sh    # guest build of the environment probe
./run.sh      # documents: no CS4281 hardware on this guest
```

## Fix
`fix.diff` adds defensive guards to `cs4281_pci_resume` (skip restore
when either channel never initialized). The attach-side checks for
`mixer_init`/`pcm_addchan` returns + `bad_unregister:` unwind are in the
DF-4537 fix (same attach function); this diff is the resume-side
backstop. `git apply --check` clean; never applied to sys/.
