Page MenuHomeFreeBSD

D43687.diff
No OneTemporary

D43687.diff

diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -126,11 +126,16 @@
static bus_read_ivar_t acpi_read_ivar;
static bus_write_ivar_t acpi_write_ivar;
static bus_get_resource_list_t acpi_get_rlist;
+static bus_get_rman_t acpi_get_rman;
static bus_set_resource_t acpi_set_resource;
static bus_alloc_resource_t acpi_alloc_resource;
static bus_adjust_resource_t acpi_adjust_resource;
static bus_release_resource_t acpi_release_resource;
static bus_delete_resource_t acpi_delete_resource;
+static bus_activate_resource_t acpi_activate_resource;
+static bus_deactivate_resource_t acpi_deactivate_resource;
+static bus_map_resource_t acpi_map_resource;
+static bus_unmap_resource_t acpi_unmap_resource;
static bus_child_pnpinfo_t acpi_child_pnpinfo_method;
static bus_child_location_t acpi_child_location_method;
static bus_hint_device_unit_t acpi_hint_device_unit;
@@ -196,16 +201,19 @@
DEVMETHOD(bus_read_ivar, acpi_read_ivar),
DEVMETHOD(bus_write_ivar, acpi_write_ivar),
DEVMETHOD(bus_get_resource_list, acpi_get_rlist),
+ DEVMETHOD(bus_get_rman, acpi_get_rman),
DEVMETHOD(bus_set_resource, acpi_set_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_alloc_resource, acpi_alloc_resource),
DEVMETHOD(bus_adjust_resource, acpi_adjust_resource),
DEVMETHOD(bus_release_resource, acpi_release_resource),
DEVMETHOD(bus_delete_resource, acpi_delete_resource),
+ DEVMETHOD(bus_activate_resource, acpi_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, acpi_deactivate_resource),
+ DEVMETHOD(bus_map_resource, acpi_map_resource),
+ DEVMETHOD(bus_unmap_resource, acpi_unmap_resource),
DEVMETHOD(bus_child_pnpinfo, acpi_child_pnpinfo_method),
DEVMETHOD(bus_child_location, acpi_child_location_method),
- DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_hint_device_unit, acpi_hint_device_unit),
@@ -479,6 +487,8 @@
if (rman_init(&acpi_rman_mem) != 0)
panic("acpi rman_init memory failed");
+ resource_list_init(&sc->sysres_rl);
+
/* Initialise the ACPI mutex */
mtx_init(&acpi_mutex, "ACPI global lock", NULL, MTX_DEF);
@@ -1294,6 +1304,20 @@
return (bus_generic_get_domain(dev, child, domain));
}
+static struct rman *
+acpi_get_rman(device_t bus, int type, u_int flags)
+{
+ /* Only memory and IO resources are managed. */
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return (&acpi_rman_io);
+ case SYS_RES_MEMORY:
+ return (&acpi_rman_mem);
+ default:
+ return (NULL);
+ }
+}
+
/*
* Pre-allocate/manage all memory and IO resources. Since rman can't handle
* duplicates, we merge any in the sysresource attach routine.
@@ -1301,8 +1325,8 @@
static int
acpi_sysres_alloc(device_t dev)
{
+ struct acpi_softc *sc = device_get_softc(dev);
struct resource *res;
- struct resource_list *rl;
struct resource_list_entry *rle;
struct rman *rm;
device_t *children;
@@ -1320,28 +1344,21 @@
}
free(children, M_TEMP);
- rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
- STAILQ_FOREACH(rle, rl, link) {
+ STAILQ_FOREACH(rle, &sc->sysres_rl, link) {
if (rle->res != NULL) {
device_printf(dev, "duplicate resource for %jx\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:
+ rm = acpi_get_rman(dev, rle->type, 0);
+ if (rm == NULL)
continue;
- }
/* Pre-allocate resource and add to our rman pool. */
- res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, rle->type,
- &rle->rid, rle->start, rle->start + rle->count - 1, rle->count, 0);
+ res = bus_alloc_resource(dev, rle->type,
+ &rle->rid, rle->start, rle->start + rle->count - 1, rle->count,
+ RF_ACTIVE | RF_UNMAPPED);
if (res != NULL) {
rman_manage_region(rm, rman_get_start(res), rman_get_end(res));
rle->res = res;
@@ -1542,63 +1559,39 @@
* from our system resource regions.
*/
if (res == NULL && start + count - 1 == end)
- res = acpi_alloc_sysres(child, type, rid, start, end, count, flags);
+ res = bus_generic_rman_alloc_resource(bus, child, type, rid, start, end,
+ count, flags);
return (res);
}
-/*
- * Attempt to allocate a specific resource range from the system
- * resource ranges. Note that we only handle memory and I/O port
- * system resources.
- */
-struct resource *
-acpi_alloc_sysres(device_t child, int type, int *rid, rman_res_t start,
- rman_res_t end, rman_res_t count, u_int flags)
+static bool
+acpi_is_resource_managed(device_t bus, int type, struct resource *r)
{
- struct rman *rm;
- struct resource *res;
-
- switch (type) {
- case SYS_RES_IOPORT:
- rm = &acpi_rman_io;
- break;
- case SYS_RES_MEMORY:
- rm = &acpi_rman_mem;
- break;
- default:
- return (NULL);
- }
+ struct rman *rm;
- KASSERT(start + count - 1 == end, ("wildcard resource range"));
- res = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
- child);
- if (res == NULL)
- return (NULL);
-
- rman_set_rid(res, *rid);
-
- /* If requested, activate the resource using the parent's method. */
- if (flags & RF_ACTIVE)
- if (bus_activate_resource(child, type, *rid, res) != 0) {
- rman_release_resource(res);
- return (NULL);
- }
-
- return (res);
+ rm = acpi_get_rman(bus, type, 0);
+ if (rm == NULL)
+ return (false);
+ return (rman_is_region_manager(r, rm));
}
-static int
-acpi_is_resource_managed(int type, struct resource *r)
+static struct resource *
+acpi_managed_resource(device_t bus, int type, struct resource *r)
{
+ struct acpi_softc *sc = device_get_softc(bus);
+ struct resource_list_entry *rle;
- /* We only handle memory and IO resources through rman. */
- switch (type) {
- case SYS_RES_IOPORT:
- return (rman_is_region_manager(r, &acpi_rman_io));
- case SYS_RES_MEMORY:
- return (rman_is_region_manager(r, &acpi_rman_mem));
- }
- return (0);
+ KASSERT(acpi_is_resource_managed(bus, type, r),
+ ("resource %p is not suballocated", r));
+
+ STAILQ_FOREACH(rle, &sc->sysres_rl, link) {
+ if (rle->type != type || rle->res == NULL)
+ continue;
+ if (rman_get_start(r) >= rman_get_start(rle->res) &&
+ rman_get_end(r) <= rman_get_end(rle->res))
+ return (rle->res);
+ }
+ return (NULL);
}
static int
@@ -1606,7 +1599,7 @@
rman_res_t start, rman_res_t end)
{
- if (acpi_is_resource_managed(type, r))
+ if (acpi_is_resource_managed(bus, type, r))
return (rman_adjust_resource(r, start, end));
return (bus_generic_adjust_resource(bus, child, type, r, start, end));
}
@@ -1615,20 +1608,12 @@
acpi_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- int ret;
-
/*
* If this resource belongs to one of our internal managers,
* deactivate it and release it to the local pool.
*/
- if (acpi_is_resource_managed(type, r)) {
- if (rman_get_flags(r) & RF_ACTIVE) {
- ret = bus_deactivate_resource(child, type, rid, r);
- if (ret != 0)
- return (ret);
- }
- return (rman_release_resource(r));
- }
+ if (acpi_is_resource_managed(bus, type, r))
+ return (bus_generic_rman_release_resource(bus, child, type, rid, r));
return (bus_generic_rl_release_resource(bus, child, type, rid, r));
}
@@ -1648,6 +1633,69 @@
resource_list_delete(rl, type, rid);
}
+static int
+acpi_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ if (acpi_is_resource_managed(bus, type, r))
+ return (bus_generic_rman_activate_resource(bus, child, type,
+ rid, r));
+ return (bus_generic_activate_resource(bus, child, type, rid, r));
+}
+
+static int
+acpi_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ if (acpi_is_resource_managed(bus, type, r))
+ return (bus_generic_rman_deactivate_resource(bus, child, type,
+ rid, r));
+ return (bus_generic_deactivate_resource(bus, child, type, rid, r));
+}
+
+static int
+acpi_map_resource(device_t bus, device_t child, int type, struct resource *r,
+ struct resource_map_request *argsp, struct resource_map *map)
+{
+ struct resource_map_request args;
+ struct resource *sysres;
+ rman_res_t length, start;
+ int error;
+
+ if (!acpi_is_resource_managed(bus, type, r))
+ return (bus_generic_map_resource(bus, child, type, r, argsp,
+ map));
+
+ /* Resources must be active to be mapped. */
+ if (!(rman_get_flags(r) & RF_ACTIVE))
+ return (ENXIO);
+
+ resource_init_map_request(&args);
+ error = resource_validate_map_request(r, argsp, &args, &start, &length);
+ if (error)
+ return (error);
+
+ sysres = acpi_managed_resource(bus, type, r);
+ if (sysres == NULL)
+ return (ENOENT);
+
+ args.offset = start - rman_get_start(sysres);
+ args.length = length;
+ return (bus_generic_map_resource(bus, child, type, sysres, &args, map));
+}
+
+static int
+acpi_unmap_resource(device_t bus, device_t child, int type, struct resource *r,
+ struct resource_map *map)
+{
+ if (acpi_is_resource_managed(bus, type, r)) {
+ r = acpi_managed_resource(bus, type, r);
+ if (r == NULL)
+ return (ENOENT);
+ }
+ return (bus_generic_unmap_resource(bus, child, type, r, map));
+}
+
/* Allocate an IO port or memory resource, given its GAS. */
int
acpi_bus_alloc_gas(device_t dev, int *type, int *rid, ACPI_GENERIC_ADDRESS *gas,
diff --git a/sys/dev/acpica/acpi_resource.c b/sys/dev/acpica/acpi_resource.c
--- a/sys/dev/acpica/acpi_resource.c
+++ b/sys/dev/acpica/acpi_resource.c
@@ -737,8 +737,6 @@
* private rman.
*/
-static int acpi_sysres_rid = 100;
-
static int acpi_sysres_probe(device_t dev);
static int acpi_sysres_attach(device_t dev);
@@ -780,6 +778,7 @@
acpi_sysres_attach(device_t dev)
{
device_t bus;
+ struct acpi_softc *bus_sc;
struct resource_list_entry *bus_rle, *dev_rle;
struct resource_list *bus_rl, *dev_rl;
int done, type;
@@ -794,7 +793,8 @@
*/
bus = device_get_parent(dev);
dev_rl = BUS_GET_RESOURCE_LIST(bus, dev);
- bus_rl = BUS_GET_RESOURCE_LIST(device_get_parent(bus), bus);
+ bus_sc = acpi_device_get_parent_softc(dev);
+ bus_rl = &bus_sc->sysres_rl;
STAILQ_FOREACH(dev_rle, dev_rl, link) {
if (dev_rle->type != SYS_RES_IOPORT && dev_rle->type != SYS_RES_MEMORY)
continue;
@@ -834,7 +834,7 @@
/* If we didn't merge with anything, add this resource. */
if (bus_rle == NULL)
- bus_set_resource(bus, type, acpi_sysres_rid++, start, count);
+ resource_list_add_next(bus_rl, type, start, end, count);
}
/* After merging/moving resources to the parent, free the list. */
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -78,6 +78,9 @@
struct apm_clone_data *acpi_clone; /* Pseudo-dev for devd(8). */
STAILQ_HEAD(,apm_clone_data) apm_cdevs; /* All apm/apmctl/acpi cdevs. */
struct callout susp_force_to; /* Force suspend if no acks. */
+
+ /* System Resources */
+ struct resource_list sysres_rl;
};
struct acpi_device {
@@ -438,9 +441,6 @@
struct resource *res, ACPI_RESOURCE *acpi_res);
ACPI_STATUS acpi_parse_resources(device_t dev, ACPI_HANDLE handle,
struct acpi_parse_resource_set *set, void *arg);
-struct resource *acpi_alloc_sysres(device_t child, int type, int *rid,
- rman_res_t start, rman_res_t end, rman_res_t count,
- u_int flags);
/* ACPI event handling */
UINT32 acpi_event_power_button_sleep(void *context);

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 7, 12:16 PM (12 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14511936
Default Alt Text
D43687.diff (11 KB)

Event Timeline