summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Grover <agrover@groveronline.com>2003-07-13 22:50:26 -0700
committerAndy Grover <agrover@groveronline.com>2003-07-13 22:50:26 -0700
commit8144203765d316a57a30e69a493e8b4bf2cd9107 (patch)
tree233d1fc5ef5fa094f9fb86409b973fb22c062934
parentfbdebc89ca92c0ee6e56ab82b6806eaa0a657205 (diff)
ACPI: Dynamically allocate SDT list (suggested by Andi Kleen)
-rw-r--r--drivers/acpi/tables.c99
1 files changed, 54 insertions, 45 deletions
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 3919b450f86f..233f8e3579df 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -33,6 +33,7 @@
#include <linux/irq.h>
#include <linux/errno.h>
#include <linux/acpi.h>
+#include <linux/bootmem.h>
#define PREFIX "ACPI: "
@@ -61,16 +62,14 @@ static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
/* System Description Table (RSDT/XSDT) */
struct acpi_table_sdt {
- unsigned long pa; /* Physical Address */
- unsigned long count; /* Table count */
- struct {
- unsigned long pa;
- enum acpi_table_id id;
- unsigned long size;
- } entry[ACPI_MAX_TABLES];
+ unsigned long pa;
+ enum acpi_table_id id;
+ unsigned long size;
} __attribute__ ((packed));
-static struct acpi_table_sdt sdt;
+static unsigned long sdt_pa; /* Physical Address */
+static unsigned long sdt_count; /* Table count */
+static struct acpi_table_sdt *sdt_entry;
void
acpi_table_print (
@@ -236,11 +235,11 @@ acpi_get_table_header_early (
/* Locate the table. */
- for (i = 0; i < sdt.count; i++) {
- if (sdt.entry[i].id != temp_id)
+ for (i = 0; i < sdt_count; i++) {
+ if (sdt_entry[i].id != temp_id)
continue;
*header = (void *)
- __acpi_map_table(sdt.entry[i].pa, sdt.entry[i].size);
+ __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
if (!*header) {
printk(KERN_WARNING PREFIX "Unable to map %s\n",
acpi_table_signatures[temp_id]);
@@ -289,11 +288,11 @@ acpi_table_parse_madt_family (
/* Locate the MADT (if exists). There should only be one. */
- for (i = 0; i < sdt.count; i++) {
- if (sdt.entry[i].id != id)
+ for (i = 0; i < sdt_count; i++) {
+ if (sdt_entry[i].id != id)
continue;
madt = (void *)
- __acpi_map_table(sdt.entry[i].pa, sdt.entry[i].size);
+ __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
if (!madt) {
printk(KERN_WARNING PREFIX "Unable to map %s\n",
acpi_table_signatures[id]);
@@ -308,7 +307,7 @@ acpi_table_parse_madt_family (
return -ENODEV;
}
- madt_end = (unsigned long) madt + sdt.entry[i].size;
+ madt_end = (unsigned long) madt + sdt_entry[i].size;
/* Parse all entries looking for a match. */
@@ -349,10 +348,10 @@ acpi_table_parse (
if (!handler)
return -EINVAL;
- for (i = 0; i < sdt.count; i++) {
- if (sdt.entry[i].id != id)
+ for (i = 0; i < sdt_count; i++) {
+ if (sdt_entry[i].id != id)
continue;
- handler(sdt.entry[i].pa, sdt.entry[i].size);
+ handler(sdt_entry[i].pa, sdt_entry[i].size);
count++;
}
@@ -377,11 +376,11 @@ acpi_table_get_sdt (
struct acpi_table_xsdt *mapped_xsdt = NULL;
- sdt.pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;
+ sdt_pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;
/* map in just the header */
header = (struct acpi_table_header *)
- __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
+ __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
if (!header) {
printk(KERN_WARNING PREFIX "Unable to map XSDT header\n");
@@ -390,7 +389,7 @@ acpi_table_get_sdt (
/* remap in the entire table before processing */
mapped_xsdt = (struct acpi_table_xsdt *)
- __acpi_map_table(sdt.pa, header->length);
+ __acpi_map_table(sdt_pa, header->length);
if (!mapped_xsdt) {
printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
return -ENODEV;
@@ -407,15 +406,21 @@ acpi_table_get_sdt (
return -ENODEV;
}
- sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3;
- if (sdt.count > ACPI_MAX_TABLES) {
+ sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 3;
+ if (sdt_count > ACPI_MAX_TABLES) {
printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n",
- (sdt.count - ACPI_MAX_TABLES));
- sdt.count = ACPI_MAX_TABLES;
+ (sdt_count - ACPI_MAX_TABLES));
+ sdt_count = ACPI_MAX_TABLES;
}
- for (i = 0; i < sdt.count; i++)
- sdt.entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
+ sdt_entry = alloc_bootmem(sdt_count * sizeof(struct acpi_table_sdt));
+ if (!sdt_entry) {
+ printk(KERN_ERR "ACPI: Could not allocate mem for SDT entries!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < sdt_count; i++)
+ sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
}
/* Then check RSDT */
@@ -424,11 +429,11 @@ acpi_table_get_sdt (
struct acpi_table_rsdt *mapped_rsdt = NULL;
- sdt.pa = rsdp->rsdt_address;
+ sdt_pa = rsdp->rsdt_address;
/* map in just the header */
header = (struct acpi_table_header *)
- __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
+ __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
if (!header) {
printk(KERN_WARNING PREFIX "Unable to map RSDT header\n");
return -ENODEV;
@@ -436,7 +441,7 @@ acpi_table_get_sdt (
/* remap in the entire table before processing */
mapped_rsdt = (struct acpi_table_rsdt *)
- __acpi_map_table(sdt.pa, header->length);
+ __acpi_map_table(sdt_pa, header->length);
if (!mapped_rsdt) {
printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
return -ENODEV;
@@ -453,15 +458,21 @@ acpi_table_get_sdt (
return -ENODEV;
}
- sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 2;
- if (sdt.count > ACPI_MAX_TABLES) {
+ sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 2;
+ if (sdt_count > ACPI_MAX_TABLES) {
printk(KERN_WARNING PREFIX "Truncated %lu RSDT entries\n",
- (sdt.count - ACPI_TABLE_COUNT));
- sdt.count = ACPI_MAX_TABLES;
+ (sdt_count - ACPI_MAX_TABLES));
+ sdt_count = ACPI_MAX_TABLES;
}
- for (i = 0; i < sdt.count; i++)
- sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
+ sdt_entry = alloc_bootmem(sdt_count * sizeof(struct acpi_table_sdt));
+ if (!sdt_entry) {
+ printk(KERN_ERR "ACPI: Could not allocate mem for SDT entries!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < sdt_count; i++)
+ sdt_entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
}
else {
@@ -469,38 +480,38 @@ acpi_table_get_sdt (
return -ENODEV;
}
- acpi_table_print(header, sdt.pa);
+ acpi_table_print(header, sdt_pa);
- for (i = 0; i < sdt.count; i++) {
+ for (i = 0; i < sdt_count; i++) {
/* map in just the header */
header = (struct acpi_table_header *)
- __acpi_map_table(sdt.entry[i].pa,
+ __acpi_map_table(sdt_entry[i].pa,
sizeof(struct acpi_table_header));
if (!header)
continue;
/* remap in the entire table before processing */
header = (struct acpi_table_header *)
- __acpi_map_table(sdt.entry[i].pa,
+ __acpi_map_table(sdt_entry[i].pa,
header->length);
if (!header)
continue;
- acpi_table_print(header, sdt.entry[i].pa);
+ acpi_table_print(header, sdt_entry[i].pa);
if (acpi_table_compute_checksum(header, header->length)) {
printk(KERN_WARNING " >>> ERROR: Invalid checksum\n");
continue;
}
- sdt.entry[i].size = header->length;
+ sdt_entry[i].size = header->length;
for (id = 0; id < ACPI_TABLE_COUNT; id++) {
if (!strncmp((char *) &header->signature,
acpi_table_signatures[id],
sizeof(header->signature))) {
- sdt.entry[i].id = id;
+ sdt_entry[i].id = id;
}
}
}
@@ -525,8 +536,6 @@ acpi_table_init (void)
unsigned long rsdp_phys = 0;
int result = 0;
- memset(&sdt, 0, sizeof(struct acpi_table_sdt));
-
/* Locate and map the Root System Description Table (RSDP) */
rsdp_phys = acpi_find_rsdp();