DF-5490 / df5490_rig.c
/* * DF-5490 rig: attach pcf0 via the same newbus API isahint.c:53-91 uses * (BUS_ADD_CHILD + bus_set_resource + probe/attach), then dump the * iicbus child state and fire the exact pcfintr sink (pcf.c:475). */ #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 <sys/bus_resource.h> #include <sys/machintr.h> #define DF_INTR_RECEIVE 0x4 #define DF_IOBASE 0x320 #define DF_IRQ 5 extern void iicbus_intr(device_t, int, char *); static int df5490_attach_pcf(void) { devclass_t dc; device_t isa, child; int error; dc = devclass_find("isa"); if (dc == NULL) { kprintf("df5490: no isa devclass\n"); return (ENXIO); } isa = devclass_get_device(dc, 1); if (isa == NULL) { isa = devclass_get_device(dc, 0); kprintf("df5490: isa1 missing, using isa0=%p\n", isa); } if (isa == NULL) { kprintf("df5490: no isa bus\n"); return (ENXIO); } child = BUS_ADD_CHILD(isa, isa, 100, "pcf", 0); if (child == NULL) { kprintf("df5490: BUS_ADD_CHILD failed\n"); return (ENXIO); } bus_set_resource(child, SYS_RES_IOPORT, 0, DF_IOBASE, 2, -1); bus_set_resource(child, SYS_RES_IRQ, 0, DF_IRQ, 1, machintr_legacy_intr_cpuid(DF_IRQ)); kprintf("df5490: added pcf child %s, probing+attaching\n", device_get_nameunit(child)); error = device_probe_and_attach(child); kprintf("df5490: device_probe_and_attach -> %d\n", error); return (error); } static void df5490_fire(void) { devclass_t dc; device_t pcf0, *kids; char c = 0x41; int nk, i; dc = devclass_find("pcf"); if (dc == NULL || (pcf0 = devclass_get_device(dc, 0)) == NULL) { kprintf("df5490: no pcf0 device found\n"); return; } if (device_get_children(pcf0, &kids, &nk) != 0) { kprintf("df5490: device_get_children failed\n"); return; } kprintf("df5490: pcf0=%s state=%d children=%d\n", device_get_nameunit(pcf0), device_get_state(pcf0), nk); for (i = 0; i < nk; i++) { kprintf("df5490: child[%d]=%s state=%d softc=%p devclass=%s\n", i, device_get_nameunit(kids[i]), device_get_state(kids[i]), device_get_softc(kids[i]), (device_get_devclass(kids[i]) ? devclass_get_name(device_get_devclass(kids[i])) : "(null)")); } kprintf("df5490: calling iicbus_intr(child0, INTR_RECEIVE, &c) == pcfintr pcf.c:475\n"); iicbus_intr(kids[0], DF_INTR_RECEIVE, &c); kprintf("df5490: iicbus_intr RETURNED (no fault)\n"); kfree(kids, M_TEMP); } static int df5490_modevent(module_t m, int what, void *arg) { if (what == MOD_LOAD) { if (df5490_attach_pcf() == 0) df5490_fire(); } return (0); } static moduledata_t df5490_mod = { "df5490_rig", df5490_modevent, NULL }; DECLARE_MODULE(df5490_rig, df5490_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); |