mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
[IA64] respect ACPI producer/consumer flag for PCI root bridges
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>
This commit is contained in:
parent
12f44f46bc
commit
463eb29740
@ -191,6 +191,29 @@ 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)
|
||||
{
|
||||
@ -198,11 +221,9 @@ count_window (struct acpi_resource *resource, void *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;
|
||||
}
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user