summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2004-06-13 22:52:30 +0000
committernjl <njl@FreeBSD.org>2004-06-13 22:52:30 +0000
commitd49f147c3f337c27d40d40e625f0b8895b9c6c0f (patch)
treed2dac6905b64b7bcc7fe4fdc69df38b6c7dc9629 /sys/dev/acpica
parent05af3d5b81d06efd1f5a8cf33121efd504b922c0 (diff)
downloadFreeBSD-src-d49f147c3f337c27d40d40e625f0b8895b9c6c0f.zip
FreeBSD-src-d49f147c3f337c27d40d40e625f0b8895b9c6c0f.tar.gz
Add support to ACPI to manage its own resources. Previously, resource
allocation was passed up to nexus. Now, we probe sysresource objects and manage the resources they describe in a local rman pool. This helps devices which attach/detach varying resources (like the _CST object) and module loads/unloads. The allocation/release routines now check to see if the resource is described in a child sysresource object and if so, allocate from the local rman. Sysresource objects add their resources to the pool and reserve them upon boot. This means sysresources need to be probed before other ACPI devices. Changes include: * Add ordering to the child device probe. The current order is: system resource objects, embedded controllers, then everything else. * Make acpi_MatchHid take a handle instead of a device_t arg. * Replace acpi_{get,set}_resource with the generic equivalents.
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r--sys/dev/acpica/acpi.c189
-rw-r--r--sys/dev/acpica/acpi_acad.c2
-rw-r--r--sys/dev/acpica/acpi_button.c10
-rw-r--r--sys/dev/acpica/acpi_cmbat.c4
-rw-r--r--sys/dev/acpica/acpi_ec.c2
-rw-r--r--sys/dev/acpica/acpi_isab.c4
-rw-r--r--sys/dev/acpica/acpi_lid.c2
-rw-r--r--sys/dev/acpica/acpi_pcib_acpi.c2
-rw-r--r--sys/dev/acpica/acpi_resource.c128
-rw-r--r--sys/dev/acpica/acpivar.h4
10 files changed, 246 insertions, 101 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 4f88cd5..ec7a24f 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -81,6 +81,9 @@ static struct cdevsw acpi_cdevsw = {
struct mtx acpi_mutex;
#endif
+/* Local pools for managing system resources for ACPI child devices. */
+struct rman acpi_rman_io, acpi_rman_mem;
+
struct acpi_quirks {
char *OemId;
uint32_t OemRevision;
@@ -111,10 +114,7 @@ static int acpi_read_ivar(device_t dev, device_t child, int index,
uintptr_t *result);
static int acpi_write_ivar(device_t dev, device_t child, int index,
uintptr_t value);
-static int acpi_set_resource(device_t dev, device_t child, int type,
- int rid, u_long start, u_long count);
-static int acpi_get_resource(device_t dev, device_t child, int type,
- int rid, u_long *startp, u_long *countp);
+static struct resource_list *acpi_get_rlist(device_t dev, device_t child);
static struct resource *acpi_alloc_resource(device_t bus, device_t child,
int type, int *rid, u_long start, u_long end,
u_long count, u_int flags);
@@ -162,8 +162,9 @@ static device_method_t acpi_methods[] = {
DEVMETHOD(bus_print_child, acpi_print_child),
DEVMETHOD(bus_read_ivar, acpi_read_ivar),
DEVMETHOD(bus_write_ivar, acpi_write_ivar),
- DEVMETHOD(bus_set_resource, acpi_set_resource),
- DEVMETHOD(bus_get_resource, acpi_get_resource),
+ DEVMETHOD(bus_get_resource_list, acpi_get_rlist),
+ DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
+ DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_alloc_resource, acpi_alloc_resource),
DEVMETHOD(bus_release_resource, acpi_release_resource),
DEVMETHOD(bus_child_pnpinfo_str, acpi_child_pnpinfo_str_method),
@@ -395,6 +396,20 @@ acpi_attach(device_t dev)
bzero(sc, sizeof(*sc));
sc->acpi_dev = dev;
+ /* Initialize resource manager. */
+ acpi_rman_io.rm_type = RMAN_ARRAY;
+ acpi_rman_io.rm_start = 0;
+ acpi_rman_io.rm_end = 0xffff;
+ acpi_rman_io.rm_descr = "I/O ports";
+ if (rman_init(&acpi_rman_io) != 0)
+ panic("acpi rman_init IO ports failed");
+ acpi_rman_mem.rm_type = RMAN_ARRAY;
+ acpi_rman_mem.rm_start = 0;
+ acpi_rman_mem.rm_end = ~0ul;
+ acpi_rman_mem.rm_descr = "I/O memory addresses";
+ if (rman_init(&acpi_rman_mem) != 0)
+ panic("acpi rman_init memory failed");
+
#ifdef ACPI_DEBUGGER
debugpoint = getenv("debug.acpi.debugger");
if (debugpoint) {
@@ -824,56 +839,102 @@ acpi_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
/*
* Handle child resource allocation/removal
*/
-static int
-acpi_set_resource(device_t dev, device_t child, int type, int rid,
- u_long start, u_long count)
+static struct resource_list *
+acpi_get_rlist(device_t dev, device_t child)
{
- struct acpi_device *ad = device_get_ivars(child);
- struct resource_list *rl = &ad->ad_rl;
-
- resource_list_add(rl, type, rid, start, start + count -1, count);
+ struct acpi_device *ad;
- return(0);
-}
-
-static int
-acpi_get_resource(device_t dev, device_t child, int type, int rid,
- u_long *startp, u_long *countp)
-{
- struct acpi_device *ad = device_get_ivars(child);
- struct resource_list *rl = &ad->ad_rl;
- struct resource_list_entry *rle;
-
- rle = resource_list_find(rl, type, rid);
- if (!rle)
- return(ENOENT);
-
- if (startp)
- *startp = rle->start;
- if (countp)
- *countp = rle->count;
-
- return (0);
+ ad = device_get_ivars(child);
+ return (&ad->ad_rl);
}
static struct resource *
acpi_alloc_resource(device_t bus, device_t child, int type, int *rid,
- u_long start, u_long end, u_long count, u_int flags)
+ u_long start, u_long end, u_long count, u_int flags)
{
struct acpi_device *ad = device_get_ivars(child);
struct resource_list *rl = &ad->ad_rl;
+ struct resource_list_entry *rle;
+ struct resource *res;
+ struct rman *rm;
+ int needactivate;
+
+ /*
+ * If this is an allocation of the "default" range for a given RID, and
+ * we know what the resources for this device are (i.e., they're on the
+ * child's resource list), use those start/end values.
+ */
+ if (start == 0UL && end == ~0UL) {
+ rle = resource_list_find(rl, type, *rid);
+ if (rle == NULL)
+ return (NULL);
+ start = rle->start;
+ end = rle->end;
+ count = rle->count;
+ }
+
+ /* If we don't manage this address, pass the request up to the parent. */
+ rle = acpi_sysres_find(type, start);
+ if (rle == NULL) {
+ return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid,
+ start, end, count, flags));
+ }
+
+ /* We only handle memory and IO resources through rman. */
+ switch (type) {
+ case SYS_RES_IOPORT:
+ rm = &acpi_rman_io;
+ break;
+ case SYS_RES_MEMORY:
+ rm = &acpi_rman_mem;
+ break;
+ default:
+ panic("acpi_alloc_resource: invalid res type %d", type);
+ }
+
+ /* If we do know it, allocate it from the local pool. */
+ needactivate = flags & RF_ACTIVE;
+ flags &= ~RF_ACTIVE;
+ res = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (res == NULL)
+ return (NULL);
+
+ /* Copy the bus tag from the pre-allocated resource. */
+ rman_set_bustag(res, rman_get_bustag(rle->res));
+ if (type == SYS_RES_IOPORT)
+ rman_set_bushandle(res, res->r_start);
+
+ /* If requested, activate the resource using the parent's method. */
+ if (needactivate)
+ if (bus_activate_resource(child, type, *rid, res) != 0) {
+ rman_release_resource(res);
+ return (NULL);
+ }
- return (resource_list_alloc(rl, bus, child, type, rid, start, end, count,
- flags));
+ return (res);
}
static int
-acpi_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r)
+acpi_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
{
- struct acpi_device *ad = device_get_ivars(child);
- struct resource_list *rl = &ad->ad_rl;
+ int ret;
+
+ /*
+ * If we know about this address, deactivate it and release it to the
+ * local pool. If we don't, pass this request up to the parent.
+ */
+ if (acpi_sysres_find(type, rman_get_start(r)) == NULL) {
+ if (rman_get_flags(r) & RF_ACTIVE) {
+ ret = bus_deactivate_resource(child, type, rid, r);
+ if (ret != 0)
+ return (ret);
+ }
+ ret = rman_release_resource(r);
+ } else
+ ret = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, type, rid, r);
- return (resource_list_release(rl, bus, child, type, rid, r));
+ return (ret);
}
/* Allocate an IO port or memory resource, given its GAS. */
@@ -1043,8 +1104,8 @@ acpi_probe_children(device_t bus)
{
ACPI_HANDLE parent;
ACPI_STATUS status;
- static char *scopes[] = {"\\_PR_", "\\_TZ_", "\\_SI", "\\_SB_", NULL};
int i;
+ static char *scopes[] = {"\\_PR_", "\\_TZ_", "\\_SI", "\\_SB_", NULL};
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
ACPI_ASSERTLOCK;
@@ -1091,6 +1152,28 @@ acpi_probe_children(device_t bus)
return_VOID;
}
+static int
+acpi_probe_order(ACPI_HANDLE handle, int level, int *order)
+{
+ int ret;
+
+ ret = 0;
+ /* IO port and memory system resource holders are first. */
+ if (acpi_MatchHid(handle, "PNP0C01") || acpi_MatchHid(handle, "PNP0C02")) {
+ *order = 1;
+ ret = 1;
+ }
+
+ /* The embedded controller is needed to handle accesses early. */
+ if (acpi_MatchHid(handle, "PNP0C09")) {
+ *order = 2;
+ ret = 1;
+ }
+
+ *order = (level + 1) * 10;
+ return (ret);
+}
+
/*
* Evaluate a child device and determine whether we might attach a device to
* it.
@@ -1099,7 +1182,8 @@ static ACPI_STATUS
acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
{
ACPI_OBJECT_TYPE type;
- device_t child, bus = (device_t)context;
+ device_t child, bus;
+ int order, probe_now;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
@@ -1107,6 +1191,7 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
if (acpi_avoid(handle))
return_ACPI_STATUS (AE_OK);
+ bus = (device_t)context;
if (ACPI_SUCCESS(AcpiGetType(handle, &type))) {
switch(type) {
case ACPI_TYPE_DEVICE:
@@ -1122,7 +1207,8 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
*/
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n",
acpi_name(handle)));
- child = BUS_ADD_CHILD(bus, level * 10, NULL, -1);
+ probe_now = acpi_probe_order(handle, level, &order);
+ child = BUS_ADD_CHILD(bus, order, NULL, -1);
if (child == NULL)
break;
@@ -1154,6 +1240,8 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
acpi_parse_resources(child, handle, &acpi_res_parse_set, NULL);
/* If we're debugging, probe/attach now rather than later */
+ if (probe_now)
+ device_probe_and_attach(child);
ACPI_DEBUG_EXEC(device_probe_and_attach(child));
break;
}
@@ -1342,13 +1430,12 @@ acpi_BatteryIsPresent(device_t dev)
}
/*
- * Match a HID string against a device
+ * Match a HID string against a handle
*/
BOOLEAN
-acpi_MatchHid(device_t dev, char *hid)
+acpi_MatchHid(ACPI_HANDLE h, char *hid)
{
ACPI_DEVICE_INFO *devinfo;
- ACPI_HANDLE h;
ACPI_BUFFER buf;
ACPI_STATUS error;
int ret, i;
@@ -1356,15 +1443,13 @@ acpi_MatchHid(device_t dev, char *hid)
ACPI_ASSERTLOCK;
ret = FALSE;
- if (hid == NULL)
- return (FALSE);
- if ((h = acpi_get_handle(dev)) == NULL)
- return (FALSE);
+ if (hid == NULL || h == NULL)
+ return (ret);
buf.Pointer = NULL;
buf.Length = ACPI_ALLOCATE_BUFFER;
error = AcpiGetObjectInfo(h, &buf);
if (ACPI_FAILURE(error))
- return (FALSE);
+ return (ret);
devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
if ((devinfo->Valid & ACPI_VALID_HID) != 0 &&
diff --git a/sys/dev/acpica/acpi_acad.c b/sys/dev/acpica/acpi_acad.c
index d5c7439..6063a71 100644
--- a/sys/dev/acpica/acpi_acad.c
+++ b/sys/dev/acpica/acpi_acad.c
@@ -137,7 +137,7 @@ static int
acpi_acad_probe(device_t dev)
{
if (acpi_get_type(dev) == ACPI_TYPE_DEVICE && !acpi_disabled("acad") &&
- acpi_MatchHid(dev, "ACPI0003")) {
+ acpi_MatchHid(acpi_get_handle(dev), "ACPI0003")) {
device_set_desc(dev, "AC Adapter");
return (0);
}
diff --git a/sys/dev/acpica/acpi_button.c b/sys/dev/acpica/acpi_button.c
index 8314486..4ea77db 100644
--- a/sys/dev/acpica/acpi_button.c
+++ b/sys/dev/acpica/acpi_button.c
@@ -90,24 +90,26 @@ static int
acpi_button_probe(device_t dev)
{
struct acpi_button_softc *sc;
+ ACPI_HANDLE h;
int ret = ENXIO;
+ h = acpi_get_handle(dev);
sc = device_get_softc(dev);
if (acpi_get_type(dev) == ACPI_TYPE_DEVICE && !acpi_disabled("button")) {
- if (acpi_MatchHid(dev, "PNP0C0C")) {
+ if (acpi_MatchHid(h, "PNP0C0C")) {
device_set_desc(dev, "Power Button");
sc->button_type = ACPI_POWER_BUTTON;
ret = 0;
- } else if (acpi_MatchHid(dev, "ACPI_FPB")) {
+ } else if (acpi_MatchHid(h, "ACPI_FPB")) {
device_set_desc(dev, "Power Button (fixed)");
sc->button_type = ACPI_POWER_BUTTON;
sc->fixed = 1;
ret = 0;
- } else if (acpi_MatchHid(dev, "PNP0C0E")) {
+ } else if (acpi_MatchHid(h, "PNP0C0E")) {
device_set_desc(dev, "Sleep Button");
sc->button_type = ACPI_SLEEP_BUTTON;
ret = 0;
- } else if (acpi_MatchHid(dev, "ACPI_FSB")) {
+ } else if (acpi_MatchHid(h, "ACPI_FSB")) {
device_set_desc(dev, "Sleep Button (fixed)");
sc->button_type = ACPI_SLEEP_BUTTON;
sc->fixed = 1;
diff --git a/sys/dev/acpica/acpi_cmbat.c b/sys/dev/acpica/acpi_cmbat.c
index 2636f0b..6f81c44 100644
--- a/sys/dev/acpica/acpi_cmbat.c
+++ b/sys/dev/acpica/acpi_cmbat.c
@@ -291,8 +291,8 @@ acpi_cmbat_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
static int
acpi_cmbat_probe(device_t dev)
{
- if (acpi_get_type(dev) == ACPI_TYPE_DEVICE &&
- !acpi_disabled("cmbat") && acpi_MatchHid(dev, "PNP0C0A")) {
+ if (acpi_get_type(dev) == ACPI_TYPE_DEVICE && !acpi_disabled("cmbat")
+ && acpi_MatchHid(acpi_get_handle(dev), "PNP0C0A")) {
device_set_desc(dev, "Control Method Battery");
return (0);
diff --git a/sys/dev/acpica/acpi_ec.c b/sys/dev/acpica/acpi_ec.c
index 03f719a..d2605bc 100644
--- a/sys/dev/acpica/acpi_ec.c
+++ b/sys/dev/acpica/acpi_ec.c
@@ -454,7 +454,7 @@ acpi_ec_probe(device_t dev)
if (DEV_ECDT(dev)) {
params = acpi_get_private(dev);
ret = 0;
- } else if (acpi_MatchHid(dev, "PNP0C09")) {
+ } else if (acpi_MatchHid(acpi_get_handle(dev), "PNP0C09")) {
params = malloc(sizeof(struct acpi_ec_params), M_TEMP,
M_WAITOK | M_ZERO);
h = acpi_get_handle(dev);
diff --git a/sys/dev/acpica/acpi_isab.c b/sys/dev/acpica/acpi_isab.c
index 61e9a1f..a7c70c7 100644
--- a/sys/dev/acpica/acpi_isab.c
+++ b/sys/dev/acpica/acpi_isab.c
@@ -90,11 +90,13 @@ MODULE_DEPEND(acpi_isab, acpi, 1, 1, 1);
static int
acpi_isab_probe(device_t dev)
{
+ ACPI_HANDLE h;
+ h = acpi_get_handle(dev);
if (acpi_get_type(dev) == ACPI_TYPE_DEVICE &&
!acpi_disabled("isa") &&
devclass_get_device(isab_devclass, 0) == dev &&
- (acpi_MatchHid(dev, "PNP0A05") || acpi_MatchHid(dev, "PNP0A06"))) {
+ (acpi_MatchHid(h, "PNP0A05") || acpi_MatchHid(h, "PNP0A06"))) {
device_set_desc(dev, "ACPI Generic ISA bridge");
return (0);
}
diff --git a/sys/dev/acpica/acpi_lid.c b/sys/dev/acpica/acpi_lid.c
index 82beb46..e169237 100644
--- a/sys/dev/acpica/acpi_lid.c
+++ b/sys/dev/acpica/acpi_lid.c
@@ -82,7 +82,7 @@ static int
acpi_lid_probe(device_t dev)
{
if (acpi_get_type(dev) == ACPI_TYPE_DEVICE && !acpi_disabled("lid") &&
- acpi_MatchHid(dev, "PNP0C0D")) {
+ acpi_MatchHid(acpi_get_handle(dev), "PNP0C0D")) {
device_set_desc(dev, "Control Method Lid Switch");
return (0);
diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c
index 47c8949..cbb9bee 100644
--- a/sys/dev/acpica/acpi_pcib_acpi.c
+++ b/sys/dev/acpica/acpi_pcib_acpi.c
@@ -117,7 +117,7 @@ acpi_pcib_acpi_probe(device_t dev)
{
if (acpi_get_type(dev) == ACPI_TYPE_DEVICE && !acpi_disabled("pci") &&
- acpi_MatchHid(dev, "PNP0A03")) {
+ acpi_MatchHid(acpi_get_handle(dev), "PNP0A03")) {
if (pci_cfgregopen() == 0)
return (ENXIO);
diff --git a/sys/dev/acpica/acpi_resource.c b/sys/dev/acpica/acpi_resource.c
index ffc2c98..06bf29b 100644
--- a/sys/dev/acpica/acpi_resource.c
+++ b/sys/dev/acpica/acpi_resource.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/bus.h>
+#include <sys/malloc.h>
#include <sys/module.h>
#include <machine/bus.h>
@@ -537,72 +538,125 @@ acpi_res_set_end_dependant(device_t dev, void *context)
}
/*
- * Resource-owning placeholders.
+ * Resource-owning placeholders for IO and memory pseudo-devices.
*
- * This code "owns" system resource objects that aren't
- * otherwise useful to devices, and which shouldn't be
- * considered "free".
- *
- * Note that some systems claim *all* of the physical address space
- * with a PNP0C01 device, so we cannot correctly "own" system memory
- * here (must be done in the SMAP handler on x86 systems, for
- * example).
+ * This code allocates system resource objects that will be owned by ACPI
+ * child devices. Really, the acpi parent device should have the resources
+ * but this would significantly affect the device probe code.
*/
-static int acpi_sysresource_probe(device_t dev);
-static int acpi_sysresource_attach(device_t dev);
+static int acpi_sysres_probe(device_t dev);
+static int acpi_sysres_attach(device_t dev);
-static device_method_t acpi_sysresource_methods[] = {
+static device_method_t acpi_sysres_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, acpi_sysresource_probe),
- DEVMETHOD(device_attach, acpi_sysresource_attach),
+ DEVMETHOD(device_probe, acpi_sysres_probe),
+ DEVMETHOD(device_attach, acpi_sysres_attach),
{0, 0}
};
-static driver_t acpi_sysresource_driver = {
+static driver_t acpi_sysres_driver = {
"acpi_sysresource",
- acpi_sysresource_methods,
+ acpi_sysres_methods,
0,
};
-static devclass_t acpi_sysresource_devclass;
-DRIVER_MODULE(acpi_sysresource, acpi, acpi_sysresource_driver,
- acpi_sysresource_devclass, 0, 0);
+static devclass_t acpi_sysres_devclass;
+DRIVER_MODULE(acpi_sysresource, acpi, acpi_sysres_driver, acpi_sysres_devclass,
+ 0, 0);
MODULE_DEPEND(acpi_sysresource, acpi, 1, 1, 1);
static int
-acpi_sysresource_probe(device_t dev)
+acpi_sysres_probe(device_t dev)
{
- if (!acpi_disabled("sysresource") && acpi_MatchHid(dev, "PNP0C02"))
- device_set_desc(dev, "System Resource");
- else
+ ACPI_HANDLE h;
+
+ h = acpi_get_handle(dev);
+ if (acpi_disabled("sysresource") ||
+ (!acpi_MatchHid(h, "PNP0C01") && !acpi_MatchHid(h, "PNP0C02")))
return (ENXIO);
+ device_set_desc(dev, "System Resource");
device_quiet(dev);
return (-100);
}
static int
-acpi_sysresource_attach(device_t dev)
+acpi_sysres_attach(device_t dev)
{
- struct resource *res;
- int i, rid;
+ device_t gparent;
+ struct resource *res;
+ struct rman *rm;
+ struct resource_list_entry *rle;
+ struct resource_list *rl;
/*
- * Suck up all the resources that might have been assigned to us.
- * Note that it's impossible to tell the difference between a
- * resource that someone else has claimed, and one that doesn't
- * exist.
+ * Pre-allocate/manage all memory and IO resources. We detect duplicates
+ * by setting rle->res to the resource we got from the parent. We can't
+ * ignore them since rman can't handle duplicates.
*/
- for (i = 0; i < 100; i++) {
- rid = i;
- res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, 0);
- rid = i;
- res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0);
- rid = i;
- res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE);
+ rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
+ SLIST_FOREACH(rle, rl, link) {
+ if (rle->res != NULL) {
+ device_printf(dev, "duplicate resource for %lx\n", rle->start);
+ continue;
+ }
+
+ /* Only memory and IO resources are valid here. */
+ switch (rle->type) {
+ case SYS_RES_IOPORT:
+ rm = &acpi_rman_io;
+ break;
+ case SYS_RES_MEMORY:
+ rm = &acpi_rman_mem;
+ break;
+ default:
+ continue;
+ }
+
+ /* Pre-allocate resource and add to our rman pool. */
+ gparent = device_get_parent(device_get_parent(dev));
+ res = BUS_ALLOC_RESOURCE(gparent, dev, rle->type, &rle->rid,
+ rle->start, rle->start + rle->count - 1, rle->count, 0);
+ if (res != NULL) {
+ rman_manage_region(rm, rman_get_start(res), rman_get_end(res));
+ rle->res = res;
+ }
}
return (0);
}
+
+struct resource_list_entry *
+acpi_sysres_find(int type, u_long addr)
+{
+ device_t *devs;
+ int i, numdevs;
+ struct resource_list *rl;
+ struct resource_list_entry *rle;
+
+ /* We only consider IO and memory resources for our pool. */
+ rle = NULL;
+ if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY)
+ return (rle);
+
+ /* Find all the sysresource devices. */
+ if (devclass_get_devices(acpi_sysres_devclass, &devs, &numdevs) != 0)
+ return (rle);
+
+ /* Check each device for a resource that contains "addr". */
+ for (i = 0; i < numdevs && rle == NULL; i++) {
+ rl = BUS_GET_RESOURCE_LIST(device_get_parent(devs[i]), devs[i]);
+ if (rl == NULL)
+ continue;
+ SLIST_FOREACH(rle, rl, link) {
+ if (type == rle->type && addr >= rle->start &&
+ addr < rle->start + rle->count)
+ break;
+ }
+ }
+
+ free(devs, M_TEMP);
+ return (rle);
+}
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index 69b84af..959681d 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -215,7 +215,7 @@ void acpi_EnterDebugger(void);
#define ACPI_DEVINFO_PRESENT(x) (((x) & 0x9) == 9)
BOOLEAN acpi_DeviceIsPresent(device_t dev);
BOOLEAN acpi_BatteryIsPresent(device_t dev);
-BOOLEAN acpi_MatchHid(device_t dev, char *hid);
+BOOLEAN acpi_MatchHid(ACPI_HANDLE h, char *hid);
ACPI_STATUS acpi_GetHandleInScope(ACPI_HANDLE parent, char *path,
ACPI_HANDLE *result);
uint32_t acpi_TimerDelta(uint32_t end, uint32_t start);
@@ -270,6 +270,8 @@ struct acpi_parse_resource_set {
extern struct acpi_parse_resource_set acpi_res_parse_set;
ACPI_STATUS acpi_parse_resources(device_t dev, ACPI_HANDLE handle,
struct acpi_parse_resource_set *set, void *arg);
+extern struct rman acpi_rman_io, acpi_rman_mem;
+struct resource_list_entry *acpi_sysres_find(int type, u_long addr);
/* ACPI event handling */
UINT32 acpi_event_power_button_sleep(void *context);
OpenPOWER on IntegriCloud