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);