From 86894d4876d3f9608c74a0e4424190cf9209f325 Mon Sep 17 00:00:00 2001 From: "Xiao, Hui" Date: Thu, 8 Dec 2011 11:25:48 +0800 Subject: [PATCH] --- yaml --- r: 286483 b: refs/heads/master c: b4e008dc53a31cb4bf6a12d9dbaf1d5c6070a838 h: refs/heads/master i: 286481: 7d0e24b5d7dab197dd2f6be584a7b914b7d249a5 286479: cdd25e5bd9e3502d54c7236b974e5630330830ac v: v3 --- [refs] | 2 +- trunk/drivers/acpi/apei/einj.c | 38 ++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index fe8a03dc45a9..8eeab6f58ba6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fdea163d8c17ba08814142259a467ba3e899010d +refs/heads/master: b4e008dc53a31cb4bf6a12d9dbaf1d5c6070a838 diff --git a/trunk/drivers/acpi/apei/einj.c b/trunk/drivers/acpi/apei/einj.c index 4fdc8a3b4f6c..6e6512e68a2d 100644 --- a/trunk/drivers/acpi/apei/einj.c +++ b/trunk/drivers/acpi/apei/einj.c @@ -194,6 +194,26 @@ static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab) return 0; } +static struct acpi_generic_address *einj_get_trigger_parameter_region( + struct acpi_einj_trigger *trigger_tab, u64 param1, u64 param2) +{ + int i; + struct acpi_whea_header *entry; + + entry = (struct acpi_whea_header *) + ((char *)trigger_tab + sizeof(struct acpi_einj_trigger)); + for (i = 0; i < trigger_tab->entry_count; i++) { + if (entry->action == ACPI_EINJ_TRIGGER_ERROR && + entry->instruction == ACPI_EINJ_WRITE_REGISTER_VALUE && + entry->register_region.space_id == + ACPI_ADR_SPACE_SYSTEM_MEMORY && + (entry->register_region.address & param2) == (param1 & param2)) + return &entry->register_region; + entry++; + } + + return NULL; +} /* Execute instructions in trigger error action table */ static int __einj_error_trigger(u64 trigger_paddr, u32 type, u64 param1, u64 param2) @@ -205,6 +225,7 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type, struct resource *r; u32 table_size; int rc = -EIO; + struct acpi_generic_address *trigger_param_region = NULL; r = request_mem_region(trigger_paddr, sizeof(*trigger_tab), "APEI EINJ Trigger Table"); @@ -266,12 +287,17 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type, if (param_extension && (type & 0x0038) && param2) { struct apei_resources addr_resources; apei_resources_init(&addr_resources); - rc = apei_resources_add(&addr_resources, - param1 & param2, - ~param2 + 1, true); - if (rc) - goto out_fini; - rc = apei_resources_sub(&trigger_resources, &addr_resources); + trigger_param_region = einj_get_trigger_parameter_region( + trigger_tab, param1, param2); + if (trigger_param_region) { + rc = apei_resources_add(&addr_resources, + trigger_param_region->address, + trigger_param_region->bit_width/8, true); + if (rc) + goto out_fini; + rc = apei_resources_sub(&trigger_resources, + &addr_resources); + } apei_resources_fini(&addr_resources); if (rc) goto out_fini;