diff options
-rw-r--r-- | drivers/acpi/resource.c | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 1c616a56e007..3e7d9f6eb875 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
@@ -34,21 +34,37 @@ | |||
34 | #define valid_IRQ(i) (true) | 34 | #define valid_IRQ(i) (true) |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect, | 37 | static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io) |
38 | bool window) | ||
39 | { | 38 | { |
40 | unsigned long flags = IORESOURCE_MEM; | 39 | u64 reslen = end - start + 1; |
41 | 40 | ||
42 | if (len == 0) | 41 | /* |
43 | flags |= IORESOURCE_DISABLED; | 42 | * CHECKME: len might be required to check versus a minimum |
43 | * length as well. 1 for io is fine, but for memory it does | ||
44 | * not make any sense at all. | ||
45 | */ | ||
46 | if (len && reslen && reslen == len && start <= end) | ||
47 | return true; | ||
48 | |||
49 | pr_info("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n", | ||
50 | io ? "io" : "mem", start, end, len); | ||
51 | |||
52 | return false; | ||
53 | } | ||
54 | |||
55 | static void acpi_dev_memresource_flags(struct resource *res, u64 len, | ||
56 | u8 write_protect, bool window) | ||
57 | { | ||
58 | res->flags = IORESOURCE_MEM; | ||
59 | |||
60 | if (!acpi_dev_resource_len_valid(res->start, res->end, len, false)) | ||
61 | res->flags |= IORESOURCE_DISABLED; | ||
44 | 62 | ||
45 | if (write_protect == ACPI_READ_WRITE_MEMORY) | 63 | if (write_protect == ACPI_READ_WRITE_MEMORY) |
46 | flags |= IORESOURCE_MEM_WRITEABLE; | 64 | res->flags |= IORESOURCE_MEM_WRITEABLE; |
47 | 65 | ||
48 | if (window) | 66 | if (window) |
49 | flags |= IORESOURCE_WINDOW; | 67 | res->flags |= IORESOURCE_WINDOW; |
50 | |||
51 | return flags; | ||
52 | } | 68 | } |
53 | 69 | ||
54 | static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len, | 70 | 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, | |||
56 | { | 72 | { |
57 | res->start = start; | 73 | res->start = start; |
58 | res->end = start + len - 1; | 74 | res->end = start + len - 1; |
59 | res->flags = acpi_dev_memresource_flags(len, write_protect, false); | 75 | acpi_dev_memresource_flags(res, len, write_protect, false); |
60 | } | 76 | } |
61 | 77 | ||
62 | /** | 78 | /** |
@@ -77,24 +93,18 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) | |||
77 | switch (ares->type) { | 93 | switch (ares->type) { |
78 | case ACPI_RESOURCE_TYPE_MEMORY24: | 94 | case ACPI_RESOURCE_TYPE_MEMORY24: |
79 | memory24 = &ares->data.memory24; | 95 | memory24 = &ares->data.memory24; |
80 | if (!memory24->minimum && !memory24->address_length) | ||
81 | return false; | ||
82 | acpi_dev_get_memresource(res, memory24->minimum, | 96 | acpi_dev_get_memresource(res, memory24->minimum, |
83 | memory24->address_length, | 97 | memory24->address_length, |
84 | memory24->write_protect); | 98 | memory24->write_protect); |
85 | break; | 99 | break; |
86 | case ACPI_RESOURCE_TYPE_MEMORY32: | 100 | case ACPI_RESOURCE_TYPE_MEMORY32: |
87 | memory32 = &ares->data.memory32; | 101 | memory32 = &ares->data.memory32; |
88 | if (!memory32->minimum && !memory32->address_length) | ||
89 | return false; | ||
90 | acpi_dev_get_memresource(res, memory32->minimum, | 102 | acpi_dev_get_memresource(res, memory32->minimum, |
91 | memory32->address_length, | 103 | memory32->address_length, |
92 | memory32->write_protect); | 104 | memory32->write_protect); |
93 | break; | 105 | break; |
94 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 106 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
95 | fixed_memory32 = &ares->data.fixed_memory32; | 107 | fixed_memory32 = &ares->data.fixed_memory32; |
96 | if (!fixed_memory32->address && !fixed_memory32->address_length) | ||
97 | return false; | ||
98 | acpi_dev_get_memresource(res, fixed_memory32->address, | 108 | acpi_dev_get_memresource(res, fixed_memory32->address, |
99 | fixed_memory32->address_length, | 109 | fixed_memory32->address_length, |
100 | fixed_memory32->write_protect); | 110 | fixed_memory32->write_protect); |
@@ -102,7 +112,8 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) | |||
102 | default: | 112 | default: |
103 | return false; | 113 | return false; |
104 | } | 114 | } |
105 | return true; | 115 | |
116 | return !(res->flags & IORESOURCE_DISABLED); | ||
106 | } | 117 | } |
107 | EXPORT_SYMBOL_GPL(acpi_dev_resource_memory); | 118 | EXPORT_SYMBOL_GPL(acpi_dev_resource_memory); |
108 | 119 | ||
@@ -186,7 +197,6 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares, | |||
186 | acpi_status status; | 197 | acpi_status status; |
187 | struct acpi_resource_address64 addr; | 198 | struct acpi_resource_address64 addr; |
188 | bool window; | 199 | bool window; |
189 | u64 len; | ||
190 | u8 io_decode; | 200 | u8 io_decode; |
191 | 201 | ||
192 | status = acpi_resource_to_address64(ares, &addr); | 202 | status = acpi_resource_to_address64(ares, &addr); |
@@ -199,10 +209,9 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares, | |||
199 | 209 | ||
200 | switch(addr.resource_type) { | 210 | switch(addr.resource_type) { |
201 | case ACPI_MEMORY_RANGE: | 211 | case ACPI_MEMORY_RANGE: |
202 | len = addr.address.maximum - addr.address.minimum + 1; | 212 | acpi_dev_memresource_flags(res, addr.address.address_length, |
203 | res->flags = acpi_dev_memresource_flags(len, | 213 | addr.info.mem.write_protect, |
204 | addr.info.mem.write_protect, | 214 | window); |
205 | window); | ||
206 | break; | 215 | break; |
207 | case ACPI_IO_RANGE: | 216 | case ACPI_IO_RANGE: |
208 | io_decode = addr.address.granularity == 0xfff ? | 217 | io_decode = addr.address.granularity == 0xfff ? |
@@ -236,7 +245,6 @@ bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, | |||
236 | { | 245 | { |
237 | struct acpi_resource_extended_address64 *ext_addr; | 246 | struct acpi_resource_extended_address64 *ext_addr; |
238 | bool window; | 247 | bool window; |
239 | u64 len; | ||
240 | u8 io_decode; | 248 | u8 io_decode; |
241 | 249 | ||
242 | if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) | 250 | if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) |
@@ -250,10 +258,10 @@ bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, | |||
250 | 258 | ||
251 | switch(ext_addr->resource_type) { | 259 | switch(ext_addr->resource_type) { |
252 | case ACPI_MEMORY_RANGE: | 260 | case ACPI_MEMORY_RANGE: |
253 | len = ext_addr->address.maximum - ext_addr->address.minimum + 1; | 261 | acpi_dev_memresource_flags(res, |
254 | res->flags = acpi_dev_memresource_flags(len, | 262 | ext_addr->address.address_length, |
255 | ext_addr->info.mem.write_protect, | 263 | ext_addr->info.mem.write_protect, |
256 | window); | 264 | window); |
257 | break; | 265 | break; |
258 | case ACPI_IO_RANGE: | 266 | case ACPI_IO_RANGE: |
259 | io_decode = ext_addr->address.granularity == 0xfff ? | 267 | io_decode = ext_addr->address.granularity == 0xfff ? |