summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpica/psloop.c51
-rw-r--r--drivers/acpi/acpica/psobject.c30
-rw-r--r--drivers/acpi/acpica/uterror.c10
3 files changed, 85 insertions, 6 deletions
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
index 68422afc365f..bc5f05906bd1 100644
--- a/drivers/acpi/acpica/psloop.c
+++ b/drivers/acpi/acpica/psloop.c
@@ -515,6 +515,22 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
+ if (walk_state->opcode == AML_SCOPE_OP) {
+ /*
+ * If the scope op fails to parse, skip the body of the
+ * scope op because the parse failure indicates that the
+ * device may not exist.
+ */
+ walk_state->parser_state.aml =
+ walk_state->aml + 1;
+ walk_state->parser_state.aml =
+ acpi_ps_get_next_package_end
+ (&walk_state->parser_state);
+ walk_state->aml =
+ walk_state->parser_state.aml;
+ ACPI_ERROR((AE_INFO,
+ "Skipping Scope block"));
+ }
continue;
}
@@ -557,7 +573,40 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
-
+ if ((walk_state->control_state) &&
+ ((walk_state->control_state->control.
+ opcode == AML_IF_OP)
+ || (walk_state->control_state->control.
+ opcode == AML_WHILE_OP))) {
+ /*
+ * If the if/while op fails to parse, we will skip parsing
+ * the body of the op.
+ */
+ parser_state->aml =
+ walk_state->control_state->control.
+ aml_predicate_start + 1;
+ parser_state->aml =
+ acpi_ps_get_next_package_end
+ (parser_state);
+ walk_state->aml = parser_state->aml;
+
+ ACPI_ERROR((AE_INFO,
+ "Skipping While/If block"));
+ if (*walk_state->aml == AML_ELSE_OP) {
+ ACPI_ERROR((AE_INFO,
+ "Skipping Else block"));
+ walk_state->parser_state.aml =
+ walk_state->aml + 1;
+ walk_state->parser_state.aml =
+ acpi_ps_get_next_package_end
+ (parser_state);
+ walk_state->aml =
+ parser_state->aml;
+ }
+ ACPI_FREE(acpi_ut_pop_generic_state
+ (&walk_state->control_state));
+ }
+ op = NULL;
continue;
}
}
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
index 7d9d0151ee54..3138e7a00da8 100644
--- a/drivers/acpi/acpica/psobject.c
+++ b/drivers/acpi/acpica/psobject.c
@@ -12,6 +12,7 @@
#include "acparser.h"
#include "amlcode.h"
#include "acconvert.h"
+#include "acnamesp.h"
#define _COMPONENT ACPI_PARSER
ACPI_MODULE_NAME("psobject")
@@ -549,6 +550,21 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
do {
if (*op) {
+ /*
+ * These Opcodes need to be removed from the namespace because they
+ * get created even if these opcodes cannot be created due to
+ * errors.
+ */
+ if (((*op)->common.aml_opcode == AML_REGION_OP)
+ || ((*op)->common.aml_opcode ==
+ AML_DATA_REGION_OP)) {
+ acpi_ns_delete_children((*op)->common.
+ node);
+ acpi_ns_remove_node((*op)->common.node);
+ (*op)->common.node = NULL;
+ acpi_ps_delete_parse_tree(*op);
+ }
+
status2 =
acpi_ps_complete_this_op(walk_state, *op);
if (ACPI_FAILURE(status2)) {
@@ -574,6 +590,20 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
#endif
walk_state->prev_op = NULL;
walk_state->prev_arg_types = walk_state->arg_types;
+
+ if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
+ /*
+ * There was something that went wrong while executing code at the
+ * module-level. We need to skip parsing whatever caused the
+ * error and keep going. One runtime error during the table load
+ * should not cause the entire table to not be loaded. This is
+ * because there could be correct AML beyond the parts that caused
+ * the runtime error.
+ */
+ ACPI_ERROR((AE_INFO,
+ "Ignore error and continue table load"));
+ return_ACPI_STATUS(AE_OK);
+ }
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/uterror.c b/drivers/acpi/acpica/uterror.c
index 12d4a0f6b8d2..5a64ddaed8a3 100644
--- a/drivers/acpi/acpica/uterror.c
+++ b/drivers/acpi/acpica/uterror.c
@@ -182,20 +182,20 @@ acpi_ut_prefixed_namespace_error(const char *module_name,
switch (lookup_status) {
case AE_ALREADY_EXISTS:
- acpi_os_printf(ACPI_MSG_BIOS_ERROR);
+ acpi_os_printf("\n" ACPI_MSG_BIOS_ERROR);
message = "Failure creating";
break;
case AE_NOT_FOUND:
- acpi_os_printf(ACPI_MSG_BIOS_ERROR);
- message = "Failure looking up";
+ acpi_os_printf("\n" ACPI_MSG_BIOS_ERROR);
+ message = "Could not resolve";
break;
default:
- acpi_os_printf(ACPI_MSG_ERROR);
- message = "Failure looking up";
+ acpi_os_printf("\n" ACPI_MSG_ERROR);
+ message = "Failure resolving";
break;
}