Index: src/sys/dev/acpica/acpi.c =================================================================== RCS file: /home/ncvs/src/sys/dev/acpica/acpi.c,v retrieving revision 1.234 diff -u -r1.234 acpi.c --- src/sys/dev/acpica/acpi.c 22 Mar 2007 18:16:40 -0000 1.234 +++ src/sys/dev/acpica/acpi.c 7 Apr 2007 06:07:08 -0000 @@ -108,6 +108,8 @@ uintptr_t value); static struct resource_list *acpi_get_rlist(device_t dev, device_t child); 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, int type, int *rid, u_long start, u_long end, u_long count, u_int flags); @@ -988,6 +990,31 @@ 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 * 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) @@ -1000,19 +1027,6 @@ struct rman *rm; 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); /* @@ -1029,19 +1043,35 @@ count = rle->count; } - /* - * If this is an allocation of a specific range, see if we can satisfy - * 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) { + /* If we don't manage this address, pass the request up to the parent. */ + rle = acpi_sysres_find(bus, type, start); + if (rle == NULL) { res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, start, end, count, flags); } 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_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 (flags & RF_ACTIVE) @@ -1077,29 +1107,15 @@ acpi_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - struct rman *rm; 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); /* - * If this resource belongs to one of our internal managers, - * deactivate it and release it to the local pool. If it doesn't, - * pass this request up to the parent. + * 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 (rm != NULL && rman_is_region_manager(r, rm)) { + if (acpi_sysres_find(bus, type, rman_get_start(r)) != NULL) { if (rman_get_flags(r) & RF_ACTIVE) { ret = bus_deactivate_resource(child, type, rid, r); if (ret != 0)