Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 222122
b: refs/heads/master
c: 4723d0f
h: refs/heads/master
v: v3
  • Loading branch information
Bjorn Helgaas authored and Jesse Barnes committed Nov 11, 2010
1 parent be9ee98 commit 0778fc3
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ac3abf2c37a9b0be604ea9825705a8510a9a6ba3
refs/heads/master: 4723d0f2f96e6c910f951d595067eb31e0dd2d01
103 changes: 83 additions & 20 deletions trunk/arch/x86/pci/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,17 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
struct acpi_resource_address64 addr;
acpi_status status;
unsigned long flags;
struct resource *root, *conflict;
u64 start, end;

status = resource_to_addr(acpi_res, &addr);
if (!ACPI_SUCCESS(status))
return AE_OK;

if (addr.resource_type == ACPI_MEMORY_RANGE) {
root = &iomem_resource;
flags = IORESOURCE_MEM;
if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
flags |= IORESOURCE_PREFETCH;
} else if (addr.resource_type == ACPI_IO_RANGE) {
root = &ioport_resource;
flags = IORESOURCE_IO;
} else
return AE_OK;
Expand All @@ -172,25 +169,90 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
return AE_OK;
}

conflict = insert_resource_conflict(root, res);
if (conflict) {
dev_err(&info->bridge->dev,
"address space collision: host bridge window %pR "
"conflicts with %s %pR\n",
res, conflict->name, conflict);
} else {
pci_bus_add_resource(info->bus, res, 0);
info->res_num++;
if (addr.translation_offset)
dev_info(&info->bridge->dev, "host bridge window %pR "
"(PCI address [%#llx-%#llx])\n",
res, res->start - addr.translation_offset,
res->end - addr.translation_offset);
info->res_num++;
if (addr.translation_offset)
dev_info(&info->bridge->dev, "host bridge window %pR "
"(PCI address [%#llx-%#llx])\n",
res, res->start - addr.translation_offset,
res->end - addr.translation_offset);
else
dev_info(&info->bridge->dev, "host bridge window %pR\n", res);

return AE_OK;
}

static bool resource_contains(struct resource *res, resource_size_t point)
{
if (res->start <= point && point <= res->end)
return true;
return false;
}

static void coalesce_windows(struct pci_root_info *info, int type)
{
int i, j;
struct resource *res1, *res2;

for (i = 0; i < info->res_num; i++) {
res1 = &info->res[i];
if (!(res1->flags & type))
continue;

for (j = i + 1; j < info->res_num; j++) {
res2 = &info->res[j];
if (!(res2->flags & type))
continue;

/*
* I don't like throwing away windows because then
* our resources no longer match the ACPI _CRS, but
* the kernel resource tree doesn't allow overlaps.
*/
if (resource_contains(res1, res2->start) ||
resource_contains(res1, res2->end) ||
resource_contains(res2, res1->start) ||
resource_contains(res2, res1->end)) {
res1->start = min(res1->start, res2->start);
res1->end = max(res1->end, res2->end);
dev_info(&info->bridge->dev,
"host bridge window expanded to %pR; %pR ignored\n",
res1, res2);
res2->flags = 0;
}
}
}
}

static void add_resources(struct pci_root_info *info)
{
int i;
struct resource *res, *root, *conflict;

if (!pci_use_crs)
return;

coalesce_windows(info, IORESOURCE_MEM);
coalesce_windows(info, IORESOURCE_IO);

for (i = 0; i < info->res_num; i++) {
res = &info->res[i];

if (res->flags & IORESOURCE_MEM)
root = &iomem_resource;
else if (res->flags & IORESOURCE_IO)
root = &ioport_resource;
else
dev_info(&info->bridge->dev,
"host bridge window %pR\n", res);
continue;

conflict = insert_resource_conflict(root, res);
if (conflict)
dev_err(&info->bridge->dev,
"address space collision: host bridge window %pR "
"conflicts with %s %pR\n",
res, conflict->name, conflict);
else
pci_bus_add_resource(info->bus, res, 0);
}
return AE_OK;
}

static void
Expand Down Expand Up @@ -224,6 +286,7 @@ get_current_resources(struct acpi_device *device, int busnum,
acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
&info);

add_resources(&info);
return;

name_alloc_fail:
Expand Down

0 comments on commit 0778fc3

Please sign in to comment.