aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2010-04-27 16:45:38 -0400
committerLen Brown <len.brown@intel.com>2010-04-28 21:44:49 -0400
commitf238b414a74a13c3d62e31a08e81b585d750df74 (patch)
tree743df688cd8554f32eff514148dd31509d8055ae
parent01bf0b64579ead8a82e7cfc32ae44bc667e7ad0f (diff)
PNPACPI: compute Address Space length rather than using _LEN
ACPI _CRS Address Space Descriptors have _MIN, _MAX, and _LEN. Linux has been computing Address Spaces as [_MIN to _MIN + _LEN - 1]. Based on the tests in the bug reports below, Windows apparently uses [_MIN to _MAX]. Per spec (ACPI 4.0, Table 6-40), for _CRS fixed-size, fixed location descriptors, "_LEN must be (_MAX - _MIN + 1)", and when that's true, it doesn't matter which way we compute the end. But of course, there are BIOSes that don't follow this rule, and we're better off if Linux handles those exceptions the same way as Windows. This patch makes Linux use [_MIN to _MAX], as Windows seems to do. This effectively reverts 3162b6f0c5e and replaces it with simpler code. https://bugzilla.kernel.org/show_bug.cgi?id=14337 (round) https://bugzilla.kernel.org/show_bug.cgi?id=15480 (truncate) Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c26
1 files changed, 4 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)