patch-2.4.19 linux-2.4.19/arch/i386/kernel/acpitable.c
Next file: linux-2.4.19/arch/i386/kernel/apic.c
Previous file: linux-2.4.19/arch/i386/defconfig
Back to the patch index
Back to the overall index
- Lines: 77
- Date:
Fri Aug 2 17:39:42 2002
- Orig file:
linux-2.4.18/arch/i386/kernel/acpitable.c
- Orig date:
Sun Nov 11 19:15:06 2001
diff -urN linux-2.4.18/arch/i386/kernel/acpitable.c linux-2.4.19/arch/i386/kernel/acpitable.c
@@ -172,40 +172,41 @@
/*
- * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_0,
+ * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
* to map the target physical address. The problem is that set_fixmap()
* provides a single page, and it is possible that the page is not
* sufficient.
* By using this area, we can map up to MAX_IO_APICS pages temporarily,
* i.e. until the next __va_range() call.
+ *
+ * Important Safety Note: The fixed I/O APIC page numbers are *subtracted*
+ * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and
+ * count idx down while incrementing the phys address.
*/
-static __inline__ char *
+static __init char *
__va_range(unsigned long phys, unsigned long size)
{
- unsigned long base, offset, mapped_size, mapped_phys = phys;
- int idx = FIX_IO_APIC_BASE_0;
+ unsigned long base, offset, mapped_size;
+ int idx;
offset = phys & (PAGE_SIZE - 1);
mapped_size = PAGE_SIZE - offset;
- set_fixmap(idx, mapped_phys);
- base = fix_to_virt(FIX_IO_APIC_BASE_0);
+ set_fixmap(FIX_IO_APIC_BASE_END, phys);
+ base = fix_to_virt(FIX_IO_APIC_BASE_END);
+ dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx\n", phys, size,
+ FIX_IO_APIC_BASE_END, base);
/*
* Most cases can be covered by the below.
*/
- if (mapped_size >= size)
- return ((unsigned char *) base + offset);
-
- dprintk("__va_range: mapping more than a single page, size = 0x%lx\n",
- size);
-
- do {
- if (idx++ == FIX_IO_APIC_BASE_END)
+ idx = FIX_IO_APIC_BASE_END;
+ while (mapped_size < size) {
+ if (--idx < FIX_IO_APIC_BASE_0)
return 0; /* cannot handle this */
- mapped_phys = mapped_phys + PAGE_SIZE;
- set_fixmap(idx, mapped_phys);
- mapped_size = mapped_size + PAGE_SIZE;
- } while (mapped_size < size);
+ phys += PAGE_SIZE;
+ set_fixmap(idx, phys);
+ mapped_size += PAGE_SIZE;
+ }
return ((unsigned char *) base + offset);
}
@@ -267,11 +268,14 @@
}
for (i = 0; i < tables; i++) {
-
+ /* Map in header, then map in full table length. */
header = (acpi_table_header *)
__va_range(saved_rsdt.entry[i],
sizeof(acpi_table_header));
-
+ if (!header)
+ break;
+ header = (acpi_table_header *)
+ __va_range(saved_rsdt.entry[i], header->length);
if (!header)
break;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)