Commit 7e06bff2 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] ACPICA 20040715 from Bob Moore

Restructured the internal HW GPE interfaces to pass/track
the current state of interrupts (enabled/disabled) in
order to avoid possible deadlock and increase flexibility
of the interfaces.

Implemented a "lexicographical compare" for String and
Buffer objects within the logical operators -- LGreater,
LLess, LGreaterEqual, and LLessEqual -- as per further
clarification to the ACPI specification.  Behavior is
similar to C library "strcmp".

Completed a major reduction in CPU stack use for the
acpi_get_firmware_table external function.  In the 32-bit
non-debug case, the stack use has been reduced from 168
bytes to 32 bytes.

Deployed a new run-time configuration flag,
acpi_gbl_enable_interpeter_slack, whose purpose is to allow
the AML interpreter to forgive certain bad AML constructs.
Default setting is FALSE.

Implemented the first use of acpi_gbl_enable_interpeter_slack
in the Field IO support code.  If enabled, it allows field
access to go beyond the end of a region definition if the
field is within the region length rounded up to the next
access width boundary (a common coding error.)

Renamed OSD_HANDLER to acpi_osd_handler, and
OSD_EXECUTION_CALLBACK to acpi_osd_exec_callback for
consistency with other ACPI symbols.  Also, these symbols
are lowercased by the latest version of the acpisrc tool.

