Skip to content

Commit

Permalink
PNPACPI: parse Extended Address Space Descriptors
Browse files Browse the repository at this point in the history
Extended Address Space Descriptors are new in ACPI 3.0 and allow the
BIOS to communicate device resource cacheability attributes (write-back,
write-through, uncacheable, etc) to the OS.

Previously, PNPACPI ignored these descriptors, so if a BIOS used them,
a device could be responding at addresses the OS doesn't know about.
This patch adds support for these descriptors in _CRS and _PRS.  We
don't attempt to encode them for _SRS (just like we don't attempt to
encode the existing 16-, 32-, and 64-bit Address Space Descriptors).

Unfortunately, I don't have a way to test this.

Signed-off-by: Bjorn Helgaas <[email protected]>
Signed-off-by: Len Brown <[email protected]>
  • Loading branch information
Bjorn Helgaas authored and lenb committed May 28, 2009
1 parent cd86a53 commit 8cb24c8
Showing 1 changed file with 44 additions and 2 deletions.
46 changes: 44 additions & 2 deletions drivers/pnp/pnpacpi/rsparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,25 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
ACPI_DECODE_16);
}

static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
struct acpi_resource *res)
{
struct acpi_resource_extended_address64 *p = &res->data.ext_address64;

if (p->producer_consumer == ACPI_PRODUCER)
return;

if (p->resource_type == ACPI_MEMORY_RANGE)
pnpacpi_parse_allocated_memresource(dev,
p->minimum, p->address_length,
p->info.mem.write_protect);
else if (p->resource_type == ACPI_IO_RANGE)
pnpacpi_parse_allocated_ioresource(dev,
p->minimum, p->address_length,
p->granularity == 0xfff ? ACPI_DECODE_10 :
ACPI_DECODE_16);
}

static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
void *data)
{
Expand Down Expand Up @@ -400,8 +419,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
break;

case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
return AE_OK;
pnpacpi_parse_allocated_ext_address_space(dev, res);
break;

case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
Expand Down Expand Up @@ -630,6 +648,28 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
IORESOURCE_IO_FIXED);
}

static __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev,
unsigned int option_flags,
struct acpi_resource *r)
{
struct acpi_resource_extended_address64 *p = &r->data.ext_address64;
unsigned char flags = 0;

if (p->address_length == 0)
return;

if (p->resource_type == ACPI_MEMORY_RANGE) {
if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
flags = IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->minimum,
p->minimum, 0, p->address_length,
flags);
} else if (p->resource_type == ACPI_IO_RANGE)
pnp_register_port_resource(dev, option_flags, p->minimum,
p->minimum, 0, p->address_length,
IORESOURCE_IO_FIXED);
}

struct acpipnp_parse_option_s {
struct pnp_dev *dev;
unsigned int option_flags;
Expand Down Expand Up @@ -711,6 +751,7 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
break;

case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
pnpacpi_parse_ext_address_option(dev, option_flags, res);
break;

case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
Expand Down Expand Up @@ -765,6 +806,7 @@ static int pnpacpi_supported_resource(struct acpi_resource *res)
case ACPI_RESOURCE_TYPE_ADDRESS16:
case ACPI_RESOURCE_TYPE_ADDRESS32:
case ACPI_RESOURCE_TYPE_ADDRESS64:
case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
return 1;
}
Expand Down

0 comments on commit 8cb24c8

Please sign in to comment.