Change acpi's handling of suballocating system resources to be a little
simpler. It now can just use rman_is_region_manager() during acpi_release_resource() to see if the the resource is suballocated from a system resource. Also, the driver no longer needs MD knowledge about how to setup bus space tags and handles when doing a suballocation, but can simply rely on bus_activate_resource() in the parent setting all that up.
This commit is contained in:
parent
d66ff27773
commit
397c30a83d
@ -106,8 +106,6 @@ static int acpi_write_ivar(device_t dev, device_t child, int index,
|
|||||||
uintptr_t value);
|
uintptr_t value);
|
||||||
static struct resource_list *acpi_get_rlist(device_t dev, device_t child);
|
static struct resource_list *acpi_get_rlist(device_t dev, device_t child);
|
||||||
static int acpi_sysres_alloc(device_t dev);
|
static int acpi_sysres_alloc(device_t dev);
|
||||||
static struct resource_list_entry *acpi_sysres_find(device_t dev, int type,
|
|
||||||
u_long addr);
|
|
||||||
static struct resource *acpi_alloc_resource(device_t bus, 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,
|
int type, int *rid, u_long start, u_long end,
|
||||||
u_long count, u_int flags);
|
u_long count, u_int flags);
|
||||||
@ -958,31 +956,6 @@ acpi_sysres_alloc(device_t dev)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find if we manage a given resource. */
|
|
||||||
static struct resource_list_entry *
|
|
||||||
acpi_sysres_find(device_t dev, int type, u_long addr)
|
|
||||||
{
|
|
||||||
struct resource_list *rl;
|
|
||||||
struct resource_list_entry *rle;
|
|
||||||
|
|
||||||
ACPI_SERIAL_ASSERT(acpi);
|
|
||||||
|
|
||||||
/* We only consider IO and memory resources for our pool. */
|
|
||||||
rle = NULL;
|
|
||||||
if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
|
|
||||||
STAILQ_FOREACH(rle, rl, link) {
|
|
||||||
if (type == rle->type && addr >= rle->start &&
|
|
||||||
addr < rle->start + rle->count)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
return (rle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct resource *
|
static struct resource *
|
||||||
acpi_alloc_resource(device_t bus, device_t child, int type, int *rid,
|
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)
|
||||||
@ -995,6 +968,19 @@ acpi_alloc_resource(device_t bus, device_t child, int type, int *rid,
|
|||||||
struct rman *rm;
|
struct rman *rm;
|
||||||
|
|
||||||
res = NULL;
|
res = NULL;
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
rm = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ACPI_SERIAL_BEGIN(acpi);
|
ACPI_SERIAL_BEGIN(acpi);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1011,35 +997,19 @@ acpi_alloc_resource(device_t bus, device_t child, int type, int *rid,
|
|||||||
count = rle->count;
|
count = rle->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't manage this address, pass the request up to the parent. */
|
/*
|
||||||
rle = acpi_sysres_find(bus, type, start);
|
* If this is an allocation of a specific range, see if we can satisfy
|
||||||
if (rle == NULL) {
|
* the request from our system resource regions. If we can't, pass the
|
||||||
|
* request up to the parent.
|
||||||
|
*/
|
||||||
|
if (!(start == 0UL && end == ~0UL) && rm != NULL)
|
||||||
|
res = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
|
||||||
|
child);
|
||||||
|
if (res == NULL) {
|
||||||
res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid,
|
res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid,
|
||||||
start, end, count, flags);
|
start, end, count, flags);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
res = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
|
|
||||||
child);
|
|
||||||
if (res == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* Copy the bus tag and handle from the pre-allocated resource. */
|
|
||||||
rman_set_rid(res, *rid);
|
rman_set_rid(res, *rid);
|
||||||
rman_set_bustag(res, rman_get_bustag(rle->res));
|
|
||||||
rman_set_bushandle(res, rman_get_start(res));
|
|
||||||
|
|
||||||
/* If requested, activate the resource using the parent's method. */
|
/* If requested, activate the resource using the parent's method. */
|
||||||
if (flags & RF_ACTIVE)
|
if (flags & RF_ACTIVE)
|
||||||
@ -1075,15 +1045,29 @@ static int
|
|||||||
acpi_release_resource(device_t bus, device_t child, int type, int rid,
|
acpi_release_resource(device_t bus, device_t child, int type, int rid,
|
||||||
struct resource *r)
|
struct resource *r)
|
||||||
{
|
{
|
||||||
|
struct rman *rm;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
rm = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ACPI_SERIAL_BEGIN(acpi);
|
ACPI_SERIAL_BEGIN(acpi);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we know about this address, deactivate it and release it to the
|
* If this resource belongs to one of our internal managers,
|
||||||
* local pool. If we don't, pass this request up to the parent.
|
* deactivate it and release it to the local pool. If it doesn't,
|
||||||
|
* pass this request up to the parent.
|
||||||
*/
|
*/
|
||||||
if (acpi_sysres_find(bus, type, rman_get_start(r)) != NULL) {
|
if (rm != NULL && rman_is_region_manager(r, rm)) {
|
||||||
if (rman_get_flags(r) & RF_ACTIVE) {
|
if (rman_get_flags(r) & RF_ACTIVE) {
|
||||||
ret = bus_deactivate_resource(child, type, rid, r);
|
ret = bus_deactivate_resource(child, type, rid, r);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user