Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 151011
b: refs/heads/master
c: 3c59f96
h: refs/heads/master
i:
  151009: 102897c
  151007: 5ac889a
v: v3
  • Loading branch information
Bob Moore authored and Len Brown committed May 27, 2009
1 parent be924a5 commit e73ea7f
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b2f7ddcfcb9c2436896cb339a7ff70245648f033
refs/heads/master: 3c59f96081259358d9d5d677f4839c36391806b6
96 changes: 78 additions & 18 deletions trunk/drivers/acpi/acpica/exconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "acnamesp.h"
#include "actables.h"
#include "acdispat.h"
#include "acevents.h"

#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("exconfig")
Expand All @@ -57,6 +58,10 @@ acpi_ex_add_table(u32 table_index,
struct acpi_namespace_node *parent_node,
union acpi_operand_object **ddb_handle);

static acpi_status
acpi_ex_region_read(union acpi_operand_object *obj_desc,
u32 length, u8 *buffer);

/*******************************************************************************
*
* FUNCTION: acpi_ex_add_table
Expand Down Expand Up @@ -255,6 +260,48 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status);
}

/*******************************************************************************
*
* FUNCTION: acpi_ex_region_read
*
* PARAMETERS: obj_desc - Region descriptor
* Length - Number of bytes to read
* Buffer - Pointer to where to put the data
*
* RETURN: Status
*
* DESCRIPTION: Read data from an operation region. The read starts from the
* beginning of the region.
*
******************************************************************************/

static acpi_status
acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer)
{
acpi_status status;
acpi_integer value;
acpi_physical_address address;
u32 i;

address = obj_desc->region.address;

/* Bytewise reads */

for (i = 0; i < length; i++) {
status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
address, 8, &value);
if (ACPI_FAILURE(status)) {
return status;
}

*buffer = (u8)value;
buffer++;
address++;
}

return AE_OK;
}

/*******************************************************************************
*
* FUNCTION: acpi_ex_load_op
Expand Down Expand Up @@ -317,18 +364,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
}
}

/*
* Map the table header and get the actual table length. The region
* length is not guaranteed to be the same as the table length.
*/
table = acpi_os_map_memory(obj_desc->region.address,
sizeof(struct acpi_table_header));
/* Get the table header first so we can get the table length */

table = ACPI_ALLOCATE(sizeof(struct acpi_table_header));
if (!table) {
return_ACPI_STATUS(AE_NO_MEMORY);
}

status =
acpi_ex_region_read(obj_desc,
sizeof(struct acpi_table_header),
ACPI_CAST_PTR(u8, table));
length = table->length;
acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
ACPI_FREE(table);

if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}

/* Must have at least an ACPI table header */

Expand All @@ -337,10 +389,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
}

/*
* The memory region is not guaranteed to remain stable and we must
* copy the table to a local buffer. For example, the memory region
* is corrupted after suspend on some machines. Dynamically loaded
* tables are usually small, so this overhead is minimal.
* The original implementation simply mapped the table, with no copy.
* However, the memory region is not guaranteed to remain stable and
* we must copy the table to a local buffer. For example, the memory
* region is corrupted after suspend on some machines. Dynamically
* loaded tables are usually small, so this overhead is minimal.
*
* The latest implementation (5/2009) does not use a mapping at all.
* We use the low-level operation region interface to read the table
* instead of the obvious optimization of using a direct mapping.
* This maintains a consistent use of operation regions across the
* entire subsystem. This is important if additional processing must
* be performed in the (possibly user-installed) operation region
* handler. For example, acpi_exec and ASLTS depend on this.
*/

/* Allocate a buffer for the table */
Expand All @@ -350,17 +411,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
return_ACPI_STATUS(AE_NO_MEMORY);
}

/* Map the entire table and copy it */
/* Read the entire table */

table = acpi_os_map_memory(obj_desc->region.address, length);
if (!table) {
status = acpi_ex_region_read(obj_desc, length,
ACPI_CAST_PTR(u8,
table_desc.pointer));
if (ACPI_FAILURE(status)) {
ACPI_FREE(table_desc.pointer);
return_ACPI_STATUS(AE_NO_MEMORY);
return_ACPI_STATUS(status);
}

ACPI_MEMCPY(table_desc.pointer, table, length);
acpi_os_unmap_memory(table, length);

table_desc.address = obj_desc->region.address;
break;

Expand Down

0 comments on commit e73ea7f

Please sign in to comment.