ACPI / table: Add new function to get table entries

The acpi_table_parse() function has a callback that
passes a pointer to a table_header. Add a new function
which takes this pointer and parses its entries. This
eliminates the need to re-traverse all the tables for
each call. e.g. as in acpi_table_parse_madt() which is
normally called after acpi_table_parse().

Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Ashwin Chaugule 2014-11-26 22:01:13 +08:00 committed by Rafael J. Wysocki
parent 5d01410fe4
commit f08bb472bf
2 changed files with 48 additions and 19 deletions

View File

@ -190,30 +190,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
} }
} }
int __init int __init
acpi_table_parse_entries(char *id, acpi_parse_entries(char *id, unsigned long table_size,
unsigned long table_size, acpi_tbl_entry_handler handler,
int entry_id, struct acpi_table_header *table_header,
acpi_tbl_entry_handler handler, int entry_id, unsigned int max_entries)
unsigned int max_entries)
{ {
struct acpi_table_header *table_header = NULL;
struct acpi_subtable_header *entry; struct acpi_subtable_header *entry;
unsigned int count = 0; int count = 0;
unsigned long table_end; unsigned long table_end;
acpi_size tbl_size;
if (acpi_disabled) if (acpi_disabled)
return -ENODEV; return -ENODEV;
if (!handler) if (!id || !handler)
return -EINVAL; return -EINVAL;
if (strncmp(id, ACPI_SIG_MADT, 4) == 0) if (!table_size)
acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size); return -EINVAL;
else
acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
if (!table_header) { if (!table_header) {
pr_warn("%4.4s not present\n", id); pr_warn("%4.4s not present\n", id);
@ -232,7 +226,7 @@ acpi_table_parse_entries(char *id,
if (entry->type == entry_id if (entry->type == entry_id
&& (!max_entries || count++ < max_entries)) && (!max_entries || count++ < max_entries))
if (handler(entry, table_end)) if (handler(entry, table_end))
goto err; return -EINVAL;
/* /*
* If entry->length is 0, break from this loop to avoid * If entry->length is 0, break from this loop to avoid
@ -240,22 +234,53 @@ acpi_table_parse_entries(char *id,
*/ */
if (entry->length == 0) { if (entry->length == 0) {
pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
goto err; return -EINVAL;
} }
entry = (struct acpi_subtable_header *) entry = (struct acpi_subtable_header *)
((unsigned long)entry + entry->length); ((unsigned long)entry + entry->length);
} }
if (max_entries && count > max_entries) { if (max_entries && count > max_entries) {
pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n", pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
id, entry_id, count - max_entries, count); id, entry_id, count - max_entries, count);
} }
return count;
}
int __init
acpi_table_parse_entries(char *id,
unsigned long table_size,
int entry_id,
acpi_tbl_entry_handler handler,
unsigned int max_entries)
{
struct acpi_table_header *table_header = NULL;
acpi_size tbl_size;
int count;
u32 instance = 0;
if (acpi_disabled)
return -ENODEV;
if (!id || !handler)
return -EINVAL;
if (!strncmp(id, ACPI_SIG_MADT, 4))
instance = acpi_apic_instance;
acpi_get_table_with_size(id, instance, &table_header, &tbl_size);
if (!table_header) {
pr_warn("%4.4s not present\n", id);
return -ENODEV;
}
count = acpi_parse_entries(id, table_size, handler, table_header,
entry_id, max_entries);
early_acpi_os_unmap_memory((char *)table_header, tbl_size); early_acpi_os_unmap_memory((char *)table_header, tbl_size);
return count; return count;
err:
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
return -EINVAL;
} }
int __init int __init

View File

@ -123,6 +123,10 @@ int acpi_numa_init (void);
int acpi_table_init (void); int acpi_table_init (void);
int acpi_table_parse(char *id, acpi_tbl_table_handler handler); int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
int __init acpi_parse_entries(char *id, unsigned long table_size,
acpi_tbl_entry_handler handler,
struct acpi_table_header *table_header,
int entry_id, unsigned int max_entries);
int __init acpi_table_parse_entries(char *id, unsigned long table_size, int __init acpi_table_parse_entries(char *id, unsigned long table_size,
int entry_id, int entry_id,
acpi_tbl_entry_handler handler, acpi_tbl_entry_handler handler,