The prototypes for the PCI interfaces in acpiosxf.h
have been updated to rename "register" to simply "reg"
to prevent certain compilers from complaining.
parent 63dbb867
...@@ -105,17 +105,18 @@ acpi_ev_valid_gpe_event ( ...@@ -105,17 +105,18 @@ acpi_ev_valid_gpe_event (
* FUNCTION: acpi_ev_walk_gpe_list * FUNCTION: acpi_ev_walk_gpe_list
* *
* PARAMETERS: gpe_walk_callback - Routine called for each GPE block * PARAMETERS: gpe_walk_callback - Routine called for each GPE block
* Flags - ACPI_NOT_ISR or ACPI_ISR
* *
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Walk the GPE lists. * DESCRIPTION: Walk the GPE lists.
* FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ev_walk_gpe_list ( acpi_ev_walk_gpe_list (
ACPI_GPE_CALLBACK gpe_walk_callback) ACPI_GPE_CALLBACK gpe_walk_callback,
u32 flags)
{ {
struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_block_info *gpe_block;
struct acpi_gpe_xrupt_info *gpe_xrupt_info; struct acpi_gpe_xrupt_info *gpe_xrupt_info;
...@@ -125,7 +126,7 @@ acpi_ev_walk_gpe_list ( ...@@ -125,7 +126,7 @@ acpi_ev_walk_gpe_list (
ACPI_FUNCTION_TRACE ("ev_walk_gpe_list"); ACPI_FUNCTION_TRACE ("ev_walk_gpe_list");
acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR); acpi_os_acquire_lock (acpi_gbl_gpe_lock, flags);
/* Walk the interrupt level descriptor list */ /* Walk the interrupt level descriptor list */
...@@ -149,7 +150,7 @@ acpi_ev_walk_gpe_list ( ...@@ -149,7 +150,7 @@ acpi_ev_walk_gpe_list (
} }
unlock_and_exit: unlock_and_exit:
acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR); acpi_os_release_lock (acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
......
...@@ -547,7 +547,7 @@ acpi_ev_terminate (void) ...@@ -547,7 +547,7 @@ acpi_ev_terminate (void)
/* Disable all GPEs in all GPE blocks */ /* Disable all GPEs in all GPE blocks */
status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block); status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, ACPI_NOT_ISR);
/* Remove SCI handler */ /* Remove SCI handler */
...@@ -559,7 +559,7 @@ acpi_ev_terminate (void) ...@@ -559,7 +559,7 @@ acpi_ev_terminate (void)
/* Deallocate all handler objects installed within GPE info structs */ /* Deallocate all handler objects installed within GPE info structs */
status = acpi_ev_walk_gpe_list (acpi_ev_delete_gpe_handlers); status = acpi_ev_walk_gpe_list (acpi_ev_delete_gpe_handlers, ACPI_NOT_ISR);
/* Return to original mode if necessary */ /* Return to original mode if necessary */
......
...@@ -130,6 +130,21 @@ acpi_ex_setup_region ( ...@@ -130,6 +130,21 @@ acpi_ex_setup_region (
if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset
+ field_datum_byte_offset + field_datum_byte_offset
+ obj_desc->common_field.access_byte_width)) { + obj_desc->common_field.access_byte_width)) {
if (acpi_gbl_enable_interpeter_slack) {
/*
* Slack mode only: We will go ahead and allow access to this
* field if it is within the region length rounded up to the next
* access width boundary.
*/
if (ACPI_ROUND_UP (rgn_desc->region.length,
obj_desc->common_field.access_byte_width) >=
(obj_desc->common_field.base_byte_offset +
obj_desc->common_field.access_byte_width +
field_datum_byte_offset)) {
return_ACPI_STATUS (AE_OK);
}
}
if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) { if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) {
/* /*
* This is the case where the access_type (acc_word, etc.) is wider * This is the case where the access_type (acc_word, etc.) is wider
......
...@@ -565,42 +565,42 @@ acpi_ex_do_logical_op ( ...@@ -565,42 +565,42 @@ acpi_ex_do_logical_op (
case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
/* Check lengths first */ /* Lexicographic compare: Scan the 1-to-1 data */
for (i = 0; (i < length0) && (i < length1); i++) {
if (ptr0[i] > ptr1[i]) {
return (TRUE);
}
}
/* Bytes match, now check lengths */
if (length0 > length1) { if (length0 > length1) {
return (TRUE); return (TRUE);
} }
else if (length0 < length1) {
return (FALSE);
}
/* Lengths equal, now scan the data */ /* Length0 <= Length1 */
for (i = 0; i < length0; i++) {
if (ptr0[i] > ptr1[i]) {
return (TRUE);
}
}
return (FALSE); return (FALSE);
case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
/* Check lengths first */ /* Lexicographic compare: Scan the 1-to-1 data */
for (i = 0; (i < length0) && (i < length1); i++) {
if (ptr0[i] < ptr1[i]) {
return (TRUE);
}
}
/* Bytes match, now check lengths */
if (length0 < length1) { if (length0 < length1) {
return (TRUE); return (TRUE);
} }
else if (length0 > length1) {
return (FALSE);
}
/* Lengths equal, now scan the data */ /* Length0 >= Length1 */
for (i = 0; i < length0; i++) {
if (ptr0[i] < ptr1[i]) {
return (TRUE);
}
}
return (FALSE); return (FALSE);
default: default:
......
...@@ -364,7 +364,7 @@ acpi_hw_enable_wakeup_gpe_block ( ...@@ -364,7 +364,7 @@ acpi_hw_enable_wakeup_gpe_block (
* *
* FUNCTION: acpi_hw_disable_all_gpes * FUNCTION: acpi_hw_disable_all_gpes
* *
* PARAMETERS: None * PARAMETERS: Flags - ACPI_NOT_ISR or ACPI_ISR
* *
* RETURN: Status * RETURN: Status
* *
...@@ -374,7 +374,7 @@ acpi_hw_enable_wakeup_gpe_block ( ...@@ -374,7 +374,7 @@ acpi_hw_enable_wakeup_gpe_block (
acpi_status acpi_status
acpi_hw_disable_all_gpes ( acpi_hw_disable_all_gpes (
void) u32 flags)
{ {
acpi_status status; acpi_status status;
...@@ -382,8 +382,8 @@ acpi_hw_disable_all_gpes ( ...@@ -382,8 +382,8 @@ acpi_hw_disable_all_gpes (
ACPI_FUNCTION_TRACE ("hw_disable_all_gpes"); ACPI_FUNCTION_TRACE ("hw_disable_all_gpes");
status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block); status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, flags);
status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block); status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block, flags);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -392,7 +392,7 @@ acpi_hw_disable_all_gpes ( ...@@ -392,7 +392,7 @@ acpi_hw_disable_all_gpes (
* *
* FUNCTION: acpi_hw_enable_all_runtime_gpes * FUNCTION: acpi_hw_enable_all_runtime_gpes
* *
* PARAMETERS: None * PARAMETERS: Flags - ACPI_NOT_ISR or ACPI_ISR
* *
* RETURN: Status * RETURN: Status
* *
...@@ -402,7 +402,7 @@ acpi_hw_disable_all_gpes ( ...@@ -402,7 +402,7 @@ acpi_hw_disable_all_gpes (
acpi_status acpi_status
acpi_hw_enable_all_runtime_gpes ( acpi_hw_enable_all_runtime_gpes (
void) u32 flags)
{ {
acpi_status status; acpi_status status;
...@@ -410,7 +410,7 @@ acpi_hw_enable_all_runtime_gpes ( ...@@ -410,7 +410,7 @@ acpi_hw_enable_all_runtime_gpes (
ACPI_FUNCTION_TRACE ("hw_enable_all_runtime_gpes"); ACPI_FUNCTION_TRACE ("hw_enable_all_runtime_gpes");
status = acpi_ev_walk_gpe_list (acpi_hw_enable_runtime_gpe_block); status = acpi_ev_walk_gpe_list (acpi_hw_enable_runtime_gpe_block, flags);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -419,7 +419,7 @@ acpi_hw_enable_all_runtime_gpes ( ...@@ -419,7 +419,7 @@ acpi_hw_enable_all_runtime_gpes (
* *
* FUNCTION: acpi_hw_enable_all_wakeup_gpes * FUNCTION: acpi_hw_enable_all_wakeup_gpes
* *
* PARAMETERS: None * PARAMETERS: Flags - ACPI_NOT_ISR or ACPI_ISR
* *
* RETURN: Status * RETURN: Status
* *
...@@ -429,7 +429,7 @@ acpi_hw_enable_all_runtime_gpes ( ...@@ -429,7 +429,7 @@ acpi_hw_enable_all_runtime_gpes (
acpi_status acpi_status
acpi_hw_enable_all_wakeup_gpes ( acpi_hw_enable_all_wakeup_gpes (
void) u32 flags)
{ {
acpi_status status; acpi_status status;
...@@ -437,7 +437,7 @@ acpi_hw_enable_all_wakeup_gpes ( ...@@ -437,7 +437,7 @@ acpi_hw_enable_all_wakeup_gpes (
ACPI_FUNCTION_TRACE ("hw_enable_all_wakeup_gpes"); ACPI_FUNCTION_TRACE ("hw_enable_all_wakeup_gpes");
status = acpi_ev_walk_gpe_list (acpi_hw_enable_wakeup_gpe_block); status = acpi_ev_walk_gpe_list (acpi_hw_enable_wakeup_gpe_block, flags);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
* RETURN: none * RETURN: none
* *
* DESCRIPTION: Clears all fixed and general purpose status bits * DESCRIPTION: Clears all fixed and general purpose status bits
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
* *
******************************************************************************/ ******************************************************************************/
...@@ -103,7 +104,7 @@ acpi_hw_clear_acpi_status ( ...@@ -103,7 +104,7 @@ acpi_hw_clear_acpi_status (
/* Clear the GPE Bits in all GPE registers in all GPE blocks */ /* Clear the GPE Bits in all GPE registers in all GPE blocks */
status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block); status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block, ACPI_ISR);
unlock_and_exit: unlock_and_exit:
if (flags & ACPI_MTX_LOCK) { if (flags & ACPI_MTX_LOCK) {
......
...@@ -292,13 +292,13 @@ acpi_enter_sleep_state ( ...@@ -292,13 +292,13 @@ acpi_enter_sleep_state (
* 1) Disable/Clear all GPEs * 1) Disable/Clear all GPEs
* 2) Enable all wakeup GPEs * 2) Enable all wakeup GPEs
*/ */
status = acpi_hw_disable_all_gpes (); status = acpi_hw_disable_all_gpes (ACPI_ISR);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
acpi_gbl_system_awake_and_running = FALSE; acpi_gbl_system_awake_and_running = FALSE;
status = acpi_hw_enable_all_wakeup_gpes (); status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -431,13 +431,13 @@ acpi_enter_sleep_state_s4bios ( ...@@ -431,13 +431,13 @@ acpi_enter_sleep_state_s4bios (
* 1) Disable/Clear all GPEs * 1) Disable/Clear all GPEs
* 2) Enable all wakeup GPEs * 2) Enable all wakeup GPEs
*/ */
status = acpi_hw_disable_all_gpes (); status = acpi_hw_disable_all_gpes (ACPI_ISR);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
acpi_gbl_system_awake_and_running = FALSE; acpi_gbl_system_awake_and_running = FALSE;
status = acpi_hw_enable_all_wakeup_gpes (); status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -467,6 +467,7 @@ acpi_enter_sleep_state_s4bios ( ...@@ -467,6 +467,7 @@ acpi_enter_sleep_state_s4bios (
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
* Called with interrupts ENABLED.
* *
******************************************************************************/ ******************************************************************************/
...@@ -557,13 +558,13 @@ acpi_leave_sleep_state ( ...@@ -557,13 +558,13 @@ acpi_leave_sleep_state (
* 1) Disable/Clear all GPEs * 1) Disable/Clear all GPEs
* 2) Enable all runtime GPEs * 2) Enable all runtime GPEs
*/ */
status = acpi_hw_disable_all_gpes (); status = acpi_hw_disable_all_gpes (ACPI_NOT_ISR);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
acpi_gbl_system_awake_and_running = TRUE; acpi_gbl_system_awake_and_running = TRUE;
status = acpi_hw_enable_all_runtime_gpes (); status = acpi_hw_enable_all_runtime_gpes (ACPI_NOT_ISR);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
......
...@@ -51,7 +51,7 @@ ACPI_MODULE_NAME ("osl") ...@@ -51,7 +51,7 @@ ACPI_MODULE_NAME ("osl")
struct acpi_os_dpc struct acpi_os_dpc
{ {
OSD_EXECUTION_CALLBACK function; acpi_osd_exec_callback function;
void *context; void *context;
}; };
...@@ -64,7 +64,7 @@ extern char line_buf[80]; ...@@ -64,7 +64,7 @@ extern char line_buf[80];
#endif /*ENABLE_DEBUGGER*/ #endif /*ENABLE_DEBUGGER*/
static unsigned int acpi_irq_irq; static unsigned int acpi_irq_irq;
static OSD_HANDLER acpi_irq_handler; static acpi_osd_handler acpi_irq_handler;
static void *acpi_irq_context; static void *acpi_irq_context;
static struct workqueue_struct *kacpid_wq; static struct workqueue_struct *kacpid_wq;
...@@ -246,7 +246,7 @@ acpi_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -246,7 +246,7 @@ acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
} }
acpi_status acpi_status
acpi_os_install_interrupt_handler(u32 gsi, OSD_HANDLER handler, void *context) acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, void *context)
{ {
unsigned int irq; unsigned int irq;
...@@ -274,7 +274,7 @@ acpi_os_install_interrupt_handler(u32 gsi, OSD_HANDLER handler, void *context) ...@@ -274,7 +274,7 @@ acpi_os_install_interrupt_handler(u32 gsi, OSD_HANDLER handler, void *context)
} }
acpi_status acpi_status
acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
{ {
if (irq) { if (irq) {
free_irq(irq, acpi_irq); free_irq(irq, acpi_irq);
...@@ -624,7 +624,7 @@ acpi_os_execute_deferred ( ...@@ -624,7 +624,7 @@ acpi_os_execute_deferred (
acpi_status acpi_status
acpi_os_queue_for_execution( acpi_os_queue_for_execution(
u32 priority, u32 priority,
OSD_EXECUTION_CALLBACK function, acpi_osd_exec_callback function,
void *context) void *context)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
......
...@@ -115,17 +115,14 @@ acpi_tb_find_table ( ...@@ -115,17 +115,14 @@ acpi_tb_find_table (
* Instance - the non zero instance of the table, allows * Instance - the non zero instance of the table, allows
* support for multiple tables of the same type * support for multiple tables of the same type
* Flags - Physical/Virtual support * Flags - Physical/Virtual support
* ret_buffer - pointer to a structure containing a buffer to * table_pointer - Where a buffer containing the table is
* receive the table * returned
* *
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: This function is called to get an ACPI table. The caller * DESCRIPTION: This function is called to get an ACPI table. A buffer is
* supplies an out_buffer large enough to contain the entire ACPI * allocated for the table and returned in table_pointer.
* table. Upon completion * This table will be a complete table including the header.
* the out_buffer->Length field will indicate the number of bytes
* copied into the out_buffer->buf_ptr buffer. This table will be
* a complete table including the header.
* *
******************************************************************************/ ******************************************************************************/
...@@ -136,12 +133,11 @@ acpi_get_firmware_table ( ...@@ -136,12 +133,11 @@ acpi_get_firmware_table (
u32 flags, u32 flags,
struct acpi_table_header **table_pointer) struct acpi_table_header **table_pointer)
{ {
struct acpi_pointer rsdp_address;
struct acpi_pointer address;
acpi_status status; acpi_status status;
struct acpi_table_header header; struct acpi_pointer address;
struct acpi_table_desc table_info; struct acpi_table_header *header = NULL;
struct acpi_table_desc rsdt_info; struct acpi_table_desc *table_info = NULL;
struct acpi_table_desc *rsdt_info;
u32 table_count; u32 table_count;
u32 i; u32 i;
u32 j; u32 j;
...@@ -152,45 +148,41 @@ acpi_get_firmware_table ( ...@@ -152,45 +148,41 @@ acpi_get_firmware_table (
/* /*
* Ensure that at least the table manager is initialized. We don't * Ensure that at least the table manager is initialized. We don't
* require that the entire ACPI subsystem is up for this interface * require that the entire ACPI subsystem is up for this interface.
* If we have a buffer, we must have a length too
*/ */
if ((instance == 0) ||
/* (!signature) ||
* If we have a buffer, we must have a length too
*/
if ((instance == 0) ||
(!signature) ||
(!table_pointer)) { (!table_pointer)) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
rsdt_info.pointer = NULL; /* Ensure that we have a RSDP */
if (!acpi_gbl_RSDP) { if (!acpi_gbl_RSDP) {
/* Get the RSDP */ /* Get the RSDP */
status = acpi_os_get_root_pointer (flags, &rsdp_address); status = acpi_os_get_root_pointer (flags, &address);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n")); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n"));
return_ACPI_STATUS (AE_NO_ACPI_TABLES); return_ACPI_STATUS (AE_NO_ACPI_TABLES);
} }
/* Map and validate the RSDP */ /* Map and validate the RSDP */
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
status = acpi_os_map_memory (rsdp_address.pointer.physical, sizeof (struct rsdp_descriptor), status = acpi_os_map_memory (address.pointer.physical, sizeof (struct rsdp_descriptor),
(void *) &acpi_gbl_RSDP); (void *) &acpi_gbl_RSDP);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
} }
else { else {
acpi_gbl_RSDP = rsdp_address.pointer.logical; acpi_gbl_RSDP = address.pointer.logical;
} }
/* /* The signature and checksum must both be correct */
* The signature and checksum must both be correct
*/
if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
/* Nope, BAD Signature */ /* Nope, BAD Signature */
...@@ -204,10 +196,9 @@ acpi_get_firmware_table ( ...@@ -204,10 +196,9 @@ acpi_get_firmware_table (
} }
} }
/* Get the RSDT and validate it */ /* Get the RSDT address via the RSDP */
acpi_tb_get_rsdt_address (&address); acpi_tb_get_rsdt_address (&address);
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"RSDP located at %p, RSDT physical=%8.8X%8.8X \n", "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
acpi_gbl_RSDP, acpi_gbl_RSDP,
...@@ -217,20 +208,40 @@ acpi_get_firmware_table ( ...@@ -217,20 +208,40 @@ acpi_get_firmware_table (
address.pointer_type |= flags; address.pointer_type |= flags;
status = acpi_tb_get_table (&address, &rsdt_info); /* Get and validate the RSDT */
rsdt_info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
if (!rsdt_info) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
status = acpi_tb_get_table (&address, rsdt_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); goto cleanup;
} }
status = acpi_tb_validate_rsdt (rsdt_info.pointer); status = acpi_tb_validate_rsdt (rsdt_info->pointer);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
goto cleanup; goto cleanup;
} }
/* Get the number of table pointers within the RSDT */ /* Allocate a scratch table header and table descriptor */
table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info.pointer); header = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_header));
if (!header) {
status = AE_NO_MEMORY;
goto cleanup;
}
table_info = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_desc));
if (!table_info) {
status = AE_NO_MEMORY;
goto cleanup;
}
/* Get the number of table pointers within the RSDT */
table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info->pointer);
address.pointer_type = acpi_gbl_table_flags | flags; address.pointer_type = acpi_gbl_table_flags | flags;
/* /*
...@@ -241,35 +252,36 @@ acpi_get_firmware_table ( ...@@ -241,35 +252,36 @@ acpi_get_firmware_table (
/* Get the next table pointer, handle RSDT vs. XSDT */ /* Get the next table pointer, handle RSDT vs. XSDT */
if (acpi_gbl_RSDP->revision < 2) { if (acpi_gbl_RSDP->revision < 2) {
address.pointer.value = (ACPI_CAST_PTR (RSDT_DESCRIPTOR, rsdt_info.pointer))->table_offset_entry[i]; address.pointer.value = (ACPI_CAST_PTR (
RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
} }
else { else {
address.pointer.value = address.pointer.value = (ACPI_CAST_PTR (
(ACPI_CAST_PTR (XSDT_DESCRIPTOR, rsdt_info.pointer))->table_offset_entry[i]; XSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
} }
/* Get the table header */ /* Get the table header */
status = acpi_tb_get_table_header (&address, &header); status = acpi_tb_get_table_header (&address, header);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
goto cleanup; goto cleanup;
} }
/* Compare table signatures and table instance */ /* Compare table signatures and table instance */
if (!ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) { if (!ACPI_STRNCMP (header->signature, signature, ACPI_NAME_SIZE)) {
/* An instance of the table was found */ /* An instance of the table was found */
j++; j++;
if (j >= instance) { if (j >= instance) {
/* Found the correct instance, get the entire table */ /* Found the correct instance, get the entire table */
status = acpi_tb_get_table_body (&address, &header, &table_info); status = acpi_tb_get_table_body (&address, header, table_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
goto cleanup; goto cleanup;
} }
*table_pointer = table_info.pointer; *table_pointer = table_info->pointer;
goto cleanup; goto cleanup;
} }
} }
...@@ -281,7 +293,15 @@ acpi_get_firmware_table ( ...@@ -281,7 +293,15 @@ acpi_get_firmware_table (
cleanup: cleanup:
acpi_os_unmap_memory (rsdt_info.pointer, (acpi_size) rsdt_info.pointer->length); acpi_os_unmap_memory (rsdt_info->pointer, (acpi_size) rsdt_info->pointer->length);
ACPI_MEM_FREE (rsdt_info);
if (header) {
ACPI_MEM_FREE (header);
}
if (table_info) {
ACPI_MEM_FREE (table_info);
}
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/* Version string */ /* Version string */
#define ACPI_CA_VERSION 0x20040615 #define ACPI_CA_VERSION 0x20040715
/* /*
* OS name, used for the _OS object. The _OS object is essentially obsolete, * OS name, used for the _OS object. The _OS object is essentially obsolete,
......
...@@ -111,7 +111,8 @@ acpi_ev_notify_dispatch ( ...@@ -111,7 +111,8 @@ acpi_ev_notify_dispatch (
acpi_status acpi_status
acpi_ev_walk_gpe_list ( acpi_ev_walk_gpe_list (
ACPI_GPE_CALLBACK gpe_walk_callback); ACPI_GPE_CALLBACK gpe_walk_callback,
u32 flags);
u8 u8
acpi_ev_valid_gpe_event ( acpi_ev_valid_gpe_event (
......
...@@ -90,11 +90,11 @@ extern u32 acpi_gbl_nesting_level; ...@@ -90,11 +90,11 @@ extern u32 acpi_gbl_nesting_level;
****************************************************************************/ ****************************************************************************/
/* /*
* Create the predefined _OSI method in the namespace? Default is TRUE * Enable "slack" in the AML interpreter? Default is FALSE, and the
* because ACPI CA is fully compatible with other ACPI implementations. * interpreter strictly follows the ACPI specification. Setting to TRUE
* Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. * allows the interpreter to forgive certain bad AML constructs.
*/ */
ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_create_osi_method, TRUE); ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_enable_interpeter_slack, FALSE);
/* /*
* Automatically serialize ALL control methods? Default is FALSE, meaning * Automatically serialize ALL control methods? Default is FALSE, meaning
...@@ -104,6 +104,13 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_create_osi_method, TRUE); ...@@ -104,6 +104,13 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_create_osi_method, TRUE);
*/ */
ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_all_methods_serialized, FALSE); ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_all_methods_serialized, FALSE);
/*
* Create the predefined _OSI method in the namespace? Default is TRUE
* because ACPI CA is fully compatible with other ACPI implementations.
* Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior.
*/
ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_create_osi_method, TRUE);
/* /*
* Disable wakeup GPEs during runtime? Default is TRUE because WAKE and * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and
* RUNTIME GPEs should never be shared, and WAKE GPEs should typically only * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only
......
...@@ -138,15 +138,15 @@ acpi_hw_get_gpe_status ( ...@@ -138,15 +138,15 @@ acpi_hw_get_gpe_status (
acpi_status acpi_status
acpi_hw_disable_all_gpes ( acpi_hw_disable_all_gpes (
void); u32 flags);
acpi_status acpi_status
acpi_hw_enable_all_runtime_gpes ( acpi_hw_enable_all_runtime_gpes (
void); u32 flags);
acpi_status acpi_status
acpi_hw_enable_all_wakeup_gpes ( acpi_hw_enable_all_wakeup_gpes (
void); u32 flags);
acpi_status acpi_status
acpi_hw_enable_runtime_gpe_block ( acpi_hw_enable_runtime_gpe_block (
......
...@@ -189,13 +189,13 @@ acpi_os_get_physical_address ( ...@@ -189,13 +189,13 @@ acpi_os_get_physical_address (
acpi_status acpi_status
acpi_os_install_interrupt_handler ( acpi_os_install_interrupt_handler (
u32 gsi, u32 gsi,
OSD_HANDLER service_routine, acpi_osd_handler service_routine,
void *context); void *context);
acpi_status acpi_status
acpi_os_remove_interrupt_handler ( acpi_os_remove_interrupt_handler (
u32 interrupt_number, u32 gsi,
OSD_HANDLER service_routine); acpi_osd_handler service_routine);
/* /*
...@@ -209,7 +209,7 @@ acpi_os_get_thread_id ( ...@@ -209,7 +209,7 @@ acpi_os_get_thread_id (
acpi_status acpi_status
acpi_os_queue_for_execution ( acpi_os_queue_for_execution (
u32 priority, u32 priority,
OSD_EXECUTION_CALLBACK function, acpi_osd_exec_callback function,
void *context); void *context);
void void
...@@ -262,25 +262,28 @@ acpi_os_write_memory ( ...@@ -262,25 +262,28 @@ acpi_os_write_memory (
/* /*
* Platform and hardware-independent PCI configuration space access * Platform and hardware-independent PCI configuration space access
* Note: Can't use "Register" as a parameter, changed to "Reg" --
* certain compilers complain.
*/ */
acpi_status acpi_status
acpi_os_read_pci_configuration ( acpi_os_read_pci_configuration (
struct acpi_pci_id *pci_id, struct acpi_pci_id *pci_id,
u32 register, u32 reg,
void *value, void *value,
u32 width); u32 width);
acpi_status acpi_status
acpi_os_write_pci_configuration ( acpi_os_write_pci_configuration (
struct acpi_pci_id *pci_id, struct acpi_pci_id *pci_id,
u32 register, u32 reg,
acpi_integer value, acpi_integer value,
u32 width); u32 width);
/* /*
* Interim function needed for PCI IRQ routing * Interim function needed for PCI IRQ routing
*/ */
void void
acpi_os_derive_pci_id( acpi_os_derive_pci_id(
acpi_handle rhandle, acpi_handle rhandle,
......
...@@ -798,11 +798,11 @@ struct acpi_system_info ...@@ -798,11 +798,11 @@ struct acpi_system_info
*/ */
typedef u32 typedef u32
(ACPI_SYSTEM_XFACE *OSD_HANDLER) ( (ACPI_SYSTEM_XFACE *acpi_osd_handler) (
void *context); void *context);
typedef void typedef void
(ACPI_SYSTEM_XFACE *OSD_EXECUTION_CALLBACK) ( (ACPI_SYSTEM_XFACE *acpi_osd_exec_callback) (
void *context); void *context);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment