Commit 7eb7c27a authored by Andy Grover's avatar Andy Grover

ACPI: Update ACPI PHP driver with to use new acpi_walk_resource API

(Bjorn Helgaas)
parent c74c7c6a
...@@ -229,136 +229,55 @@ static int detect_ejectable_slots (acpi_handle *bridge_handle) ...@@ -229,136 +229,55 @@ static int detect_ejectable_slots (acpi_handle *bridge_handle)
/* decode ACPI _CRS data and convert into our internal resource list /* decode ACPI _CRS data and convert into our internal resource list
* TBD: _TRA, etc. * TBD: _TRA, etc.
*/ */
static void static acpi_status
decode_acpi_resource (struct acpi_resource *resource, struct acpiphp_bridge *bridge) decode_acpi_resource (struct acpi_resource *resource, void *context)
{ {
struct acpi_resource_address16 *address16_data; struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
struct acpi_resource_address32 *address32_data; struct acpi_resource_address64 address;
struct acpi_resource_address64 *address64_data;
struct pci_resource *res; struct pci_resource *res;
u32 resource_type, producer_consumer, address_length; if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
u64 min_address_range, max_address_range; resource->id != ACPI_RSTYPE_ADDRESS32 &&
u16 cache_attribute = 0; resource->id != ACPI_RSTYPE_ADDRESS64)
return AE_OK;
int done = 0, found;
/* shut up gcc */
resource_type = producer_consumer = address_length = 0;
min_address_range = max_address_range = 0;
while (!done) {
found = 0;
switch (resource->id) {
case ACPI_RSTYPE_ADDRESS16:
address16_data = (struct acpi_resource_address16 *)&resource->data;
resource_type = address16_data->resource_type;
producer_consumer = address16_data->producer_consumer;
min_address_range = address16_data->min_address_range;
max_address_range = address16_data->max_address_range;
address_length = address16_data->address_length;
if (resource_type == ACPI_MEMORY_RANGE)
cache_attribute = address16_data->attribute.memory.cache_attribute;
found = 1;
break;
case ACPI_RSTYPE_ADDRESS32:
address32_data = (struct acpi_resource_address32 *)&resource->data;
resource_type = address32_data->resource_type;
producer_consumer = address32_data->producer_consumer;
min_address_range = address32_data->min_address_range;
max_address_range = address32_data->max_address_range;
address_length = address32_data->address_length;
if (resource_type == ACPI_MEMORY_RANGE)
cache_attribute = address32_data->attribute.memory.cache_attribute;
found = 1;
break;
case ACPI_RSTYPE_ADDRESS64:
address64_data = (struct acpi_resource_address64 *)&resource->data;
resource_type = address64_data->resource_type;
producer_consumer = address64_data->producer_consumer;
min_address_range = address64_data->min_address_range;
max_address_range = address64_data->max_address_range;
address_length = address64_data->address_length;
if (resource_type == ACPI_MEMORY_RANGE)
cache_attribute = address64_data->attribute.memory.cache_attribute;
found = 1;
break;
case ACPI_RSTYPE_END_TAG:
done = 1;
break;
default:
/* ignore */
break;
}
resource = (struct acpi_resource *)((char*)resource + resource->length); acpi_resource_to_address64(resource, &address);
if (found && producer_consumer == ACPI_PRODUCER && address_length > 0) { if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
switch (resource_type) { dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type, address.min_address_range, address.max_address_range);
case ACPI_MEMORY_RANGE: res = acpiphp_make_resource(address.min_address_range,
if (cache_attribute == ACPI_PREFETCHABLE_MEMORY) { address.address_length);
dbg("resource type: prefetchable memory 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
res = acpiphp_make_resource(min_address_range,
address_length);
if (!res) { if (!res) {
err("out of memory\n"); err("out of memory\n");
return; return AE_OK;
} }
switch (address.resource_type) {
case ACPI_MEMORY_RANGE:
if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
res->next = bridge->p_mem_head; res->next = bridge->p_mem_head;
bridge->p_mem_head = res; bridge->p_mem_head = res;
} else { } else {
dbg("resource type: memory 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
res = acpiphp_make_resource(min_address_range,
address_length);
if (!res) {
err("out of memory\n");
return;
}
res->next = bridge->mem_head; res->next = bridge->mem_head;
bridge->mem_head = res; bridge->mem_head = res;
} }
break; break;
case ACPI_IO_RANGE: case ACPI_IO_RANGE:
dbg("resource type: io 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
res = acpiphp_make_resource(min_address_range,
address_length);
if (!res) {
err("out of memory\n");
return;
}
res->next = bridge->io_head; res->next = bridge->io_head;
bridge->io_head = res; bridge->io_head = res;
break; break;
case ACPI_BUS_NUMBER_RANGE: case ACPI_BUS_NUMBER_RANGE:
dbg("resource type: bus number %d - %d\n", (u32)min_address_range, (u32)max_address_range);
res = acpiphp_make_resource(min_address_range,
address_length);
if (!res) {
err("out of memory\n");
return;
}
res->next = bridge->bus_head; res->next = bridge->bus_head;
bridge->bus_head = res; bridge->bus_head = res;
break; break;
default: default:
/* invalid type */ /* invalid type */
kfree(res);
break; break;
} }
} }
}
acpiphp_resource_sort_and_combine(&bridge->io_head); return AE_OK;
acpiphp_resource_sort_and_combine(&bridge->mem_head);
acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
acpiphp_resource_sort_and_combine(&bridge->bus_head);
dbg("ACPI _CRS resource:\n");
acpiphp_dump_resource(bridge);
} }
...@@ -476,9 +395,6 @@ static void init_bridge_misc (struct acpiphp_bridge *bridge) ...@@ -476,9 +395,6 @@ static void init_bridge_misc (struct acpiphp_bridge *bridge)
static void add_host_bridge (acpi_handle *handle, int seg, int bus) static void add_host_bridge (acpi_handle *handle, int seg, int bus)
{ {
acpi_status status; acpi_status status;
struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
.pointer = NULL};
struct acpiphp_bridge *bridge; struct acpiphp_bridge *bridge;
bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
...@@ -501,7 +417,8 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus) ...@@ -501,7 +417,8 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus)
/* decode resources */ /* decode resources */
status = acpi_get_current_resources(handle, &buffer); status = acpi_walk_resources(handle, METHOD_NAME__CRS,
decode_acpi_resource, bridge);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
err("failed to decode bridge resources\n"); err("failed to decode bridge resources\n");
...@@ -509,8 +426,13 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus) ...@@ -509,8 +426,13 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus)
return; return;
} }
decode_acpi_resource(buffer.pointer, bridge); acpiphp_resource_sort_and_combine(&bridge->io_head);
kfree(buffer.pointer); acpiphp_resource_sort_and_combine(&bridge->mem_head);
acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
acpiphp_resource_sort_and_combine(&bridge->bus_head);
dbg("ACPI _CRS resource:\n");
acpiphp_dump_resource(bridge);
if (bridge->bus_head) { if (bridge->bus_head) {
bridge->bus = bridge->bus_head->base; bridge->bus = bridge->bus_head->base;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment