|
|
@@ -34,21 +34,37 @@
|
|
|
#define valid_IRQ(i) (true)
|
|
|
#endif
|
|
|
|
|
|
-static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect,
|
|
|
- bool window)
|
|
|
+static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
|
|
|
{
|
|
|
- unsigned long flags = IORESOURCE_MEM;
|
|
|
+ u64 reslen = end - start + 1;
|
|
|
|
|
|
- if (len == 0)
|
|
|
- flags |= IORESOURCE_DISABLED;
|
|
|
+ /*
|
|
|
+ * CHECKME: len might be required to check versus a minimum
|
|
|
+ * length as well. 1 for io is fine, but for memory it does
|
|
|
+ * not make any sense at all.
|
|
|
+ */
|
|
|
+ if (len && reslen && reslen == len && start <= end)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ pr_info("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n",
|
|
|
+ io ? "io" : "mem", start, end, len);
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static void acpi_dev_memresource_flags(struct resource *res, u64 len,
|
|
|
+ u8 write_protect, bool window)
|
|
|
+{
|
|
|
+ res->flags = IORESOURCE_MEM;
|
|
|
+
|
|
|
+ if (!acpi_dev_resource_len_valid(res->start, res->end, len, false))
|
|
|
+ res->flags |= IORESOURCE_DISABLED;
|
|
|
|
|
|
if (write_protect == ACPI_READ_WRITE_MEMORY)
|
|
|
- flags |= IORESOURCE_MEM_WRITEABLE;
|
|
|
+ res->flags |= IORESOURCE_MEM_WRITEABLE;
|
|
|
|
|
|
if (window)
|
|
|
- flags |= IORESOURCE_WINDOW;
|
|
|
-
|
|
|
- return flags;
|
|
|
+ res->flags |= IORESOURCE_WINDOW;
|
|
|
}
|
|
|
|
|
|
static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
|
|
|
@@ -56,7 +72,7 @@ static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
|
|
|
{
|
|
|
res->start = start;
|
|
|
res->end = start + len - 1;
|
|
|
- res->flags = acpi_dev_memresource_flags(len, write_protect, false);
|
|
|
+ acpi_dev_memresource_flags(res, len, write_protect, false);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -77,24 +93,18 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
|
|
|
switch (ares->type) {
|
|
|
case ACPI_RESOURCE_TYPE_MEMORY24:
|
|
|
memory24 = &ares->data.memory24;
|
|
|
- if (!memory24->minimum && !memory24->address_length)
|
|
|
- return false;
|
|
|
acpi_dev_get_memresource(res, memory24->minimum,
|
|
|
memory24->address_length,
|
|
|
memory24->write_protect);
|
|
|
break;
|
|
|
case ACPI_RESOURCE_TYPE_MEMORY32:
|
|
|
memory32 = &ares->data.memory32;
|
|
|
- if (!memory32->minimum && !memory32->address_length)
|
|
|
- return false;
|
|
|
acpi_dev_get_memresource(res, memory32->minimum,
|
|
|
memory32->address_length,
|
|
|
memory32->write_protect);
|
|
|
break;
|
|
|
case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
|
|
|
fixed_memory32 = &ares->data.fixed_memory32;
|
|
|
- if (!fixed_memory32->address && !fixed_memory32->address_length)
|
|
|
- return false;
|
|
|
acpi_dev_get_memresource(res, fixed_memory32->address,
|
|
|
fixed_memory32->address_length,
|
|
|
fixed_memory32->write_protect);
|
|
|
@@ -102,7 +112,8 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
|
|
|
default:
|
|
|
return false;
|
|
|
}
|
|
|
- return true;
|
|
|
+
|
|
|
+ return !(res->flags & IORESOURCE_DISABLED);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
|
|
|
|
|
|
@@ -186,7 +197,6 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares,
|
|
|
acpi_status status;
|
|
|
struct acpi_resource_address64 addr;
|
|
|
bool window;
|
|
|
- u64 len;
|
|
|
u8 io_decode;
|
|
|
|
|
|
status = acpi_resource_to_address64(ares, &addr);
|
|
|
@@ -199,10 +209,9 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares,
|
|
|
|
|
|
switch(addr.resource_type) {
|
|
|
case ACPI_MEMORY_RANGE:
|
|
|
- len = addr.address.maximum - addr.address.minimum + 1;
|
|
|
- res->flags = acpi_dev_memresource_flags(len,
|
|
|
- addr.info.mem.write_protect,
|
|
|
- window);
|
|
|
+ acpi_dev_memresource_flags(res, addr.address.address_length,
|
|
|
+ addr.info.mem.write_protect,
|
|
|
+ window);
|
|
|
break;
|
|
|
case ACPI_IO_RANGE:
|
|
|
io_decode = addr.address.granularity == 0xfff ?
|
|
|
@@ -236,7 +245,6 @@ bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
|
|
|
{
|
|
|
struct acpi_resource_extended_address64 *ext_addr;
|
|
|
bool window;
|
|
|
- u64 len;
|
|
|
u8 io_decode;
|
|
|
|
|
|
if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
|
|
|
@@ -250,10 +258,10 @@ bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
|
|
|
|
|
|
switch(ext_addr->resource_type) {
|
|
|
case ACPI_MEMORY_RANGE:
|
|
|
- len = ext_addr->address.maximum - ext_addr->address.minimum + 1;
|
|
|
- res->flags = acpi_dev_memresource_flags(len,
|
|
|
- ext_addr->info.mem.write_protect,
|
|
|
- window);
|
|
|
+ acpi_dev_memresource_flags(res,
|
|
|
+ ext_addr->address.address_length,
|
|
|
+ ext_addr->info.mem.write_protect,
|
|
|
+ window);
|
|
|
break;
|
|
|
case ACPI_IO_RANGE:
|
|
|
io_decode = ext_addr->address.granularity == 0xfff ?
|