Skip to content

Commit

Permalink
[IA64] respect ACPI producer/consumer flag for PCI root bridges
Browse files Browse the repository at this point in the history
Address space resources for ACPI devices have a producer/consumer
flag.  All devices "consume" the indicated address space.  If the
resource is marked as a "producer", the range is also passed on
to child devices.

We currently ignore this flag when setting up MMIO and I/O port
windows for PCI root bridges, so we could mistakenly interpret
a "consumed-only" range, like CSR space for the device itself,
as a window that is routed to children.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
  • Loading branch information
Bjorn Helgaas authored and Tony Luck committed Sep 23, 2005
1 parent 12f44f4 commit 463eb29
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions arch/ia64/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,18 +191,39 @@ add_io_space (struct acpi_resource_address64 *addr)
return IO_SPACE_BASE(i);
}

static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
struct acpi_resource_address64 *addr)
{
acpi_status status;

/*
* We're only interested in _CRS descriptors that are
* - address space descriptors for memory or I/O space
* - non-zero size
* - producers, i.e., the address space is routed downstream,
* not consumed by the bridge itself
*/
status = acpi_resource_to_address64(resource, addr);
if (ACPI_SUCCESS(status) &&
(addr->resource_type == ACPI_MEMORY_RANGE ||
addr->resource_type == ACPI_IO_RANGE) &&
addr->address_length &&
addr->producer_consumer == ACPI_PRODUCER)
return AE_OK;

return AE_ERROR;
}

static acpi_status __devinit
count_window (struct acpi_resource *resource, void *data)
{
unsigned int *windows = (unsigned int *) data;
struct acpi_resource_address64 addr;
acpi_status status;

status = acpi_resource_to_address64(resource, &addr);
status = resource_to_window(resource, &addr);
if (ACPI_SUCCESS(status))
if (addr.resource_type == ACPI_MEMORY_RANGE ||
addr.resource_type == ACPI_IO_RANGE)
(*windows)++;
(*windows)++;

return AE_OK;
}
Expand All @@ -221,13 +242,11 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
unsigned long flags, offset = 0;
struct resource *root;

status = acpi_resource_to_address64(res, &addr);
/* Return AE_OK for non-window resources to keep scanning for more */
status = resource_to_window(res, &addr);
if (!ACPI_SUCCESS(status))
return AE_OK;

if (!addr.address_length)
return AE_OK;

if (addr.resource_type == ACPI_MEMORY_RANGE) {
flags = IORESOURCE_MEM;
root = &iomem_resource;
Expand Down

0 comments on commit 463eb29

Please sign in to comment.