Hello This is a newbie question: I am trying to write a simple DragonFly kernel module for the gmux device that is attached to the LPC bus. Probing works fine but I am stuck with the attachment routine: I can't allocate IO ports for the device.
The device shows up in the device tree but is not attached: --- # devinfo -rv | grep GMUX: unknown pnpinfo _HID=APP000B _UID=0 at handle=\_SB_.PCI0.LPCB.GMUX --- I looked up acpi tables (acpidump etc), the IO resources for GMUX seem to be there: --- --- Scope (\_SB.PCI0.LPCB) { Device (GMUX) { Name (_HID, EisaId ("APP000B")) // _HID: Hardware ID Name (_CID, "gmux") // _CID: Compatible ID Name (_STA, 0x0B) // _STA: Status Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings { IO (Decode16, 0x0700, // Range Minimum 0x07FF, // Range Maximum 0x01, // Alignment 0xFF, // Length ) }) --- --- Also, looking devinfo -rv shows that the range 0x0700 to 0x07FF has been set aside by the kernel: --- # devinfo -u . . . I/O ports: . . . 0x400 - 0x1fff (root0) . . . --- So am I right supposing that bus_alloc_resource_any should be able to claim the range 0x700 to 0x7FF for the gmux device? At the moment, trying to allocate IO ports with bus_alloc_resource returns NULL. I wonder if anyone has suggestions about what has gone wrong or where to dig further? I attach the code. Thanks Peeter --
/* * gmux_off - simple kernel module that turns off the second or discrete * graphics device for apple macbookpro laptops * * IGD - integrated graphics device * DIS - discrete graphics device * */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/bio.h> #include <sys/bus.h> #include <sys/malloc.h> #include <sys/module.h> #include <sys/proc.h> #include <sys/types.h> #include <sys/systm.h> #include <sys/device.h> #include <sys/conf.h> #include <sys/rman.h> #include "opt_acpi.h" #include <contrib/dev/acpica/source/include/acpi.h> #include <contrib/dev/acpica/source/include/accommon.h> #include <dev/acpica/acpivar.h> #define GMUX_ACPI_HID "APP000B" struct gmux_softc { int io_rid; struct resource *io_res; int unit; bool indexed; device_t gmux_dev; struct lock gmux_lock; }; static int gmux_off_acpi_probe(device_t dev); static int gmux_off_acpi_attach(device_t dev); static int gmux_off_acpi_detach(device_t dev); static int gmux_off_acpi_probe(device_t dev) { device_t bus; static char *gmux_ids[] = { GMUX_ACPI_HID, NULL }; bus = device_get_parent(dev); if (ACPI_ID_PROBE(bus, dev, gmux_ids) == NULL) return(ENXIO); if (ACPI_SUCCESS(ACPI_EVALUATE_OBJECT(bus, dev, "_UID", NULL, NULL))) { device_set_desc(dev, "apple gmux controller"); } else { device_set_desc(dev, "apple gmux controller"); } return(BUS_PROBE_SPECIFIC); //for now } static int gmux_off_acpi_attach(device_t dev) { struct gmux_softc *sc; int error; int unit; sc = device_get_softc(dev); unit = device_get_unit(dev); sc->gmux_dev = dev; sc->unit = unit; sc->io_rid = 0; sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->io_rid, RF_ACTIVE); if (sc->io_res == NULL) { return(ENXIO); } //DEBUG device_printf(dev, "attach(): bus_alloc_resource: port = %d\n", sc->io_rid); return(error); } static int gmux_off_acpi_detach(device_t dev) { struct gmux_softc *sc = device_get_softc(dev); return(bus_release_resource(dev, SYS_RES_IOPORT, sc->io_rid, sc->io_res)); } static device_method_t gmux_off_acpi_methods[] = { DEVMETHOD(device_probe, gmux_off_acpi_probe), DEVMETHOD(device_attach, gmux_off_acpi_attach), DEVMETHOD(device_detach, gmux_off_acpi_detach), DEVMETHOD_END }; devclass_t gmux_off_devclass; static driver_t gmux_off_acpi_driver = { "gmux_off_acpi", gmux_off_acpi_methods, sizeof(struct gmux_softc) }; DRIVER_MODULE(gmux_off, acpi, gmux_off_acpi_driver, gmux_off_devclass, 0, 0);