# DF-5490 — pcf: iicbus child never attaches (missing DRIVER_MODULE(iicbus, pcf)) → NULL-softc panic in pcfintr

## What
`pcf_attach()` (sys/bus/iicbus/pcf/pcf.c:200) adds an `"iicbus"` child to the
pcf bus, but no `DRIVER_MODULE(iicbus, pcf, ...)` exists anywhere — the iicbus
driver is registered only on the `iicbb` bus (sys/bus/iicbus/iicbus.c:194).
DragonFly newbus probes a child only against drivers registered in the parent
bus's devclass (sys/kern/subr_bus.c:1414-1484 `device_probe_child`), so the
child never attaches: it stays `state=0` (DS_NOTPRESENT) with `softc == NULL`
forever. `pcfintr()` — the live IRQ handler registered by `pcf_attach()`
(pcf.c:193-195) — calls `iicbus_intr(pcf->iicbus, ...)` on 8 paths
(pcf.c:412, 430, 435, 445, 447, 453, 468, 475); `iicbus_intr()` dereferences
`device_get_softc(bus)->owner` (iiconf.c:47-50) → NULL softc → page fault →
kernel panic. ENI (chip interrupt enable) is permanently set by
`pcf_rst_card()` (pcf.c:537), `pcf_stop()` (pcf.c:300) and pcfintr's own error
path (pcf.c:490), so on real PCF8584 hardware in the default (non-polled)
configuration the FIRST interrupt after attach panics the machine
deterministically. The driver is also functionally dead: with no iicbus
attachment there is no `/dev/iicN` and no in-tree caller can reach
`pcf_write`/`pcf_read`/`pcf_start`.

## Build (guest)
```
scp df5490_rig.c dfbsd:/root/
mkdir -p /usr/src/sys/bus/iicbus/df5490 && cp /root/df5490_rig.c $_/
printf 'KMOD=   df5490_rig\nSRCS=   df5490_rig.c\nSRCS+=  bus_if.h device_if.h iicbus_if.h isa_if.h\n.include <bsd.kmod.mk>\n' > /usr/src/sys/bus/iicbus/df5490/Makefile
cd /usr/src/sys/bus/iicbus/df5490 && make
```

## Run (baseline — expect panic)
```
kldload iicbus && kldload pcf
kldload /usr/src/sys/bus/iicbus/df5490/df5490_rig.ko
```
The rig attaches pcf0 through the exact newbus API `isahint` uses
(BUS_ADD_CHILD + bus_set_resource + device_probe_and_attach — cf.
sys/bus/isa/isahint.c:53-91), because the kernel's hinted-children
enumeration only reads the compiled-in devtab (subr_bus.c:2401
`resource_query_string`), so kenv/loader hints cannot add an isa child at
runtime. After attach it dumps the child state and then invokes the exact
`pcfintr` sink call (`iicbus_intr(pcf->iicbus, INTR_RECEIVE, &data)`,
pcf.c:475).

### Expected (observed) — see panic.txt / run.log.baseline_panic_full
```
df5490: added pcf child pcf0, probing+attaching
pcf0: <PCF8584 I2C bus controller> at port 0x320-0x321 irq 5 on isa1
interrupt uses mplock: pcf0
df5490: device_probe_and_attach -> 0
df5490: pcf0=pcf0 state=3 children=1
df5490: child[0]=iicbus0 state=0 softc=0 devclass=iicbus     <-- never attached, NULL softc
df5490: calling iicbus_intr(child0, INTR_RECEIVE, &c) == pcfintr pcf.c:475
Fatal trap 12: page fault while in kernel mode
fault virtual address  = 0x8
Stopped at      iicbus_intr+0x18:       movq    0x8(%rax),%rbx   <-- sc->owner @ offset 8 of NULL softc
```

## Run (fix validation — expect NO panic)
```
cd /usr/src && patch -p1 < fix.diff          # adds DRIVER_MODULE(iicbus, pcf, ...) + pcfintr guard
cd sys/bus/iicbus/pcf && make && cp pcf.ko /root/pcf_fixed.ko
kldload iicbus && kldload iic && kldload /root/pcf_fixed.ko
kldload /usr/src/sys/bus/iicbus/df5490/df5490_rig.ko
```
### Expected (observed) — see run.fixed_serial.log
```
iicbus0: <Philips I2C bus> on pcf0 addr 0xaa
df5490: child[0]=iicbus0 state=3 softc=0xfffff8004f0e7478 devclass=iicbus
df5490: iicbus_intr RETURNED (no fault)
```
Guest stays up; the previously-panicking sink call is a clean no-op
(owner == NULL).

## Notes
- The only hardware-substituted step is IRQ *delivery*: on real PCF8584
  silicon the chip's interrupt (enabled since probe via ENI, pcf.c:171→537)
  calls the registered `pcfintr` handler, which makes the identical
  `iicbus_intr(pcf->iicbus, ...)` call that the rig makes. The device state
  (pcf0 attached, irq registered, child unattached with NULL softc) is the
  genuine production state, created through production newbus APIs.
- Cross-observations for future audits (other files): (1) even with the fix,
  iicbus0's own wildcard children (ic/iic/iicsmb) did not attach/materialize
  `/dev/iic0` — iicbus.c/iic.c child-handling question; (2) `kldunload
  iicbus` succeeded while iicbus0 was attached (module unload not pinned to
  attached bus children).
