aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c26
-rw-r--r--drivers/pnp/resource.c4
2 files changed, 8 insertions, 22 deletions
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 35bb44af49b3..100e4d9372f1 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -274,26 +274,6 @@ static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
274 pnp_add_bus_resource(dev, start, end); 274 pnp_add_bus_resource(dev, start, end);
275} 275}
276 276
277static u64 addr_space_length(struct pnp_dev *dev, u64 min, u64 max, u64 len)
278{
279 u64 max_len;
280
281 max_len = max - min + 1;
282 if (len <= max_len)
283 return len;
284
285 /*
286 * Per 6.4.3.5, _LEN cannot exceed _MAX - _MIN + 1, but some BIOSes
287 * don't do this correctly, e.g.,
288 * https://bugzilla.kernel.org/show_bug.cgi?id=15480
289 */
290 dev_info(&dev->dev,
291 "resource length %#llx doesn't fit in %#llx-%#llx, trimming\n",
292 (unsigned long long) len, (unsigned long long) min,
293 (unsigned long long) max);
294 return max_len;
295}
296
297static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, 277static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
298 struct acpi_resource *res) 278 struct acpi_resource *res)
299{ 279{
@@ -309,7 +289,8 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
309 return; 289 return;
310 } 290 }
311 291
312 len = addr_space_length(dev, p->minimum, p->maximum, p->address_length); 292 /* Windows apparently computes length rather than using _LEN */
293 len = p->maximum - p->minimum + 1;
313 window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; 294 window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
314 295
315 if (p->resource_type == ACPI_MEMORY_RANGE) 296 if (p->resource_type == ACPI_MEMORY_RANGE)
@@ -330,7 +311,8 @@ static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
330 int window; 311 int window;
331 u64 len; 312 u64 len;
332 313
333 len = addr_space_length(dev, p->minimum, p->maximum, p->address_length); 314 /* Windows apparently computes length rather than using _LEN */
315 len = p->maximum - p->minimum + 1;
334 window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; 316 window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
335 317
336 if (p->resource_type == ACPI_MEMORY_RANGE) 318 if (p->resource_type == ACPI_MEMORY_RANGE)
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 2e54e6a23c72..e3446ab8b563 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -211,6 +211,8 @@ int pnp_check_port(struct pnp_dev *dev, struct resource *res)
211 if (tres->flags & IORESOURCE_IO) { 211 if (tres->flags & IORESOURCE_IO) {
212 if (cannot_compare(tres->flags)) 212 if (cannot_compare(tres->flags))
213 continue; 213 continue;
214 if (tres->flags & IORESOURCE_WINDOW)
215 continue;
214 tport = &tres->start; 216 tport = &tres->start;
215 tend = &tres->end; 217 tend = &tres->end;
216 if (ranged_conflict(port, end, tport, tend)) 218 if (ranged_conflict(port, end, tport, tend))
@@ -271,6 +273,8 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
271 if (tres->flags & IORESOURCE_MEM) { 273 if (tres->flags & IORESOURCE_MEM) {
272 if (cannot_compare(tres->flags)) 274 if (cannot_compare(tres->flags))
273 continue; 275 continue;
276 if (tres->flags & IORESOURCE_WINDOW)
277 continue;
274 taddr = &tres->start; 278 taddr = &tres->start;
275 tend = &tres->end; 279 tend = &tres->end;
276 if (ranged_conflict(addr, end, taddr, tend)) 280 if (ranged_conflict(addr, end, taddr, tend))