aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Stone <ahs3@redhat.com>2016-08-19 20:48:12 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-08-30 19:35:44 -0400
commit8726d4f441505def8a488d50e50568403f6ad191 (patch)
treeb8e306ba648fd7ed80a7058e4d09e7386036b58e
parentfa162a05de280e7e62f30eac4dc591e8f5052483 (diff)
ACPI / tables: fix acpi_parse_entries_array() so it traverses all subtables
The acpi_parse_entries_array() function currently returns the very first time there is any error found by one of the callback functions, or if one of the callbacks returns a non-zero value. However, the ACPI subtables being traversed could still have valid entries that could be used by one of the callback functions. And, if the comments are correct, that is what should happen -- always traverse all of the subtables, calling as many of the callbacks as possible. This patch makes the function consistent with its description so that it will properly invoke all callbacks for all matching entries, for all subtables, instead of stopping abruptly as it does today. This does change the semantics of using acpi_parse_entries_array(). In examining all users of the function, none of them rely on the current behavior; that is, there appears to be no assumption that either all subtables are traversed and all callbacks invoked, or that the function will return immediately on any error from a callback. Each callback operates independently. Hence, there should be no functional change due to this change in semantics. Future patches being prepared will rely on this new behavior; indeed, they were written assuming the acpi_parse_entries_array() function operated as its comments describe. For example, a callback that counts the number of subtables of a specific type can now be assured that as many subtables as possible have been enumerated. Signed-off-by: Al Stone <ahs3@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/tables.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index bf273c70977a..b7dac30adf0c 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -246,6 +246,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
246 struct acpi_subtable_header *entry; 246 struct acpi_subtable_header *entry;
247 unsigned long table_end; 247 unsigned long table_end;
248 int count = 0; 248 int count = 0;
249 int errs = 0;
249 int i; 250 int i;
250 251
251 if (acpi_disabled) 252 if (acpi_disabled)
@@ -278,8 +279,10 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
278 if (entry->type != proc[i].id) 279 if (entry->type != proc[i].id)
279 continue; 280 continue;
280 if (!proc[i].handler || 281 if (!proc[i].handler ||
281 proc[i].handler(entry, table_end)) 282 (!errs && proc[i].handler(entry, table_end))) {
282 return -EINVAL; 283 errs++;
284 continue;
285 }
283 286
284 proc[i].count++; 287 proc[i].count++;
285 break; 288 break;
@@ -305,7 +308,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
305 id, proc->id, count - max_entries, count); 308 id, proc->id, count - max_entries, count);
306 } 309 }
307 310
308 return count; 311 return errs ? -EINVAL : count;
309} 312}
310 313
311int __init 314int __init