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

Reply via email to