Hi Ashwin,
I like this patch! Please see comments below.
On 19.03.2014 04:51, Ashwin Chaugule wrote:
Introduce a new function that takes a table_header pointer acquired from acpi_table_parse(). This eliminates the need to get the table pointer again by traversing the whole list of tables. e.g. as in acpi_table_parse_madt().
Signed-off-by: Ashwin Chaugule ashwin.chaugule@linaro.org
drivers/acpi/tables.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 4 ++++ 2 files changed, 59 insertions(+)
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index be6a7d7..eaf805b 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -203,6 +203,61 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) } }
+int __init +acpi_parse_entries(unsigned long table_size,
acpi_tbl_entry_handler handler,
struct acpi_table_header *table_header,
int entry_id, unsigned int max_entries)
+{
- struct acpi_subtable_header *entry;
- unsigned int count = 0;
- unsigned long table_end;
- acpi_size tbl_size = table_header->length;
- if (acpi_disabled)
return -ENODEV;
- if (!table_header) {
pr_warn(PREFIX "Table header not present\n");
return -ENODEV;
- }
- table_end = (unsigned long)table_header + table_header->length;
- /* Parse all entries looking for a match. */
- entry = (struct acpi_subtable_header *)
((unsigned long)table_header + table_size);
- while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
table_end) {
if (entry->type == entry_id
&& (!max_entries || count++ < max_entries))
if (handler(entry, table_end))
goto err;
/*
* If entry->length is 0, break from this loop to avoid
* infinite loop.
*/
if (entry->length == 0) {
pr_err(PREFIX "[0x%02x] Invalid zero length\n", entry_id);
goto err;
}
entry = (struct acpi_subtable_header *)
((unsigned long)entry + entry->length);
- }
- if (max_entries && count > max_entries) {
pr_warn(PREFIX "[0x%02x] ignored %i entries of %i found\n",
entry_id, count - max_entries, count);
- }
- early_acpi_os_unmap_memory((char *)table_header, tbl_size);
- return count;
+err:
- early_acpi_os_unmap_memory((char *)table_header, tbl_size);
- return -EINVAL;
+}
Majority logic of acpi_parse_entries() overlaps acpi_table_parse_entries(). I think we can refactor acpi_table_parse_entries() function to take advantage of acpi_parse_entries(). Something like this:
int __init acpi_table_parse_entries(char *id, unsigned long table_size, int entry_id, acpi_tbl_entry_handler handler, unsigned int max_entries) { [...] if (strncmp(id, ACPI_SIG_MADT, 4) == 0) acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size); else acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
[...]
return acpi_parse_entries(table_size, handler, table_header, entry_id, max_entries); }
Tomasz
int __init acpi_table_parse_entries(char *id, diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 372038a..7d5dba2 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -122,6 +122,10 @@ int acpi_numa_init (void);
int acpi_table_init (void); int acpi_table_parse(char *id, acpi_tbl_table_handler handler); +int __init acpi_parse_entries(unsigned long table_size,
acpi_tbl_entry_handler handler,
struct acpi_table_header *table_header,
int __init acpi_table_parse_entries(char *id, unsigned long table_size, int entry_id, acpi_tbl_entry_handler handler,int entry_id, unsigned int max_entries);