drm/nouveau/bios: attempt to fetch entire acpi rom image in one shot
authorBen Skeggs <bskeggs@redhat.com>
Fri, 12 Oct 2012 02:45:15 +0000 (22:45 -0400)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 28 Nov 2012 23:56:26 +0000 (09:56 +1000)
v2: fdo#55948 - the _ROM method silently truncates size to 4KiB, perform
    a checksum test and fall back to slow _ROM access on failure.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/subdev/bios/base.c

index 70ca7d5a1aa1aaa4e4302ab599ed5398d4f666eb..1cf818d6d48e23b4b3cb5d08c35ccef20bce0d22 100644 (file)
@@ -210,11 +210,19 @@ nouveau_bios_shadow_acpi(struct nouveau_bios *bios)
                return;
 
        bios->data = kmalloc(bios->size, GFP_KERNEL);
-       for (i = 0; bios->data && i < bios->size; i += cnt) {
-               cnt = min((bios->size - i), (u32)4096);
-               ret = nouveau_acpi_get_bios_chunk(bios->data, i, cnt);
-               if (ret != cnt)
-                       break;
+       if (bios->data) {
+               /* disobey the acpi spec - much faster on at least w530 ... */
+               ret = nouveau_acpi_get_bios_chunk(bios->data, 0, bios->size);
+               if (ret != bios->size ||
+                   nvbios_checksum(bios->data, bios->size)) {
+                       /* ... that didn't work, ok, i'll be good now */
+                       for (i = 0; i < bios->size; i += cnt) {
+                               cnt = min((bios->size - i), (u32)4096);
+                               ret = nouveau_acpi_get_bios_chunk(bios->data, i, cnt);
+                               if (ret != cnt)
+                                       break;
+                       }
+               }
        }
 }