Commit 2a5cc977 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-acpi.bkbits.net/linux-acpi

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 72785ef7 3469e901
......@@ -1590,6 +1590,12 @@ L: linux-tr@linuxtr.net
W: http://www.linuxtr.net
S: Maintained
TOSHIBA ACPI EXTRAS DRIVER
P: John Belmonte
M: toshiba_acpi@memebeam.org
W: http://memebeam.org/toys/ToshibaAcpiDriver
S: Maintained
TOSHIBA SMM DRIVER
P: Jonathan Buzzard
M: jonathan@buzzard.org.uk
......
......@@ -1051,8 +1051,6 @@ void __init mp_config_acpi_legacy_irqs (void)
return;
}
#endif /*CONFIG_X86_IO_APIC*/
#ifdef CONFIG_ACPI_PCI
void __init mp_parse_prt (void)
......@@ -1120,4 +1118,6 @@ void __init mp_parse_prt (void)
#endif /*CONFIG_ACPI_PCI*/
#endif /*CONFIG_X86_IO_APIC*/
#endif /*CONFIG_ACPI_BOOT*/
......@@ -91,3 +91,25 @@ CONFIG_ACPI_DEBUG
of verbosity. Saying Y enables these statements. This will increase
your kernel size by around 50K.
CONFIG_ACPI_TOSHIBA
This driver adds support for access to certain system settings
on "legacy free" Toshiba laptops. These laptops can be recognized by
their lack of a BIOS setup menu and APM support.
On these machines, all system configuration is handled through the
ACPI. This driver is required for access to controls not covered
by the general ACPI drivers, such as LCD brightness, video output,
etc.
This driver differs from the non-ACPI Toshiba laptop driver (located
under "Processor type and features") in several aspects.
Configuration is accessed by reading and writing text files in the
/proc tree instead of by program interface to /dev. Furthermore, no
power management functions are exposed, as those are handled by the
general ACPI drivers.
More information about this driver is available at
<http://memebeam.org/toys/ToshibaAcpiDriver>.
If you have a legacy free Toshiba laptop (such as the Libretto L1
series), say Y.
......@@ -31,6 +31,7 @@ if [ "$CONFIG_X86" = "y" ]; then
tristate ' Fan' CONFIG_ACPI_FAN
tristate ' Processor' CONFIG_ACPI_PROCESSOR
dep_tristate ' Thermal Zone' CONFIG_ACPI_THERMAL $CONFIG_ACPI_PROCESSOR
tristate ' Toshiba Laptop Extras' CONFIG_ACPI_TOSHIBA
bool ' Debug Statements' CONFIG_ACPI_DEBUG
fi
fi
......
......@@ -43,5 +43,6 @@ obj-$(CONFIG_ACPI_POWER) += power.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
obj-$(CONFIG_ACPI_SYSTEM) += system.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
include $(TOPDIR)/Rules.make
/*
* acpi_bus.h - ACPI Bus Driver ($Revision: 21 $)
* acpi_bus.h - ACPI Bus Driver ($Revision: 22 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -46,7 +46,6 @@ struct acpi_handle_list {
/* acpi_utils.h */
acpi_status acpi_extract_package (acpi_object *, acpi_buffer *, acpi_buffer *);
acpi_status acpi_evaluate (acpi_handle, acpi_string, acpi_object_list *, acpi_buffer *);
acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, acpi_object_list *, unsigned long *);
acpi_status acpi_evaluate_reference (acpi_handle, acpi_string, acpi_object_list *, struct acpi_handle_list *);
......
/*
* acpi_drivers.h ($Revision: 30 $)
* acpi_drivers.h ($Revision: 31 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -124,6 +124,7 @@
#ifdef CONFIG_ACPI_EC
int acpi_ec_ecdt_probe (void);
int acpi_ec_init (void);
void acpi_ec_exit (void);
......
/*
* acpi_ksyms.c - ACPI Kernel Symbols ($Revision: 15 $)
* acpi_ksyms.c - ACPI Kernel Symbols ($Revision: 16 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -102,7 +102,6 @@ EXPORT_SYMBOL(acpi_os_wait_semaphore);
/* ACPI Utilities (acpi_utils.c) */
EXPORT_SYMBOL(acpi_extract_package);
EXPORT_SYMBOL(acpi_evaluate);
EXPORT_SYMBOL(acpi_evaluate_integer);
EXPORT_SYMBOL(acpi_evaluate_reference);
......
/*
* acpi_battery.c - ACPI Battery Driver ($Revision: 35 $)
* acpi_battery.c - ACPI Battery Driver ($Revision: 36 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -251,7 +251,7 @@ acpi_battery_set_alarm (
arg0.integer.value = alarm;
status = acpi_evaluate(battery->handle, "_BTP", &arg_list, NULL);
status = acpi_evaluate_object(battery->handle, "_BTP", &arg_list, NULL);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
......
/*
* acpi_bus.c - ACPI Bus Driver ($Revision: 77 $)
* acpi_bus.c - ACPI Bus Driver ($Revision: 79 $)
*
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*
......@@ -1052,13 +1052,19 @@ acpi_bus_match (
break;
}
if (!cid[0])
if (!cid[0]) {
acpi_os_free(buffer.pointer);
return -ENOENT;
}
if (strstr(driver->ids, cid))
if (strstr(driver->ids, cid)) {
acpi_os_free(buffer.pointer);
return 0;
}
acpi_os_free(buffer.pointer);
}
return -ENOENT;
}
......@@ -1802,7 +1808,7 @@ acpi_bus_scan_fixed (
int result = 0;
struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_bus_scan");
ACPI_FUNCTION_TRACE("acpi_bus_scan_fixed");
if (!root)
return_VALUE(-ENODEV);
......@@ -1929,115 +1935,98 @@ acpi_bus_init (void)
int result = 0;
acpi_status status = AE_OK;
acpi_buffer buffer = {sizeof(acpi_fadt), &acpi_fadt};
int progress = 0;
ACPI_FUNCTION_TRACE("acpi_bus_init");
/*
* [0] Initailize the ACPI Core Subsystem.
*/
status = acpi_initialize_subsystem();
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to initialize the ACPI Interpreter\n");
result = -ENODEV;
goto end;
goto error0;
}
progress++;
/*
* [1] Load the ACPI tables.
*/
status = acpi_load_tables();
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to load the System Description Tables\n");
result = -ENODEV;
goto end;
goto error0;
}
progress++;
/*
* [2] Check the blacklist
*/
if (acpi_blacklisted()) {
result = -ENODEV;
goto end;
goto error1;
}
progress++;
/*
* [3] Get a separate copy of the FADT for use by other drivers.
* Get a separate copy of the FADT for use by other drivers.
*/
status = acpi_get_table(ACPI_TABLE_FADT, 1, &buffer);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to get the FADT\n");
result = -ENODEV;
goto end;
goto error1;
}
progress++;
status = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n");
goto error1;
}
#ifdef CONFIG_ACPI_EC
/*
* [4] Enable the ACPI Core Subsystem.
* ACPI 2.0 requires the EC driver to be loaded and work before
* the EC device is found in the namespace. This is accomplished
* by looking for the ECDT table, and getting the EC parameters out
* of that.
*/
status = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION);
result = acpi_ec_ecdt_probe();
if (result) {
goto error1;
}
#endif
status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n");
result = -ENODEV;
goto end;
printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
goto error1;
}
printk(KERN_INFO PREFIX "Interpreter enabled\n");
progress++;
/*
* [5] Get the system interrupt model and evaluate \_PIC.
* Get the system interrupt model and evaluate \_PIC.
*/
result = acpi_bus_init_irq();
if (result)
goto end;
progress++;
goto error1;
/*
* [6] Register for all standard device notifications.
* Register the for all standard device notifications.
*/
status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, &acpi_bus_notify, NULL);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to register for device notifications\n");
result = -ENODEV;
goto end;
goto error1;
}
progress++;
/*
* [7] Create the root device.
* Create the root device in the bus's device tree
*/
result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT,
ACPI_BUS_TYPE_SYSTEM);
if (result)
goto end;
progress++;
goto error2;
/*
* [8] Create the root file system.
* Create the top ACPI proc directory
*/
acpi_device_dir(acpi_root) = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
if (!acpi_root) {
result = -ENODEV;
goto end;
goto error3;
}
acpi_root_dir = acpi_device_dir(acpi_root);
progress++;
/*
* [9] Install drivers required for proper enumeration of the
* Install drivers required for proper enumeration of the
* ACPI namespace.
*/
acpi_system_init(); /* ACPI System */
......@@ -2049,41 +2038,30 @@ acpi_bus_init (void)
acpi_pci_link_init(); /* ACPI PCI Interrupt Link */
acpi_pci_root_init(); /* ACPI PCI Root Bridge */
#endif
progress++;
/*
* [10] Enumerate devices in the ACPI namespace.
* Enumerate devices in the ACPI namespace.
*/
result = acpi_bus_scan_fixed(acpi_root);
if (result)
goto end;
goto error4;
result = acpi_bus_scan(acpi_root);
if (result)
goto end;
end:
/*
* Clean up if anything went awry.
*/
if (result) {
switch (progress) {
case 10:
case 9: remove_proc_entry("ACPI", NULL);
case 8: acpi_bus_remove(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
case 7: acpi_remove_notify_handler(ACPI_ROOT_OBJECT,
ACPI_SYSTEM_NOTIFY, &acpi_bus_notify);
case 6:
case 5:
case 4:
case 3:
case 2: acpi_terminate();
case 1:
case 0:
default: return_VALUE(-ENODEV);
}
}
goto error4;
return_VALUE(0);
/* Mimic structured exception handling */
error4:
remove_proc_entry("ACPI", NULL);
error3:
acpi_bus_remove(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
error2:
acpi_remove_notify_handler(ACPI_ROOT_OBJECT,
ACPI_SYSTEM_NOTIFY, &acpi_bus_notify);
error1:
acpi_terminate();
error0:
return_VALUE(-ENODEV);
}
......
/*******************************************************************************
*
* Module Name: dbdisasm - parser op tree display routines
* $Revision: 66 $
* $Revision: 67 $
*
******************************************************************************/
......@@ -674,7 +674,8 @@ acpi_db_display_opcode (
(walk_state) &&
(walk_state->results) &&
(walk_state->results->results.num_results)) {
acpi_db_decode_internal_object (walk_state->results->results.obj_desc [walk_state->results->results.num_results-1]);
acpi_db_decode_internal_object (
walk_state->results->results.obj_desc [walk_state->results->results.num_results-1]);
}
#endif
break;
......
/*******************************************************************************
*
* Module Name: dbdisply - debug display commands
* $Revision: 75 $
* $Revision: 76 $
*
******************************************************************************/
......@@ -300,6 +300,11 @@ acpi_db_decode_internal_object (
return;
}
if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
acpi_os_printf ("%p", obj_desc);
return;
}
acpi_os_printf (" %s", acpi_ut_get_object_type_name (obj_desc));
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
......@@ -336,12 +341,45 @@ acpi_db_decode_internal_object (
default:
/* No additional display for other types */
acpi_os_printf ("%p", obj_desc);
break;
}
}
/*******************************************************************************
*
* FUNCTION: Acpi_db_decode_node
*
* PARAMETERS: Node - Object to be displayed
*
* RETURN: None
*
* DESCRIPTION: Short display of a namespace node
*
******************************************************************************/
void
acpi_db_decode_node (
acpi_namespace_node *node)
{
acpi_os_printf ("<Node> Name %4.4s Type-%s",
node->name.ascii, acpi_ut_get_type_name (node->type));
if (node->flags & ANOBJ_METHOD_ARG) {
acpi_os_printf (" [Method Arg]");
}
if (node->flags & ANOBJ_METHOD_LOCAL) {
acpi_os_printf (" [Method Local]");
}
acpi_db_decode_internal_object (acpi_ns_get_attached_object (node));
}
/*******************************************************************************
*
* FUNCTION: Acpi_db_display_internal_object
......@@ -381,16 +419,7 @@ acpi_db_display_internal_object (
case ACPI_DESC_TYPE_NAMED:
acpi_os_printf ("<Node> Name %4.4s Type-%s",
((acpi_namespace_node *)obj_desc)->name.ascii,
acpi_ut_get_type_name (((acpi_namespace_node *) obj_desc)->type));
if (((acpi_namespace_node *) obj_desc)->flags & ANOBJ_METHOD_ARG) {
acpi_os_printf (" [Method Arg]");
}
if (((acpi_namespace_node *) obj_desc)->flags & ANOBJ_METHOD_LOCAL) {
acpi_os_printf (" [Method Local]");
}
acpi_db_decode_node ((acpi_namespace_node *) obj_desc);
break;
......@@ -406,8 +435,10 @@ acpi_db_display_internal_object (
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case INTERNAL_TYPE_REFERENCE:
switch (obj_desc->reference.opcode) {
case AML_LOCAL_OP:
acpi_os_printf ("[Local%d] ", obj_desc->reference.offset);
if (walk_state) {
obj_desc = walk_state->local_variables[obj_desc->reference.offset].object;
......@@ -416,7 +447,9 @@ acpi_db_display_internal_object (
}
break;
case AML_ARG_OP:
acpi_os_printf ("[Arg%d] ", obj_desc->reference.offset);
if (walk_state) {
obj_desc = walk_state->arguments[obj_desc->reference.offset].object;
......@@ -425,24 +458,51 @@ acpi_db_display_internal_object (
}
break;
case AML_DEBUG_OP:
acpi_os_printf ("[Debug] ");
break;
case AML_INDEX_OP:
acpi_os_printf ("[Index] ");
acpi_db_decode_internal_object (obj_desc->reference.object);
break;
case AML_REF_OF_OP:
acpi_os_printf ("[Reference] ");
/* Reference can be to a Node or an Operand object */
switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc->reference.object)) {
case ACPI_DESC_TYPE_NAMED:
acpi_db_decode_node (obj_desc->reference.object);
break;
case ACPI_DESC_TYPE_OPERAND:
acpi_db_decode_internal_object (obj_desc->reference.object);
break;
default:
break;
}
break;
default:
acpi_os_printf ("Unknown Reference opcode %X\n",
obj_desc->reference.opcode);
break;
}
break;
default:
acpi_os_printf ("<Obj> ");
acpi_os_printf (" ");
acpi_db_decode_internal_object (obj_desc);
......
/*******************************************************************************
*
* Module Name: dbexec - debugger control method execution
* $Revision: 41 $
* $Revision: 42 $
*
******************************************************************************/
......@@ -223,6 +223,9 @@ acpi_db_execute (
acpi_gbl_db_method_info.args = args;
acpi_gbl_db_method_info.flags = flags;
return_obj.pointer = NULL;
return_obj.length = ACPI_ALLOCATE_BUFFER;
acpi_db_execute_setup (&acpi_gbl_db_method_info);
status = acpi_db_execute_method (&acpi_gbl_db_method_info, &return_obj);
......@@ -260,6 +263,10 @@ acpi_db_execute (
acpi_gbl_db_method_info.pathname, return_obj.pointer, return_obj.length);
acpi_db_dump_object (return_obj.pointer, 1);
}
else {
acpi_os_printf ("No return object from execution of %s\n",
acpi_gbl_db_method_info.pathname);
}
}
acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
......
......@@ -2,7 +2,7 @@
*
* Module Name: dbfileio - Debugger file I/O commands. These can't usually
* be used when running the debugger in Ring 0 (Kernel mode)
* $Revision: 63 $
* $Revision: 64 $
*
******************************************************************************/
......@@ -279,9 +279,13 @@ ae_local_load_table (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Install the new table into the local data structures */
table_info.pointer = table_ptr;
status = acpi_tb_recognize_table (&table_info, ACPI_TABLE_SECONDARY);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Install the new table into the local data structures */
status = acpi_tb_install_table (&table_info);
if (ACPI_FAILURE (status)) {
......
/******************************************************************************
*
* Module Name: dsmethod - Parser/Interpreter interface - control method parsing
* $Revision: 86 $
* $Revision: 87 $
*
*****************************************************************************/
......@@ -290,7 +290,7 @@ acpi_ds_call_control_method (
/* Create and init a Root Node */
op = acpi_ps_alloc_op (AML_SCOPE_OP);
op = acpi_ps_create_scope_op ();
if (!op) {
status = AE_NO_MEMORY;
goto cleanup;
......
/******************************************************************************
*
* Module Name: dsobject - Dispatcher object management routines
* $Revision: 103 $
* $Revision: 104 $
*
*****************************************************************************/
......@@ -368,6 +368,8 @@ acpi_ds_init_object_from_op (
obj_desc->reference.opcode = AML_LOCAL_OP;
obj_desc->reference.offset = opcode - AML_LOCAL_OP;
acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset,
walk_state, (acpi_namespace_node **) &obj_desc->reference.object);
break;
......
/******************************************************************************
*
* Module Name: dswload - Dispatcher namespace load callbacks
* $Revision: 66 $
* $Revision: 67 $
*
*****************************************************************************/
......@@ -448,12 +448,6 @@ acpi_ds_load2_end_op (
if (op->common.aml_opcode == AML_SCOPE_OP) {
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"Ending scope Op=%p State=%p\n", op, walk_state));
if (op->named.name == ACPI_UINT16_MAX) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unnamed scope! Op=%p State=%p\n",
op, walk_state));
return (AE_OK);
}
}
......
/*
* acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 31 $)
* acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 35 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -76,13 +76,18 @@ static struct acpi_driver acpi_ec_driver = {
struct acpi_ec {
acpi_handle handle;
unsigned long gpe_bit;
unsigned long status_port;
unsigned long command_port;
unsigned long data_port;
acpi_generic_address status_addr;
acpi_generic_address command_addr;
acpi_generic_address data_addr;
unsigned long global_lock;
spinlock_t lock;
};
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
static struct acpi_ec *ec_ecdt;
/* compare this against UIDs in properly enumerated ECs to determine if we
have a dupe */
static unsigned long ecdt_uid = 0xFFFFFFFF;
/* --------------------------------------------------------------------------
Transaction Management
......@@ -93,7 +98,7 @@ acpi_ec_wait (
struct acpi_ec *ec,
u8 event)
{
u8 acpi_ec_status = 0;
u32 acpi_ec_status = 0;
u32 i = ACPI_EC_UDELAY_COUNT;
if (!ec)
......@@ -103,7 +108,7 @@ acpi_ec_wait (
switch (event) {
case ACPI_EC_EVENT_OBF:
do {
acpi_ec_status = inb(ec->status_port);
acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr, 0);
if (acpi_ec_status & ACPI_EC_FLAG_OBF)
return 0;
udelay(ACPI_EC_UDELAY);
......@@ -111,7 +116,7 @@ acpi_ec_wait (
break;
case ACPI_EC_EVENT_IBE:
do {
acpi_ec_status = inb(ec->status_port);
acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr, 0);
if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
return 0;
udelay(ACPI_EC_UDELAY);
......@@ -151,17 +156,18 @@ acpi_ec_read (
spin_lock_irqsave(&ec->lock, flags);
outb(ACPI_EC_COMMAND_READ, ec->command_port);
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr, 0);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
if (result)
goto end;
outb(address, ec->data_port);
acpi_hw_low_level_write(8, address, &ec->data_addr, 0);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
if (result)
goto end;
*data = inb(ec->data_port);
acpi_hw_low_level_read(8, (u32*) data, &ec->data_addr, 0);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
*data, address));
......@@ -200,17 +206,17 @@ acpi_ec_write (
spin_lock_irqsave(&ec->lock, flags);
outb(ACPI_EC_COMMAND_WRITE, ec->command_port);
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr, 0);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
if (result)
goto end;
outb(address, ec->data_port);
acpi_hw_low_level_write(8, address, &ec->data_addr, 0);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
if (result)
goto end;
outb(data, ec->data_port);
acpi_hw_low_level_write(8, data, &ec->data_addr, 0);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
if (result)
goto end;
......@@ -256,15 +262,14 @@ acpi_ec_query (
* Note that successful completion of the query causes the ACPI_EC_SCI
* bit to be cleared (and thus clearing the interrupt source).
*/
spin_lock_irqsave(&ec->lock, flags);
outb(ACPI_EC_COMMAND_QUERY, ec->command_port);
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr, 0);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
if (result)
goto end;
*data = inb(ec->data_port);
acpi_hw_low_level_read(8, (u32*) data, &ec->data_addr, 0);
if (!*data)
result = -ENODATA;
......@@ -309,7 +314,7 @@ acpi_ec_gpe_query (
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
acpi_evaluate(query_data->handle, object_name, NULL, NULL);
acpi_evaluate_object(query_data->handle, object_name, NULL, NULL);
kfree(query_data);
......@@ -331,7 +336,7 @@ acpi_ec_gpe_handler (
return;
spin_lock_irqsave(&ec->lock, flags);
value = inb(ec->command_port);
acpi_hw_low_level_read(8, (u32*) &value, &ec->command_addr, 0);
spin_unlock_irqrestore(&ec->lock, flags);
/* TBD: Implement asynch events!
......@@ -340,7 +345,6 @@ acpi_ec_gpe_handler (
* treat EC-SCIs as level (versus EDGE!) triggered, preventing
* a purely interrupt-driven approach (grumble, grumble).
*/
if (!(value & ACPI_EC_FLAG_SCI))
return;
......@@ -459,7 +463,7 @@ acpi_ec_read_info (
p += sprintf(p, "gpe bit: 0x%02x\n",
(u32) ec->gpe_bit);
p += sprintf(p, "ports: 0x%02x, 0x%02x\n",
(u32) ec->status_port, (u32) ec->data_port);
(u32) ec->status_addr.address, (u32) ec->data_addr.address);
p += sprintf(p, "use global lock: %s\n",
ec->global_lock?"yes":"no");
......@@ -535,6 +539,7 @@ acpi_ec_add (
int result = 0;
acpi_status status = AE_OK;
struct acpi_ec *ec = NULL;
unsigned long uid;
ACPI_FUNCTION_TRACE("acpi_ec_add");
......@@ -555,6 +560,14 @@ acpi_ec_add (
/* Use the global lock for all EC transactions? */
acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
/* If our UID matches ecdt_uid, we already found this EC via the
ECDT. Abort. */
acpi_evaluate_integer(ec->handle, "_UID", NULL, &uid);
if (ecdt_uid == uid) {
result = -ENODEV;
goto end;
}
/* Get GPE bit assignment (EC events). */
status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe_bit);
if (ACPI_FAILURE(status)) {
......@@ -623,9 +636,8 @@ acpi_ec_start (
return_VALUE(-EINVAL);
/*
* Get I/O port addresses
* Get I/O port addresses. Convert to GAS format.
*/
status = acpi_get_current_resources(ec->handle, &buffer);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
......@@ -638,7 +650,10 @@ acpi_ec_start (
result = -ENODEV;
goto end;
}
ec->data_port = resource->data.io.min_base_address;
ec->data_addr.address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
ec->data_addr.register_bit_width = 8;
ec->data_addr.register_bit_offset = 0;
ec->data_addr.address = resource->data.io.min_base_address;
resource = ACPI_NEXT_RESOURCE(resource);
if (!resource || (resource->id != ACPI_RSTYPE_IO)) {
......@@ -646,30 +661,36 @@ acpi_ec_start (
result = -ENODEV;
goto end;
}
ec->command_port = ec->status_port = resource->data.io.min_base_address;
ec->command_addr.address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
ec->command_addr.register_bit_width = 8;
ec->command_addr.register_bit_offset = 0;
ec->command_addr.address = resource->data.io.min_base_address;
ec->status_addr = ec->command_addr;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
(u32) ec->gpe_bit, (u32) ec->command_port, (u32) ec->data_port));
(u32) ec->gpe_bit, (u32) ec->command_addr.address,
(u32) ec->data_addr.address));
/*
* Install GPE handler
*/
status = acpi_install_gpe_handler(ec->gpe_bit,
ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
if (ACPI_FAILURE(status)) {
result = -ENODEV;
goto end;
}
status = acpi_install_address_space_handler (ec->handle,
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
&acpi_ec_space_setup, ec);
if (ACPI_FAILURE(status)) {
acpi_remove_address_space_handler(ec->handle,
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
return_VALUE(-ENODEV);
acpi_remove_gpe_handler(ec->gpe_bit, &acpi_ec_gpe_handler);
result = -ENODEV;
goto end;
}
end:
kfree(buffer.pointer);
acpi_os_free(buffer.pointer);
return_VALUE(result);
}
......@@ -703,6 +724,64 @@ acpi_ec_stop (
}
int __init
acpi_ec_ecdt_probe (void)
{
acpi_status status;
struct acpi_table_ecdt *ecdt_ptr;
status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
(acpi_table_header **) &ecdt_ptr);
if (ACPI_SUCCESS(status)) {
printk(KERN_INFO PREFIX "Found ECDT\n");
/*
* TODO: When the new driver model allows it, simply tell the
* EC driver it has a new device via that, instead if this.
*/
ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!ec_ecdt)
return -ENOMEM;
memset(ec_ecdt, 0, sizeof(struct acpi_ec));
ec_ecdt->command_addr = ecdt_ptr->ec_control;
ec_ecdt->status_addr = ecdt_ptr->ec_control;
ec_ecdt->data_addr = ecdt_ptr->ec_data;
ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
ec_ecdt->lock = SPIN_LOCK_UNLOCKED;
/* use the GL just to be safe */
ec_ecdt->global_lock = TRUE;
ecdt_uid = ecdt_ptr->uid;
/*
* Install GPE handler
*/
status = acpi_install_gpe_handler(ec_ecdt->gpe_bit,
ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler,
ec_ecdt);
if (ACPI_FAILURE(status)) {
goto error;
}
status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
&acpi_ec_space_setup, ec_ecdt);
if (ACPI_FAILURE(status)) {
acpi_remove_gpe_handler(ec_ecdt->gpe_bit,
&acpi_ec_gpe_handler);
goto error;
}
}
return 0;
error:
kfree(ec_ecdt);
return -ENODEV;
}
int __init
acpi_ec_init (void)
{
......@@ -719,6 +798,19 @@ acpi_ec_init (void)
return_VALUE(0);
}
void __exit
acpi_ec_ecdt_exit (void)
{
if (!ec_ecdt)
return;
acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
acpi_remove_gpe_handler(ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
kfree(ec_ecdt);
}
void __exit
acpi_ec_exit (void)
......@@ -731,5 +823,8 @@ acpi_ec_exit (void)
if (!result)
remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
acpi_ec_ecdt_exit();
return_VOID;
}
/******************************************************************************
*
* Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
* $Revision: 66 $
* $Revision: 67 $
*
*****************************************************************************/
......@@ -138,6 +138,7 @@ acpi_ex_load_table_op (
ACPI_FUNCTION_TRACE ("Ex_load_table_op");
#if 0
/*
* Make sure that the signature does not match one of the tables that
* is already loaded.
......@@ -148,6 +149,7 @@ acpi_ex_load_table_op (
return_ACPI_STATUS (AE_ALREADY_EXISTS);
}
#endif
/* Find the ACPI table */
......
/******************************************************************************
*
* Module Name: exdump - Interpreter debug output routines
* $Revision: 155 $
* $Revision: 156 $
*
*****************************************************************************/
......@@ -121,6 +121,13 @@ acpi_ex_dump_operand (
break;
case AML_REF_OF_OP:
acpi_os_printf ("Reference: (Ref_of) %p\n",
obj_desc->reference.object);
break;
case AML_ARG_OP:
acpi_os_printf ("Reference: Arg%d",
......@@ -157,10 +164,12 @@ acpi_ex_dump_operand (
case AML_INT_NAMEPATH_OP:
acpi_os_printf ("Reference.Node->Name %X\n",
obj_desc->reference.node->name.integer);
break;
default:
/* unknown opcode */
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
* $Revision: 106 $
* $Revision: 107 $
*
*****************************************************************************/
......@@ -41,6 +41,7 @@
*
* PARAMETERS: Obj_desc - Create a reference to this object
* Return_desc - Where to store the reference
* Walk_state - Current state
*
* RETURN: Status
*
......@@ -55,65 +56,75 @@ acpi_ex_get_object_reference (
acpi_operand_object **return_desc,
acpi_walk_state *walk_state)
{
acpi_status status = AE_OK;
acpi_operand_object *reference_obj;
acpi_operand_object *referenced_obj;
ACPI_FUNCTION_TRACE_PTR ("Ex_get_object_reference", obj_desc);
*return_desc = NULL;
switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
case ACPI_DESC_TYPE_OPERAND:
if (ACPI_GET_OBJECT_TYPE (obj_desc) != INTERNAL_TYPE_REFERENCE) {
*return_desc = NULL;
status = AE_TYPE;
goto cleanup;
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
/*
* Not a Name -- an indirect name pointer would have
* been converted to a direct name pointer in Acpi_ex_resolve_operands
* Must be a reference to a Local or Arg
*/
switch (obj_desc->reference.opcode) {
case AML_LOCAL_OP:
case AML_ARG_OP:
status = acpi_ds_method_data_get_node (obj_desc->reference.opcode,
obj_desc->reference.offset, walk_state,
ACPI_CAST_INDIRECT_PTR (acpi_namespace_node, return_desc));
/* The referenced object is the pseudo-node for the local/arg */
referenced_obj = obj_desc->reference.object;
break;
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(Internal) Unknown Ref subtype %02x\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference subtype %X\n",
obj_desc->reference.opcode));
*return_desc = NULL;
status = AE_AML_INTERNAL;
goto cleanup;
return_ACPI_STATUS (AE_AML_INTERNAL);
}
break;
case ACPI_DESC_TYPE_NAMED:
/* Must be a named object; Just return the Node */
*return_desc = obj_desc;
/*
* A named reference that has already been resolved to a Node
*/
referenced_obj = obj_desc;
break;
default:
*return_desc = NULL;
status = AE_TYPE;
break;
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type %X in %p\n",
ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc));
return_ACPI_STATUS (AE_TYPE);
}
cleanup:
/* Create a new reference object */
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p Ref=%p\n", obj_desc, *return_desc));
return_ACPI_STATUS (status);
reference_obj = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
if (!reference_obj) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
reference_obj->reference.opcode = AML_REF_OF_OP;
reference_obj->reference.object = referenced_obj;
*return_desc = reference_obj;
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n",
obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
return_ACPI_STATUS (AE_OK);
}
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exoparg1 - AML execution - opcodes with 1 argument
* $Revision: 139 $
* $Revision: 140 $
*
*****************************************************************************/
......@@ -355,7 +355,7 @@ acpi_ex_opcode_1A_1T_1R (
goto cleanup;
}
/* Get the object reference and store it */
/* Get the object reference, store it, and remove our reference */
status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state);
if (ACPI_FAILURE (status)) {
......@@ -363,6 +363,7 @@ acpi_ex_opcode_1A_1T_1R (
}
status = acpi_ex_store (return_desc2, operand[1], walk_state);
acpi_ut_remove_reference (return_desc2);
/* The object exists in the namespace, return TRUE */
......@@ -733,6 +734,15 @@ acpi_ex_opcode_1A_0T_1R (
operand[0] = temp_desc;
break;
case AML_REF_OF_OP:
/* Get the object to which the reference refers */
temp_desc = operand[0]->reference.object;
acpi_ut_remove_reference (operand[0]);
operand[0] = temp_desc;
break;
default:
/* Must be an Index op - handled below */
......
/******************************************************************************
*
* Module Name: exoparg2 - AML execution - opcodes with 2 arguments
* $Revision: 108 $
* $Revision: 109 $
*
*****************************************************************************/
......@@ -359,7 +359,8 @@ acpi_ex_opcode_2A_1T_1R (
/* Object to be indexed is a Package */
if (index >= operand[0]->package.count) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond package end\n"));
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond package end (%X)\n",
index, operand[0]->package.count));
status = AE_AML_PACKAGE_LIMIT;
goto cleanup;
}
......@@ -401,7 +402,8 @@ acpi_ex_opcode_2A_1T_1R (
/* Object to be indexed is a Buffer */
if (index >= operand[0]->buffer.length) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond end of buffer\n"));
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond end of buffer (%X)\n",
index, operand[0]->buffer.length));
status = AE_AML_BUFFER_LIMIT;
goto cleanup;
}
......@@ -522,7 +524,8 @@ acpi_ex_opcode_2A_0T_1R (
default:
ACPI_REPORT_ERROR (("Acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
ACPI_REPORT_ERROR (("Acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n",
walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exresnte - AML Interpreter object resolution
* $Revision: 56 $
* $Revision: 57 $
*
*****************************************************************************/
......@@ -219,7 +219,7 @@ acpi_ex_resolve_node_to_value (
/* No named references are allowed here */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported reference opcode %X\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X\n",
source_desc->reference.opcode));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exresolv - AML Interpreter object resolution
* $Revision: 114 $
* $Revision: 115 $
*
*****************************************************************************/
......@@ -227,9 +227,11 @@ acpi_ex_resolve_object_to_value (
break;
case AML_REF_OF_OP:
case AML_DEBUG_OP:
/* Just leave the object as-is */
break;
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exresop - AML Interpreter operand/object resolution
* $Revision: 53 $
* $Revision: 54 $
*
*****************************************************************************/
......@@ -204,6 +204,7 @@ acpi_ex_resolve_operands (
case AML_DEBUG_OP:
case AML_NAME_OP:
case AML_INDEX_OP:
case AML_REF_OF_OP:
case AML_ARG_OP:
case AML_LOCAL_OP:
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exstore - AML Interpreter object store support
* $Revision: 167 $
* $Revision: 168 $
*
*****************************************************************************/
......@@ -130,6 +130,7 @@ acpi_ex_store (
*/
switch (ref_desc->reference.opcode) {
case AML_NAME_OP:
case AML_REF_OF_OP:
/* Storing an object into a Name "container" */
......
/******************************************************************************
*
* Name: acconfig.h - Global configuration constants
* $Revision: 104 $
* $Revision: 105 $
*
*****************************************************************************/
......@@ -54,7 +54,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20020611
#define ACPI_CA_VERSION 0x20020702
/* Version of ACPI supported */
......
/******************************************************************************
*
* Name: acdebug.h - ACPI/AML debugger
* $Revision: 61 $
* $Revision: 62 $
*
*****************************************************************************/
......@@ -212,6 +212,10 @@ void
acpi_db_decode_internal_object (
acpi_operand_object *obj_desc);
void
acpi_db_decode_node (
acpi_namespace_node *node);
u32
acpi_db_block_type (
acpi_parse_object *op);
......
/******************************************************************************
*
* Name: acglobal.h - Declarations for global variables
* $Revision: 125 $
* $Revision: 126 $
*
*****************************************************************************/
......@@ -72,6 +72,7 @@ extern u32 acpi_gbl_nesting_level;
*
*/
ACPI_EXTERN u32 acpi_gbl_table_flags;
ACPI_EXTERN u32 acpi_gbl_rsdt_table_count;
ACPI_EXTERN RSDP_DESCRIPTOR *acpi_gbl_RSDP;
ACPI_EXTERN xsdt_descriptor *acpi_gbl_XSDT;
ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT;
......
/******************************************************************************
*
* Name: aclocal.h - Internal data types used across the ACPI subsystem
* $Revision: 167 $
* $Revision: 168 $
*
*****************************************************************************/
......@@ -33,10 +33,6 @@ typedef void* acpi_mutex;
typedef u32 ACPI_MUTEX_HANDLE;
#define ACPI_MEMORY_MODE 0x01
#define ACPI_LOGICAL_ADDRESSING 0x00
#define ACPI_PHYSICAL_ADDRESSING 0x01
/* Total number of aml opcodes defined */
#define AML_NUM_OPCODES 0x7E
......
/******************************************************************************
*
* Module Name: acparser.h - AML Parser subcomponent prototypes and defines
* $Revision: 59 $
* $Revision: 60 $
*
*****************************************************************************/
......@@ -266,6 +266,10 @@ acpi_ps_delete_completed_op (
/* psutils - parser utilities */
acpi_parse_object *
acpi_ps_create_scope_op (
void);
void
acpi_ps_init_op (
acpi_parse_object *op,
......
......@@ -43,6 +43,10 @@ acpi_status
acpi_enable_subsystem (
u32 flags);
acpi_status
acpi_initialize_objects (
u32 flags);
acpi_status
acpi_terminate (
void);
......
/******************************************************************************
*
* Name: actables.h - ACPI table management
* $Revision: 41 $
* $Revision: 42 $
*
*****************************************************************************/
......@@ -43,8 +43,7 @@ acpi_tb_handle_to_object (
acpi_status
acpi_tb_convert_to_xsdt (
acpi_table_desc *table_info,
u32 *number_of_tables);
acpi_table_desc *table_info);
acpi_status
acpi_tb_convert_table_fadt (
......@@ -63,13 +62,31 @@ acpi_tb_get_table_count (
* tbget - Table "get" routines
*/
void
acpi_tb_table_override (
acpi_status
acpi_tb_get_table (
ACPI_POINTER *address,
acpi_table_desc *table_info);
acpi_status
acpi_tb_get_table_with_override (
acpi_tb_get_table_header (
ACPI_POINTER *address,
acpi_table_header *return_header);
acpi_status
acpi_tb_get_table_body (
ACPI_POINTER *address,
acpi_table_header *header,
acpi_table_desc *table_info);
acpi_status
acpi_tb_get_this_table (
ACPI_POINTER *address,
acpi_table_header *header,
acpi_table_desc *table_info);
acpi_status
acpi_tb_table_override (
acpi_table_header *header,
acpi_table_desc *table_info);
acpi_status
......@@ -78,11 +95,6 @@ acpi_tb_get_table_ptr (
u32 instance,
acpi_table_header **table_ptr_loc);
acpi_status
acpi_tb_get_table (
ACPI_POINTER *address,
acpi_table_desc *table_info);
acpi_status
acpi_tb_verify_rsdp (
ACPI_POINTER *address);
......@@ -96,20 +108,19 @@ acpi_tb_validate_rsdt (
acpi_table_header *table_ptr);
acpi_status
acpi_tb_get_table_pointer (
ACPI_POINTER *address,
u32 flags,
ACPI_SIZE *size,
acpi_table_header **table_ptr);
/*
* tbgetall - Get all firmware ACPI tables
*/
acpi_tb_get_required_tables (
void);
acpi_status
acpi_tb_get_all_tables (
u32 number_of_tables);
acpi_tb_get_primary_table (
ACPI_POINTER *address,
acpi_table_desc *table_info);
acpi_status
acpi_tb_get_secondary_table (
ACPI_POINTER *address,
acpi_string signature,
acpi_table_desc *table_info);
/*
* tbinstall - Table installation
......@@ -122,11 +133,13 @@ acpi_tb_install_table (
acpi_status
acpi_tb_match_signature (
NATIVE_CHAR *signature,
acpi_table_desc *table_info);
acpi_table_desc *table_info,
u8 search_type);
acpi_status
acpi_tb_recognize_table (
acpi_table_desc *table_info);
acpi_table_desc *table_info,
u8 search_type);
acpi_status
acpi_tb_init_table_descriptor (
......@@ -165,7 +178,7 @@ acpi_tb_free_acpi_tables_of_type (
acpi_status
acpi_tb_get_table_rsdt (
u32 *number_of_tables);
void);
u8 *
acpi_tb_scan_memory_for_rsdp (
......@@ -189,12 +202,6 @@ acpi_tb_find_table (
NATIVE_CHAR *oem_table_id,
acpi_table_header **table_ptr);
acpi_status
acpi_tb_map_acpi_table (
ACPI_PHYSICAL_ADDRESS physical_address,
ACPI_SIZE *size,
acpi_table_header **logical_address);
acpi_status
acpi_tb_verify_table_checksum (
acpi_table_header *table_header);
......
/******************************************************************************
*
* Name: actbl.h - Table data structures defined in ACPI specification
* $Revision: 52 $
* $Revision: 53 $
*
*****************************************************************************/
......@@ -185,9 +185,15 @@ typedef struct /* Smart Battery Description Table */
/* Definitions for the Flags bitfield member of ACPI_TABLE_SUPPORT */
#define ACPI_TABLE_SINGLE 0
#define ACPI_TABLE_MULTIPLE 1
#define ACPI_TABLE_EXECUTABLE 2
#define ACPI_TABLE_SINGLE 0x00
#define ACPI_TABLE_MULTIPLE 0x01
#define ACPI_TABLE_EXECUTABLE 0x02
#define ACPI_TABLE_ROOT 0x00
#define ACPI_TABLE_PRIMARY 0x10
#define ACPI_TABLE_SECONDARY 0x20
#define ACPI_TABLE_OTHER 0x30
#define ACPI_TABLE_TYPE_MASK 0x30
/* Data about each known table type */
......
/******************************************************************************
*
* Name: actypes.h - Common data types for the entire ACPI subsystem
* $Revision: 237 $
* $Revision: 238 $
*
*****************************************************************************/
......@@ -209,8 +209,18 @@ typedef struct acpi_pointer
/* Pointer_types for above */
#define ACPI_LOGICAL_POINTER 0x01
#define ACPI_PHYSICAL_POINTER 0x02
#define ACPI_PHYSICAL_POINTER 0x01
#define ACPI_LOGICAL_POINTER 0x02
/* Processor mode */
#define ACPI_PHYSICAL_ADDRESSING 0x04
#define ACPI_LOGICAL_ADDRESSING 0x08
#define ACPI_MEMORY_MODE 0x0C
#define ACPI_PHYSMODE_PHYSPTR ACPI_PHYSICAL_ADDRESSING | ACPI_PHYSICAL_POINTER
#define ACPI_LOGMODE_PHYSPTR ACPI_LOGICAL_ADDRESSING | ACPI_PHYSICAL_POINTER
#define ACPI_LOGMODE_LOGPTR ACPI_LOGICAL_ADDRESSING | ACPI_LOGICAL_POINTER
/*
......
/******************************************************************************
*
* Module Name: aslresource.h - ASL resource descriptors
* $Revision: 19 $
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2002, R. Byron Moore
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASLRESOURCE_H
#define __ASLRESOURCE_H
#define ASL_RESNAME_ADDRESS "_ADR"
#define ASL_RESNAME_ALIGNMENT "_ALN"
#define ASL_RESNAME_ADDRESSSPACE "_ASI"
#define ASL_RESNAME_BASEADDRESS "_BAS"
#define ASL_RESNAME_BUSMASTER "_BM_" /* Master(1), Slave(0) */
#define ASL_RESNAME_DECODE "_DEC"
#define ASL_RESNAME_DMA "_DMA"
#define ASL_RESNAME_DMATYPE "_TYP" /* Compatible(0), A(1), B(2), F(3) */
#define ASL_RESNAME_GRANULARITY "_GRA"
#define ASL_RESNAME_INTERRUPT "_INT"
#define ASL_RESNAME_INTERRUPTLEVEL "_LL_" /* Active_lo(1), Active_hi(0) */
#define ASL_RESNAME_INTERRUPTSHARE "_SHR" /* Shareable(1), No_share(0) */
#define ASL_RESNAME_INTERRUPTTYPE "_HE_" /* Edge(1), Level(0) */
#define ASL_RESNAME_LENGTH "_LEN"
#define ASL_RESNAME_MEMATTRIBUTES "_MTP" /* Memory(0), Reserved(1), ACPI(2), NVS(3) */
#define ASL_RESNAME_MEMTYPE "_MEM" /* Non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */
#define ASL_RESNAME_MAXADDR "_MAX"
#define ASL_RESNAME_MINADDR "_MIN"
#define ASL_RESNAME_MAXTYPE "_MAF"
#define ASL_RESNAME_MINTYPE "_MIF"
#define ASL_RESNAME_REGISTERBITOFFSET "_RBO"
#define ASL_RESNAME_REGISTERBITWIDTH "_RBW"
#define ASL_RESNAME_RANGETYPE "_RNG"
#define ASL_RESNAME_READWRITETYPE "_RW_" /* Read_only(0), Writeable (1) */
#define ASL_RESNAME_TRANSLATION "_TRA"
#define ASL_RESNAME_TRANSTYPE "_TRS" /* Sparse(1), Dense(0) */
#define ASL_RESNAME_TYPE "_TTP" /* Translation(1), Static (0) */
#define ASL_RESNAME_XFERTYPE "_SIZ" /* 8(0), 8_and16(1), 16(2) */
/* Default sizes for "small" resource descriptors */
#define ASL_RDESC_IRQ_SIZE 0x02
#define ASL_RDESC_DMA_SIZE 0x02
#define ASL_RDESC_ST_DEPEND_SIZE 0x00
#define ASL_RDESC_END_DEPEND_SIZE 0x00
#define ASL_RDESC_IO_SIZE 0x07
#define ASL_RDESC_FIXED_IO_SIZE 0x03
#define ASL_RDESC_END_TAG_SIZE 0x01
typedef struct asl_resource_node
{
u32 buffer_length;
void *buffer;
struct asl_resource_node *next;
} ASL_RESOURCE_NODE;
/*
* Resource descriptors defined in the ACPI specification
*/
#pragma pack(1)
typedef struct asl_irq_format_desc
{
u8 descriptor_type;
u16 irq_mask;
u8 flags;
} ASL_IRQ_FORMAT_DESC;
#pragma pack(1)
typedef struct asl_irq_noflags_desc
{
u8 descriptor_type;
u16 irq_mask;
} ASL_IRQ_NOFLAGS_DESC;
#pragma pack(1)
typedef struct asl_dma_format_desc
{
u8 descriptor_type;
u8 dma_channel_mask;
u8 flags;
} ASL_DMA_FORMAT_DESC;
#pragma pack(1)
typedef struct asl_start_dependent_desc
{
u8 descriptor_type;
u8 flags;
} ASL_START_DEPENDENT_DESC;
#pragma pack(1)
typedef struct asl_start_dependent_noprio_desc
{
u8 descriptor_type;
} ASL_START_DEPENDENT_NOPRIO_DESC;
#pragma pack(1)
typedef struct asl_end_dependent_desc
{
u8 descriptor_type;
} ASL_END_DEPENDENT_DESC;
#pragma pack(1)
typedef struct asl_io_port_desc
{
u8 descriptor_type;
u8 information;
u16 address_min;
u16 address_max;
u8 alignment;
u8 length;
} ASL_IO_PORT_DESC;
#pragma pack(1)
typedef struct asl_fixed_io_port_desc
{
u8 descriptor_type;
u16 base_address;
u8 length;
} ASL_FIXED_IO_PORT_DESC;
#pragma pack(1)
typedef struct asl_small_vendor_desc
{
u8 descriptor_type;
u8 vendor_defined[7];
} ASL_SMALL_VENDOR_DESC;
#pragma pack(1)
typedef struct asl_end_tag_desc
{
u8 descriptor_type;
u8 checksum;
} ASL_END_TAG_DESC;
/* LARGE descriptors */
#pragma pack(1)
typedef struct asl_memory_24_desc
{
u8 descriptor_type;
u16 length;
u8 information;
u16 address_min;
u16 address_max;
u16 alignment;
u16 range_length;
} ASL_MEMORY_24_DESC;
#pragma pack(1)
typedef struct asl_large_vendor_desc
{
u8 descriptor_type;
u16 length;
u8 vendor_defined[1];
} ASL_LARGE_VENDOR_DESC;
#pragma pack(1)
typedef struct asl_memory_32_desc
{
u8 descriptor_type;
u16 length;
u8 information;
u32 address_min;
u32 address_max;
u32 alignment;
u32 range_length;
} ASL_MEMORY_32_DESC;
#pragma pack(1)
typedef struct asl_fixed_memory_32_desc
{
u8 descriptor_type;
u16 length;
u8 information;
u32 base_address;
u32 range_length;
} ASL_FIXED_MEMORY_32_DESC;
#pragma pack(1)
typedef struct asl_qword_address_desc
{
u8 descriptor_type;
u16 length;
u8 resource_type;
u8 flags;
u8 specific_flags;
u64 granularity;
u64 address_min;
u64 address_max;
u64 translation_offset;
u64 address_length;
u8 optional_fields[2];
} ASL_QWORD_ADDRESS_DESC;
#pragma pack(1)
typedef struct asl_dword_address_desc
{
u8 descriptor_type;
u16 length;
u8 resource_type;
u8 flags;
u8 specific_flags;
u32 granularity;
u32 address_min;
u32 address_max;
u32 translation_offset;
u32 address_length;
u8 optional_fields[2];
} ASL_DWORD_ADDRESS_DESC;
#pragma pack(1)
typedef struct asl_word_address_desc
{
u8 descriptor_type;
u16 length;
u8 resource_type;
u8 flags;
u8 specific_flags;
u16 granularity;
u16 address_min;
u16 address_max;
u16 translation_offset;
u16 address_length;
u8 optional_fields[2];
} ASL_WORD_ADDRESS_DESC;
#pragma pack(1)
typedef struct asl_extended_xrupt_desc
{
u8 descriptor_type;
u16 length;
u8 flags;
u8 table_length;
u32 interrupt_number[1];
/* Res_source_index, Res_source optional fields follow */
} ASL_EXTENDED_XRUPT_DESC;
#pragma pack(1)
typedef struct asl_general_register_desc
{
u8 descriptor_type;
u16 length;
u8 address_space_id;
u8 bit_width;
u8 bit_offset;
u8 reserved;
u64 address;
} ASL_GENERAL_REGISTER_DESC;
/* Union of all resource descriptors, sow we can allocate the worst case */
typedef union asl_resource_desc
{
ASL_IRQ_FORMAT_DESC irq;
ASL_DMA_FORMAT_DESC dma;
ASL_START_DEPENDENT_DESC std;
ASL_END_DEPENDENT_DESC end;
ASL_IO_PORT_DESC iop;
ASL_FIXED_IO_PORT_DESC fio;
ASL_SMALL_VENDOR_DESC smv;
ASL_END_TAG_DESC et;
ASL_MEMORY_24_DESC M24;
ASL_LARGE_VENDOR_DESC lgv;
ASL_MEMORY_32_DESC M32;
ASL_FIXED_MEMORY_32_DESC F32;
ASL_QWORD_ADDRESS_DESC qas;
ASL_DWORD_ADDRESS_DESC das;
ASL_WORD_ADDRESS_DESC was;
ASL_EXTENDED_XRUPT_DESC exx;
ASL_GENERAL_REGISTER_DESC grg;
u32 U32_item;
u16 U16_item;
u8 U8item;
} ASL_RESOURCE_DESC;
#define NEXT_RESOURCE_DESC(a,b) (ASL_RESOURCE_DESC *) (((char *) (a)) + sizeof(b))
#define DEFAULT_RESOURCE_DESC_SIZE (sizeof (ASL_RESOURCE_DESC) + sizeof (ASL_END_TAG_DESC))
/*
* Resource utilities
*/
ASL_RESOURCE_NODE *
rs_allocate_resource_node (
u32 size);
void
rs_create_bit_field (
acpi_parse_object *op,
char *name,
u32 byte_offset,
u32 bit_offset);
void
rs_create_byte_field (
acpi_parse_object *op,
char *name,
u32 byte_offset);
void
rs_set_flag_bits (
u8 *flags,
acpi_parse_object *op,
u8 position,
u8 default);
acpi_parse_object *
rs_complete_node_and_get_next (
acpi_parse_object *op);
ASL_RESOURCE_NODE *
rs_do_one_resource_descriptor (
acpi_parse_object *descriptor_type_op,
u32 current_byte_offset);
u32
rs_link_descriptor_chain (
ASL_RESOURCE_NODE **previous_rnode,
ASL_RESOURCE_NODE *rnode);
/*
* Small descriptors
*/
ASL_RESOURCE_NODE *
rs_do_dma_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_end_dependent_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_fixed_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_interrupt_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_irq_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_irq_no_flags_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_memory24_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_memory32_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_memory32_fixed_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_start_dependent_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_start_dependent_no_pri_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_vendor_small_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
/*
* Large descriptors
*/
u32
rs_get_string_data_length (
acpi_parse_object *initializer_op);
ASL_RESOURCE_NODE *
rs_do_dword_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_dword_memory_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_qword_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_qword_memory_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_word_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_word_bus_number_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_vendor_large_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_general_register_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
#endif
/******************************************************************************
*
* Name: aclinux.h - OS specific defines, etc.
* $Revision: 25 $
* $Revision: 26 $
*
*****************************************************************************/
......
......@@ -2,7 +2,7 @@
*
* Module Name: nseval - Object evaluation interfaces -- includes control
* method lookup and execution.
* $Revision: 116 $
* $Revision: 117 $
*
******************************************************************************/
......@@ -485,7 +485,8 @@ acpi_ns_get_object_value (
if (ACPI_SUCCESS (status)) {
status = AE_CTRL_RETURN_VALUE;
*return_obj_desc = ACPI_CAST_PTR (acpi_operand_object, resolved_node);
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning obj %p\n", resolved_node));
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
*return_obj_desc, acpi_ut_get_object_type_name (*return_obj_desc)));
}
}
......
/******************************************************************************
*
* Module Name: nsload - namespace loading/expanding/contracting procedures
* $Revision: 55 $
* $Revision: 56 $
*
*****************************************************************************/
......@@ -115,12 +115,11 @@ acpi_ns_one_complete_parse (
/* Create and init a Root Node */
parse_root = acpi_ps_alloc_op (AML_SCOPE_OP);
parse_root = acpi_ps_create_scope_op ();
if (!parse_root) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
parse_root->named.name = ACPI_ROOT_NAME;
/* Create and initialize a new walk state */
......
/*******************************************************************************
*
* Module Name: nsnames - Name manipulation and search
* $Revision: 77 $
* $Revision: 78 $
*
******************************************************************************/
......@@ -179,7 +179,7 @@ acpi_ns_get_pathname_length (
size = 0;
next_node = node;
while (next_node != acpi_gbl_root_node) {
while (next_node && (next_node != acpi_gbl_root_node)) {
size += PATH_SEGMENT_LENGTH;
next_node = acpi_ns_get_parent_node (next_node);
}
......
/*
* acpi_osl.c - OS-dependent functions ($Revision: 78 $)
* acpi_osl.c - OS-dependent functions ($Revision: 83 $)
*
* Copyright (C) 2000 Andrew Henroid
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
......@@ -42,7 +42,7 @@
u64 efi_mem_attributes (u64 phys_addr);
#endif
#ifdef _IA64
#ifdef CONFIG_IA64
#include <asm/hw_irq.h>
#include <asm/delay.h>
#endif
......@@ -176,7 +176,7 @@ acpi_status
acpi_os_map_memory(ACPI_PHYSICAL_ADDRESS phys, ACPI_SIZE size, void **virt)
{
#ifdef CONFIG_ACPI_EFI
if (EFI_MEMORY_UC & efi_mem_attributes(phys)) {
if (!(EFI_MEMORY_WB & efi_mem_attributes(phys))) {
*virt = ioremap(phys, size);
} else {
*virt = phys_to_virt(phys);
......@@ -234,9 +234,9 @@ acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
acpi_status
acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
{
#ifdef _IA64
irq = isa_irq_to_vector(irq);
#endif /*_IA64*/
#ifdef CONFIG_IA64
irq = gsi_to_vector(irq);
#endif
acpi_irq_irq = irq;
acpi_irq_handler = handler;
acpi_irq_context = context;
......@@ -252,9 +252,9 @@ acpi_status
acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
{
if (acpi_irq_handler) {
#ifdef _IA64
irq = isa_irq_to_vector(irq);
#endif /*_IA64*/
#ifdef CONFIG_IA64
irq = gsi_to_vector(irq);
#endif
free_irq(irq, acpi_irq);
acpi_irq_handler = NULL;
}
......@@ -349,12 +349,13 @@ acpi_os_read_memory(
#ifdef CONFIG_ACPI_EFI
int iomem = 0;
if (EFI_MEMORY_UC & efi_mem_attributes(phys_addr)) {
if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
virt_addr = phys_to_virt(phys_addr);
}
else {
iomem = 1;
virt_addr = ioremap(phys_addr, width);
}
else
virt_addr = phys_to_virt(phys_addr);
#else
virt_addr = phys_to_virt(phys_addr);
#endif
......@@ -394,12 +395,13 @@ acpi_os_write_memory(
#ifdef CONFIG_ACPI_EFI
int iomem = 0;
if (EFI_MEMORY_UC & efi_mem_attributes(phys_addr)) {
if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
virt_addr = phys_to_virt(phys_addr);
}
else {
iomem = 1;
virt_addr = ioremap(phys_addr,width);
virt_addr = ioremap(phys_addr, width);
}
else
virt_addr = phys_to_virt(phys_addr);
#else
virt_addr = phys_to_virt(phys_addr);
#endif
......@@ -627,31 +629,35 @@ acpi_os_queue_for_execution(
case OSD_PRIORITY_GPE:
{
static struct tq_struct task;
/*
* Allocate/initialize DPC structure. Note that this memory will be
* freed by the callee.
* freed by the callee. The kernel handles the tq_struct list in a
* way that allows us to also free its memory inside the callee.
* Because we may want to schedule several tasks with different
* parameters we can't use the approach some kernel code uses of
* having a static tq_struct.
* We can save time and code by allocating the DPC and tq_structs
* from the same memory.
*/
dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_ATOMIC);
struct tq_struct *task;
dpc = kmalloc(sizeof(ACPI_OS_DPC)+sizeof(struct tq_struct), GFP_ATOMIC);
if (!dpc)
return_ACPI_STATUS (AE_NO_MEMORY);
dpc->function = function;
dpc->context = context;
memset(&task, 0, sizeof(struct tq_struct));
task.routine = acpi_os_schedule_exec;
task.data = (void*)dpc;
task = (void *)(dpc+1);
INIT_TQUEUE(task, acpi_os_schedule_exec, (void*)dpc);
if (schedule_task(&task) < 0) {
if (schedule_task(task) < 0) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to schedule_task() failed.\n"));
kfree(dpc);
status = AE_ERROR;
}
}
break;
default:
/*
* Allocate/initialize DPC structure. Note that this memory will be
......
/******************************************************************************
*
* Module Name: psparse - Parser top level AML parse routines
* $Revision: 127 $
* $Revision: 128 $
*
*****************************************************************************/
......@@ -581,6 +581,10 @@ acpi_ps_parse_loop (
pre_op.common.value.arg = NULL;
pre_op.common.aml_opcode = walk_state->opcode;
/*
* Get and append arguments until we find the node that contains
* the name (the type ARGP_NAME).
*/
while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME) {
arg = acpi_ps_get_next_arg (parser_state,
GET_CURRENT_ARG_TYPE (walk_state->arg_types),
......
/******************************************************************************
*
* Module Name: psutils - Parser miscellaneous utilities (Parser only)
* $Revision: 51 $
* $Revision: 52 $
*
*****************************************************************************/
......@@ -27,11 +27,42 @@
#include "acpi.h"
#include "acparser.h"
#include "amlcode.h"
#include "acnamesp.h"
#define _COMPONENT ACPI_PARSER
ACPI_MODULE_NAME ("psutils")
/*******************************************************************************
*
* FUNCTION: Acpi_ps_create_scope_op
*
* PARAMETERS: None
*
* RETURN: Scope_op
*
* DESCRIPTION: Create a Scope and associated namepath op with the root name
*
******************************************************************************/
acpi_parse_object *
acpi_ps_create_scope_op (
void)
{
acpi_parse_object *scope_op;
scope_op = acpi_ps_alloc_op (AML_SCOPE_OP);
if (!scope_op) {
return (NULL);
}
scope_op->named.name = ACPI_ROOT_NAME;
return (scope_op);
}
/*******************************************************************************
*
* FUNCTION: Acpi_ps_init_op
......
/******************************************************************************
*
* Module Name: psxface - Parser external interfaces
* $Revision: 64 $
* $Revision: 65 $
*
*****************************************************************************/
......@@ -108,7 +108,7 @@ acpi_psx_execute (
/* Create and init a Root Node */
op = acpi_ps_alloc_op (AML_SCOPE_OP);
op = acpi_ps_create_scope_op ();
if (!op) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
......@@ -149,7 +149,7 @@ acpi_psx_execute (
/* Create and init a Root Node */
op = acpi_ps_alloc_op (AML_SCOPE_OP);
op = acpi_ps_create_scope_op ();
if (!op) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
......
/*
* pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 7 $)
* pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 10 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -250,8 +250,13 @@ acpi_pci_irq_lookup (
return_VALUE(0);
}
if (!entry->irq && entry->link.handle)
if (!entry->irq && entry->link.handle) {
entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index);
if (!entry->irq) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
return_VALUE(0);
}
}
else if (!entry->irq) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static routing entry (IRQ 0)\n"));
return_VALUE(0);
......@@ -323,7 +328,7 @@ acpi_pci_irq_enable (
/*
* First we check the PCI IRQ routing table (PRT) for an IRQ. PRT
* values override any BIOS-assinged IRQs set during boot.
* values override any BIOS-assigned IRQs set during boot.
*/
irq = acpi_pci_irq_lookup(0, dev->bus->number, PCI_SLOT(dev->devfn), pin);
......@@ -334,14 +339,19 @@ acpi_pci_irq_enable (
if (!irq)
irq = acpi_pci_irq_derive(dev, pin);
if (irq)
dev->irq = irq;
if (!dev->irq) {
printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s\n", ('A' + pin), dev->slot_name);
return_VALUE(0);
/*
* No IRQ known to the ACPI subsystem - maybe the BIOS /
* driver reported one, then use it. Exit in any case.
*/
if (!irq) {
printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s", ('A' + pin), dev->slot_name);
if (dev->irq)
printk(" - using IRQ %d\n", dev->irq);
return_VALUE(dev->irq);
}
dev->irq = irq;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", dev->slot_name, dev->irq));
/*
......
/*
* pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 31 $)
* pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 33 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -110,6 +110,10 @@ acpi_pci_link_get_possible (
resource = (acpi_resource *) buffer.pointer;
/* skip past dependent function resource (if present) */
if (resource->id == ACPI_RSTYPE_START_DPF)
resource = ACPI_NEXT_RESOURCE(resource);
switch (resource->id) {
case ACPI_RSTYPE_IRQ:
{
......@@ -160,7 +164,7 @@ acpi_pci_link_get_possible (
"Found %d possible IRQs\n", link->irq.possible_count));
end:
kfree(buffer.pointer);
acpi_os_free(buffer.pointer);
return_VALUE(result);
}
......@@ -255,7 +259,7 @@ acpi_pci_link_get_current (
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
end:
kfree(buffer.pointer);
acpi_os_free(buffer.pointer);
return_VALUE(result);
}
......@@ -393,7 +397,7 @@ acpi_pci_link_check (void)
if (link->irq.active)
acpi_irq_penalty[link->irq.active] += 100;
else {
else if (link->irq.possible_count) {
int penalty = 100 / link->irq.possible_count;
for (i=0; i<link->irq.possible_count; i++) {
if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ)
......@@ -410,7 +414,7 @@ acpi_pci_link_check (void)
int i = 0;
link = list_entry(node, struct acpi_pci_link, node);
if (!link) {
if (!link || !link->irq.possible_count) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
continue;
}
......@@ -436,7 +440,7 @@ acpi_pci_link_check (void)
printk(PREFIX "%s [%s] enabled at IRQ %d\n",
acpi_device_name(link->device),
acpi_device_bid(link->device), irq);
acpi_device_bid(link->device), link->irq.active);
}
return_VALUE(0);
......
/*
* pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 38 $)
* pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 39 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -154,7 +154,7 @@ acpi_pci_evaluate_crs (
root->mem_tra = acpi_pci_root_bus_tra ((acpi_resource *)
buffer.pointer, ACPI_MEMORY_RANGE);
kfree(buffer.pointer);
acpi_os_free(buffer.pointer);
return_VALUE(0);
}
......
/*
* acpi_power.c - ACPI Bus Power Management ($Revision: 37 $)
* acpi_power.c - ACPI Bus Power Management ($Revision: 38 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -186,7 +186,7 @@ acpi_power_on (
return_VALUE(0);
}
status = acpi_evaluate(resource->handle, "_ON", NULL, NULL);
status = acpi_evaluate_object(resource->handle, "_ON", NULL, NULL);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
......@@ -240,7 +240,7 @@ acpi_power_off (
return_VALUE(0);
}
status = acpi_evaluate(resource->handle, "_OFF", NULL, NULL);
status = acpi_evaluate_object(resource->handle, "_OFF", NULL, NULL);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
......
/*
* acpi_processor.c - ACPI Processor Driver ($Revision: 66 $)
* acpi_processor.c - ACPI Processor Driver ($Revision: 69 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -616,8 +616,15 @@ acpi_processor_set_power_policy (
* Set the default C1 promotion and C2 demotion policies, where we
* promote from C1 to C2 after several (10) successive C1 transitions,
* as we cannot (currently) measure the time spent in C1. Demote from
* C2 to C1 after experiencing several (4) 'shorts' (time spent in C2
* is less than the C2 transtion latency).
* C2 to C1 anytime we experience a 'short' (time spent in C2 is less
* than the C2 transtion latency). Note the simplifying assumption
* that the 'cost' of a transition is amortized when we sleep for at
* least as long as the transition's latency (thus the total transition
* time is two times the latency).
*
* TBD: Measure C1 sleep times by instrumenting the core IRQ handler.
* TBD: Demote to default C-State after long periods of activity.
* TBD: Investigate policy's use of CPU utilization -vs- sleep duration.
*/
if (pr->power.states[ACPI_STATE_C2].valid) {
pr->power.states[ACPI_STATE_C1].promotion.threshold.count = 10;
......@@ -625,7 +632,7 @@ acpi_processor_set_power_policy (
pr->power.states[ACPI_STATE_C2].latency_ticks;
pr->power.states[ACPI_STATE_C1].promotion.state = ACPI_STATE_C2;
pr->power.states[ACPI_STATE_C2].demotion.threshold.count = 4;
pr->power.states[ACPI_STATE_C2].demotion.threshold.count = 1;
pr->power.states[ACPI_STATE_C2].demotion.threshold.ticks =
pr->power.states[ACPI_STATE_C2].latency_ticks;
pr->power.states[ACPI_STATE_C2].demotion.state = ACPI_STATE_C1;
......@@ -929,7 +936,7 @@ acpi_processor_get_performance_control (
pr->performance.status_register));
end:
kfree(buffer.pointer);
acpi_os_free(buffer.pointer);
return_VALUE(result);
}
......@@ -1006,7 +1013,7 @@ acpi_processor_get_performance_states (
}
end:
kfree(buffer.pointer);
acpi_os_free(buffer.pointer);
return_VALUE(result);
}
......@@ -2059,11 +2066,8 @@ acpi_processor_get_info (
if (!pr)
return_VALUE(-EINVAL);
#ifdef CONFIG_SMP
/* FIXME: What should this be? -- RR */
if (num_online_cpus() > 1)
errata.smp = num_online_cpus();
#endif
errata.smp = TRUE;
acpi_processor_errata(pr);
......
/*******************************************************************************
*
* Module Name: rscreate - Create resource lists/tables
* $Revision: 57 $
* $Revision: 58 $
*
******************************************************************************/
......@@ -39,7 +39,6 @@
*
* PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream
* Output_buffer - Pointer to the user's buffer
* Output_buffer_length - Pointer to the size of Output_buffer
*
* RETURN: Status - AE_OK if okay, else a valid acpi_status code
* If Output_buffer is not large enough, Output_buffer_length
......@@ -116,7 +115,6 @@ acpi_rs_create_resource_list (
* PARAMETERS: Package_object - Pointer to an acpi_operand_object
* package
* Output_buffer - Pointer to the user's buffer
* Output_buffer_length - Size of Output_buffer
*
* RETURN: Status AE_OK if okay, else a valid acpi_status code.
* If the Output_buffer is too small, the error will be
......
/*******************************************************************************
*
* Module Name: rsio - IO and DMA resource descriptors
* $Revision: 20 $
* $Revision: 21 $
*
******************************************************************************/
......@@ -410,6 +410,7 @@ acpi_rs_dma_resource (
if (i == 0) {
/* Zero channels is invalid! */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found Zero DMA channels in resource list\n"));
return_ACPI_STATUS (AE_BAD_DATA);
}
output_struct->data.dma.number_of_channels = i;
......@@ -432,6 +433,7 @@ acpi_rs_dma_resource (
output_struct->data.dma.transfer = temp8 & 0x03;
if (0x03 == output_struct->data.dma.transfer) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid DMA.Transfer preference (3)\n"));
return_ACPI_STATUS (AE_BAD_DATA);
}
......
/*******************************************************************************
*
* Module Name: rsirq - IRQ resource descriptors
* $Revision: 28 $
* $Revision: 29 $
*
******************************************************************************/
......@@ -99,6 +99,7 @@ acpi_rs_irq_resource (
if (i == 0) {
/* Zero interrupts is invalid! */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found Zero interrupt levels in resource list\n"));
return_ACPI_STATUS (AE_BAD_DATA);
}
output_struct->data.irq.number_of_interrupts = i;
......@@ -133,6 +134,7 @@ acpi_rs_irq_resource (
* are allowed (ACPI spec v1.0b ection 6.4.2.1),
* so an error will occur if we reach this point
*/
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid interrupt polarity/trigger in resource list\n"));
return_ACPI_STATUS (AE_BAD_DATA);
}
}
......
/*******************************************************************************
*
* Module Name: rslist - Linked list utilities
* $Revision: 30 $
* $Revision: 31 $
*
******************************************************************************/
......@@ -471,6 +471,8 @@ acpi_rs_list_to_byte_stream (
* If we get here, everything is out of sync,
* so exit with an error
*/
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n",
linked_list->id));
status = AE_BAD_DATA;
break;
......
/*
* acpi_system.c - ACPI System Driver ($Revision: 57 $)
* acpi_system.c - ACPI System Driver ($Revision: 60 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -24,7 +24,6 @@
*/
#define ACPI_C
#define HAVE_NEW_DEVICE_MODEL
#include <linux/config.h>
#include <linux/kernel.h>
......@@ -126,7 +125,7 @@ acpi_system_restore_state (
/* wait for power to come back */
mdelay(10);
#ifdef HAVE_NEW_DEVICE_MODEL
/* turn all the devices back on */
device_resume(RESUME_POWER_ON);
......@@ -135,11 +134,8 @@ acpi_system_restore_state (
/* restore device context */
device_resume(RESUME_RESTORE_STATE);
#else
#error Resume cant work without driver model
#endif
if ((state == ACPI_STATE_S1) && (dmi_broken & BROKEN_INIT_AFTER_S1)) {
if (dmi_broken & BROKEN_INIT_AFTER_S1) {
printk("Broken toshiba laptop -> kicking interrupts\n");
init_8259A(0);
}
......@@ -166,7 +162,6 @@ acpi_system_save_state(
{
int error = 0;
#ifdef HAVE_NEW_DEVICE_MODEL
/* Send notification to devices that they will be suspended.
* If any device or driver cannot make the transition, either up
* or down, we'll get an error back.
......@@ -174,10 +169,9 @@ acpi_system_save_state(
error = device_suspend(state, SUSPEND_NOTIFY);
if (error)
return AE_ERROR;
#endif
if (state < ACPI_STATE_S5) {
#ifdef HAVE_NEW_DEVICE_MODEL
/* Tell devices to stop I/O and actually save their state.
* It is theoretically possible that something could fail,
* so handle that gracefully..
......@@ -190,7 +184,6 @@ acpi_system_save_state(
device_resume(RESUME_RESTORE_STATE);
return error;
}
#endif
/* flush caches */
ACPI_FLUSH_CPU_CACHE();
......@@ -202,15 +195,13 @@ acpi_system_save_state(
if (!error && (state == ACPI_STATE_S4))
error = acpi_save_state_disk();
#ifdef HAVE_NEW_DEVICE_MODEL
if (error) {
device_resume(RESUME_RESTORE_STATE);
return error;
}
#endif
}
}
#ifdef HAVE_NEW_DEVICE_MODEL
/* disable interrupts
* Note that acpi_suspend -- our caller -- will do this once we return.
* But, we want it done early, so we don't get any suprises during
......@@ -233,7 +224,7 @@ acpi_system_save_state(
*/
if (error && state != ACPI_STATE_S5)
acpi_system_restore_state(state);
#endif
return error ? AE_ERROR : AE_OK;
}
......@@ -515,12 +506,12 @@ acpi_system_read_dsdt (
if (size > count)
size = count;
if (copy_to_user(buffer, data, size)) {
kfree(dsdt.pointer);
acpi_os_free(dsdt.pointer);
return_VALUE(-EFAULT);
}
}
kfree(dsdt.pointer);
acpi_os_free(dsdt.pointer);
*ppos += size;
......@@ -558,12 +549,12 @@ acpi_system_read_fadt (
if (size > count)
size = count;
if (copy_to_user(buffer, data, size)) {
kfree(fadt.pointer);
acpi_os_free(fadt.pointer);
return_VALUE(-EFAULT);
}
}
kfree(fadt.pointer);
acpi_os_free(fadt.pointer);
*ppos += size;
......
/******************************************************************************
*
* Module Name: tbconvrt - ACPI Table conversion utilities
* $Revision: 41 $
* $Revision: 42 $
*
*****************************************************************************/
......@@ -90,8 +90,7 @@ acpi_tb_get_table_count (
acpi_status
acpi_tb_convert_to_xsdt (
acpi_table_desc *table_info,
u32 *number_of_tables)
acpi_table_desc *table_info)
{
ACPI_SIZE table_size;
u32 i;
......@@ -101,13 +100,10 @@ acpi_tb_convert_to_xsdt (
ACPI_FUNCTION_ENTRY ();
/* Get the number of tables defined in the RSDT or XSDT */
*number_of_tables = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info->pointer);
/* Compute size of the converted XSDT */
table_size = ((ACPI_SIZE) *number_of_tables * sizeof (u64)) + sizeof (acpi_table_header);
table_size = ((ACPI_SIZE) acpi_gbl_rsdt_table_count * sizeof (u64)) +
sizeof (acpi_table_header);
/* Allocate an XSDT */
......@@ -123,7 +119,7 @@ acpi_tb_convert_to_xsdt (
/* Copy the table pointers */
for (i = 0; i < *number_of_tables; i++) {
for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
if (acpi_gbl_RSDP->revision < 2) {
ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
((RSDT_DESCRIPTOR_REV1 *) table_info->pointer)->table_offset_entry[i]);
......
/******************************************************************************
*
* Module Name: tbget - ACPI Table get* routines
* $Revision: 77 $
* $Revision: 78 $
*
*****************************************************************************/
......@@ -34,777 +34,438 @@
/*******************************************************************************
*
* FUNCTION: Acpi_tb_table_override
* FUNCTION: Acpi_tb_get_table
*
* PARAMETERS: *Table_info - Info for current table
* PARAMETERS: Address - Address of table to retrieve. Can be
* Logical or Physical
* Table_info - Where table info is returned
*
* RETURN: None
*
* DESCRIPTION: Attempts override of current table with a new one if provided
* by the host OS.
* DESCRIPTION: Get entire table of unknown size.
*
******************************************************************************/
void
acpi_tb_table_override (
acpi_status
acpi_tb_get_table (
ACPI_POINTER *address,
acpi_table_desc *table_info)
{
acpi_table_header *new_table;
acpi_status status;
ACPI_POINTER address;
acpi_table_desc new_table_info;
ACPI_FUNCTION_TRACE ("Acpi_tb_table_override");
status = acpi_os_table_override (table_info->pointer, &new_table);
if (ACPI_FAILURE (status)) {
/* Some severe error from the OSL, but we basically ignore it */
acpi_table_header header;
ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
acpi_format_exception (status)));
return_VOID;
}
if (!new_table) {
/* No table override */
ACPI_FUNCTION_TRACE ("Tb_get_table");
return_VOID;
}
/*
* We have a new table to override the old one. Get a copy of
* the new one. We know that the new table has a logical pointer.
* Get the header in order to get signature and table size
*/
address.pointer_type = ACPI_LOGICAL_POINTER;
address.pointer.logical = new_table;
status = acpi_tb_get_table (&address, &new_table_info);
status = acpi_tb_get_table_header (address, &header);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not copy ACPI table override\n"));
return_VOID;
return_ACPI_STATUS (status);
}
/*
* Delete the original table
*/
acpi_tb_delete_single_table (table_info);
/* Copy the table info */
/* Get the entire table */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Successful table override [%4.4s]\n",
((acpi_table_header *) new_table_info.pointer)->signature));
status = acpi_tb_get_table_body (address, &header, table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get ACPI table (size %X), %s\n",
header.length, acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
ACPI_MEMCPY (table_info, &new_table_info, sizeof (acpi_table_desc));
return_VOID;
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_with_override
* FUNCTION: Acpi_tb_get_table_header
*
* PARAMETERS: Address - Physical or logical address of table
* *Table_info - Where the table info is returned
* PARAMETERS: Address - Address of table to retrieve. Can be
* Logical or Physical
* Return_header - Where the table header is returned
*
* RETURN: Status
*
* DESCRIPTION: Gets and installs the table with possible table override by OS.
* DESCRIPTION: Get an ACPI table header. Works in both physical or virtual
* addressing mode. Works with both physical or logical pointers.
* Table is either copied or mapped, depending on the pointer
* type and mode of the processor.
*
******************************************************************************/
acpi_status
acpi_tb_get_table_with_override (
acpi_tb_get_table_header (
ACPI_POINTER *address,
acpi_table_desc *table_info)
acpi_table_header *return_header)
{
acpi_status status;
acpi_status status = AE_OK;
acpi_table_header *header = NULL;
ACPI_FUNCTION_TRACE ("Acpi_tb_get_table_with_override");
ACPI_FUNCTION_TRACE ("Tb_get_table_header");
status = acpi_tb_get_table (address, table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get ACPI table, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/*
* Attempt override. It either happens or it doesn't, no status
* Flags contains the current processor mode (Virtual or Physical addressing)
* The Pointer_type is either Logical or Physical
*/
acpi_tb_table_override (table_info);
switch (address->pointer_type) {
case ACPI_PHYSMODE_PHYSPTR:
case ACPI_LOGMODE_LOGPTR:
/* Install the table */
/* Pointer matches processor mode, copy the header */
status = acpi_tb_install_table (table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not install ACPI table, %s\n",
acpi_format_exception (status)));
}
ACPI_MEMCPY (return_header, address->pointer.logical, sizeof (acpi_table_header));
break;
return_ACPI_STATUS (status);
}
case ACPI_LOGMODE_PHYSPTR:
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_ptr
*
* PARAMETERS: Table_type - one of the defined table types
* Instance - Which table of this type
* Table_ptr_loc - pointer to location to place the pointer for
* return
*
* RETURN: Status
*
* DESCRIPTION: This function is called to get the pointer to an ACPI table.
*
******************************************************************************/
/* Create a logical address for the physical pointer*/
acpi_status
acpi_tb_get_table_ptr (
acpi_table_type table_type,
u32 instance,
acpi_table_header **table_ptr_loc)
{
acpi_table_desc *table_desc;
u32 i;
status = acpi_os_map_memory (address->pointer.physical, sizeof (acpi_table_header),
(void **) &header);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not map memory at %p for length %X\n",
address->pointer.physical, sizeof (acpi_table_header)));
return_ACPI_STATUS (status);
}
/* Copy header and delete mapping */
ACPI_FUNCTION_TRACE ("Tb_get_table_ptr");
ACPI_MEMCPY (return_header, header, sizeof (acpi_table_header));
acpi_os_unmap_memory (header, sizeof (acpi_table_header));
break;
if (!acpi_gbl_DSDT) {
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
default:
if (table_type > ACPI_TABLE_MAX) {
ACPI_REPORT_ERROR (("Invalid address flags %X\n",
address->pointer_type));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* For all table types (Single/Multiple), the first
* instance is always in the list head.
*/
if (instance == 1) {
/*
* Just pluck the pointer out of the global table!
* Will be null if no table is present
*/
*table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
return_ACPI_STATUS (AE_OK);
}
/*
* Check for instance out of range
*/
if (instance > acpi_gbl_acpi_tables[table_type].count) {
return_ACPI_STATUS (AE_NOT_EXIST);
}
/* Walk the list to get the desired table
* Since the if (Instance == 1) check above checked for the
* first table, setting Table_desc equal to the .Next member
* is actually pointing to the second table. Therefore, we
* need to walk from the 2nd table until we reach the Instance
* that the user is looking for and return its table pointer.
*/
table_desc = acpi_gbl_acpi_tables[table_type].next;
for (i = 2; i < instance; i++) {
table_desc = table_desc->next;
}
/* We are now pointing to the requested table's descriptor */
*table_ptr_loc = table_desc->pointer;
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table
* FUNCTION: Acpi_tb_get_table_body
*
* PARAMETERS: Address - Physical address of table to retrieve
* *Table_info - Where the table info is returned
* PARAMETERS: Address - Address of table to retrieve. Can be
* Logical or Physical
* Header - Header of the table to retrieve
* Table_info - Where the table info is returned
*
* RETURN: Status
*
* DESCRIPTION: Maps the physical address of table into a logical address
* DESCRIPTION: Get an entire ACPI table with support to allow the host OS to
* replace the table with a newer version (table override.)
* Works in both physical or virtual
* addressing mode. Works with both physical or logical pointers.
* Table is either copied or mapped, depending on the pointer
* type and mode of the processor.
*
******************************************************************************/
acpi_status
acpi_tb_get_table (
acpi_tb_get_table_body (
ACPI_POINTER *address,
acpi_table_header *header,
acpi_table_desc *table_info)
{
acpi_table_header *table_header = NULL;
acpi_table_header *full_table = NULL;
ACPI_SIZE size;
u8 allocation;
acpi_status status = AE_OK;
acpi_status status;
ACPI_FUNCTION_TRACE ("Tb_get_table");
ACPI_FUNCTION_TRACE ("Tb_get_table_body");
if (!table_info || !address) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
switch (address->pointer_type) {
case ACPI_LOGICAL_POINTER:
/*
* Getting data from a buffer, not BIOS tables
*/
table_header = address->pointer.logical;
/* Allocate buffer for the entire table */
full_table = ACPI_MEM_ALLOCATE (table_header->length);
if (!full_table) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Copy the entire table (including header) to the local buffer */
size = (ACPI_SIZE) table_header->length;
ACPI_MEMCPY (full_table, table_header, size);
/* Save allocation type */
allocation = ACPI_MEM_ALLOCATED;
break;
case ACPI_PHYSICAL_POINTER:
/*
* Not reading from a buffer, just map the table's physical memory
* into our address space.
* Attempt table override.
*/
size = SIZE_IN_HEADER;
status = acpi_tb_table_override (header, table_info);
if (ACPI_SUCCESS (status)) {
/* Table was overridden by the host OS */
status = acpi_tb_map_acpi_table (address->pointer.physical, &size, &full_table);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Save allocation type */
allocation = ACPI_MEM_MAPPED;
break;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Return values */
table_info->pointer = full_table;
table_info->length = size;
table_info->allocation = allocation;
table_info->base_pointer = full_table;
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
full_table->signature,
ACPI_HIDWORD (address->pointer.physical),
ACPI_LODWORD (address->pointer.physical), full_table));
/* No override, get the original table */
status = acpi_tb_get_this_table (address, header, table_info);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_all_tables
*
* PARAMETERS: Number_of_tables - Number of tables to get
*
* RETURN: Status
* FUNCTION: Acpi_tb_table_override
*
* DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must
* already be loaded and validated.
* PARAMETERS: Header - Pointer to table header
* Table_info - Return info if table is overridden
*
* Get the minimum set of ACPI tables, namely:
* RETURN: None
*
* 1) FADT (via RSDT in loop below)
* 2) FACS (via FADT)
* 3) DSDT (via FADT)
* DESCRIPTION: Attempts override of current table with a new one if provided
* by the host OS.
*
******************************************************************************/
acpi_status
acpi_tb_get_all_tables (
u32 number_of_tables)
acpi_tb_table_override (
acpi_table_header *header,
acpi_table_desc *table_info)
{
acpi_status status = AE_OK;
u32 index;
acpi_table_desc table_info;
acpi_table_header *new_table;
acpi_status status;
ACPI_POINTER address;
ACPI_FUNCTION_TRACE ("Tb_get_all_tables");
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Number of tables: %d\n", number_of_tables));
/*
* Loop through all table pointers found in RSDT.
* This will NOT include the FACS and DSDT - we must get
* them after the loop.
*
* The ONLY table we are interested in getting here is the FADT.
*/
for (index = 0; index < number_of_tables; index++) {
/* Clear the Table_info each time */
ACPI_MEMSET (&table_info, 0, sizeof (acpi_table_desc));
/* Get the table via the XSDT */
address.pointer_type = acpi_gbl_table_flags;
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_XSDT->table_offset_entry[index]);
ACPI_FUNCTION_TRACE ("Tb_table_override");
status = acpi_tb_get_table (&address, &table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Recognize and install the table */
status = acpi_tb_install_table (&table_info);
if (ACPI_FAILURE (status)) {
/*
* Unrecognized or unsupported table, delete it and ignore the
* error. Just get as many tables as we can, later we will
* determine if there are enough tables to continue.
*/
(void) acpi_tb_uninstall_table (&table_info);
status = AE_OK;
}
}
if (!acpi_gbl_FADT) {
ACPI_REPORT_ERROR (("No FADT present in R/XSDT\n"));
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
/*
* Convert the FADT to a common format. This allows earlier revisions of the
* table to coexist with newer versions, using common access code.
* The OSL will examine the header and decide whether to override this
* table. If it decides to override, a table will be returned in New_table,
* which we will then copy.
*/
status = acpi_tb_convert_table_fadt ();
status = acpi_os_table_override (header, &new_table);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
return_ACPI_STATUS (status);
}
/*
* Get the FACS (must have the FADT first, from loop above)
* Acpi_tb_get_table_facs will fail if FADT pointer is not valid
*/
address.pointer_type = acpi_gbl_table_flags;
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_FADT->Xfirmware_ctrl);
/* Some severe error from the OSL, but we basically ignore it */
status = acpi_tb_get_table (&address, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get the FACS, %s\n",
ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/* Install the FACS */
status = acpi_tb_install_table (&table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not install the FACS, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
if (!new_table) {
/* No table override */
/*
* Create the common FACS pointer table
* (Contains pointers to the original table)
*/
status = acpi_tb_build_common_facs (&table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
/*
* Get/install the DSDT (We know that the FADT is valid now)
* We have a new table to override the old one. Get a copy of
* the new one. We know that the new table has a logical pointer.
*/
address.pointer_type = acpi_gbl_table_flags;
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_FADT->Xdsdt);
address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
address.pointer.logical = new_table;
status = acpi_tb_get_table_with_override (&address, &table_info);
status = acpi_tb_get_this_table (&address, new_table, table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get the DSDT\n"));
ACPI_REPORT_ERROR (("Could not copy override ACPI table, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/* Set Integer Width (32/64) based upon DSDT revision */
acpi_ut_set_integer_width (acpi_gbl_DSDT->revision);
/* Dump the entire DSDT */
ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
"Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width));
ACPI_DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);
/* Copy the table info */
/* Always delete the RSDP mapping, we are done with it */
ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
table_info->pointer->signature));
acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);
return_ACPI_STATUS (status);
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_verify_rsdp
* FUNCTION: Acpi_tb_get_this_table
*
* PARAMETERS: Number_of_tables - Where the table count is placed
* PARAMETERS: Address - Address of table to retrieve. Can be
* Logical or Physical
* Header - Header of the table to retrieve
* Table_info - Where the table info is returned
*
* RETURN: Status
*
* DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
* DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual
* addressing mode. Works with both physical or logical pointers.
* Table is either copied or mapped, depending on the pointer
* type and mode of the processor.
*
******************************************************************************/
acpi_status
acpi_tb_verify_rsdp (
ACPI_POINTER *address)
acpi_tb_get_this_table (
ACPI_POINTER *address,
acpi_table_header *header,
acpi_table_desc *table_info)
{
acpi_table_desc table_info;
acpi_status status;
RSDP_DESCRIPTOR *rsdp;
acpi_table_header *full_table = NULL;
u8 allocation;
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE ("Tb_verify_rsdp");
ACPI_FUNCTION_TRACE ("Tb_get_this_table");
switch (address->pointer_type) {
case ACPI_LOGICAL_POINTER:
rsdp = address->pointer.logical;
break;
case ACPI_PHYSICAL_POINTER:
/*
* Obtain access to the RSDP structure
* Flags contains the current processor mode (Virtual or Physical addressing)
* The Pointer_type is either Logical or Physical
*/
status = acpi_os_map_memory (address->pointer.physical, sizeof (RSDP_DESCRIPTOR),
(void **) &rsdp);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
break;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* The signature and checksum must both be correct
*/
if (ACPI_STRNCMP ((NATIVE_CHAR *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
/* Nope, BAD Signature */
status = AE_BAD_SIGNATURE;
goto cleanup;
}
/* Check the standard checksum */
if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
status = AE_BAD_CHECKSUM;
goto cleanup;
}
/* Check extended checksum if table version >= 2 */
if (rsdp->revision >= 2) {
if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
status = AE_BAD_CHECKSUM;
goto cleanup;
}
}
/* The RSDP supplied is OK */
table_info.pointer = ACPI_CAST_PTR (acpi_table_header, rsdp);
table_info.length = sizeof (RSDP_DESCRIPTOR);
table_info.allocation = ACPI_MEM_MAPPED;
table_info.base_pointer = rsdp;
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Save the RSDP in a global for easy access */
acpi_gbl_RSDP = ACPI_CAST_PTR (RSDP_DESCRIPTOR, table_info.pointer);
return_ACPI_STATUS (status);
/* Error exit */
cleanup:
if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) {
acpi_os_unmap_memory (rsdp, sizeof (RSDP_DESCRIPTOR));
}
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_rsdt_address
*
* PARAMETERS: None
*
* RETURN: RSDT physical address
*
* DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
* version of the RSDP
*
******************************************************************************/
void
acpi_tb_get_rsdt_address (
ACPI_POINTER *out_address)
{
ACPI_FUNCTION_ENTRY ();
switch (address->pointer_type) {
case ACPI_PHYSMODE_PHYSPTR:
case ACPI_LOGMODE_LOGPTR:
out_address->pointer_type = acpi_gbl_table_flags;
/* Pointer matches processor mode, copy the table to a new buffer */
/*
* For RSDP revision 0 or 1, we use the RSDT.
* For RSDP revision 2 (and above), we use the XSDT
*/
if (acpi_gbl_RSDP->revision < 2) {
out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
}
else {
out_address->pointer.value = ACPI_GET_ADDRESS (acpi_gbl_RSDP->xsdt_physical_address);
full_table = ACPI_MEM_ALLOCATE (header->length);
if (!full_table) {
ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n",
header->signature, header->length));
return_ACPI_STATUS (AE_NO_MEMORY);
}
}
/* Copy the entire table (including header) to the local buffer */
/*******************************************************************************
*
* FUNCTION: Acpi_tb_validate_rsdt
*
* PARAMETERS: Table_ptr - Addressable pointer to the RSDT.
*
* RETURN: Status
*
* DESCRIPTION: Validate signature for the RSDT or XSDT
*
******************************************************************************/
ACPI_MEMCPY (full_table, address->pointer.logical, header->length);
acpi_status
acpi_tb_validate_rsdt (
acpi_table_header *table_ptr)
{
int no_match;
/* Save allocation type */
allocation = ACPI_MEM_ALLOCATED;
break;
ACPI_FUNCTION_NAME ("Tb_validate_rsdt");
case ACPI_LOGMODE_PHYSPTR:
/*
* For RSDP revision 0 or 1, we use the RSDT.
* For RSDP revision 2 and above, we use the XSDT
* Just map the table's physical memory
* into our address space.
*/
if (acpi_gbl_RSDP->revision < 2) {
no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG,
sizeof (RSDT_SIG) -1);
}
else {
no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG,
sizeof (XSDT_SIG) -1);
status = acpi_os_map_memory (address->pointer.physical, (ACPI_SIZE) header->length,
(void **) &full_table);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %p for length %X\n",
header->signature, address->pointer.physical, header->length));
return (status);
}
if (no_match) {
/* Invalid RSDT or XSDT signature */
/* Save allocation type */
ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
allocation = ACPI_MEM_MAPPED;
break;
ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
"RSDT/XSDT signature at %X (%p) is invalid\n",
acpi_gbl_RSDP->rsdt_physical_address,
(void *) (NATIVE_UINT) acpi_gbl_RSDP->rsdt_physical_address));
default:
return (AE_BAD_SIGNATURE);
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n",
address->pointer_type));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_pointer
*
* PARAMETERS: Physical_address - Address from RSDT
* Flags - virtual or physical addressing
* Table_ptr - Addressable address (output)
*
* RETURN: Status
*
* DESCRIPTION: Create an addressable pointer to an ACPI table
*
******************************************************************************/
acpi_status
acpi_tb_get_table_pointer (
ACPI_POINTER *address,
u32 flags,
ACPI_SIZE *size,
acpi_table_header **table_ptr)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_ENTRY ();
/*
* What mode is the processor in? (Virtual or Physical addressing)
* Validate checksum for _most_ tables,
* even the ones whose signature we don't recognize
*/
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
/* Incoming pointer can be either logical or physical */
switch (address->pointer_type) {
case ACPI_PHYSICAL_POINTER:
*size = SIZE_IN_HEADER;
status = acpi_tb_map_acpi_table (address->pointer.physical, size, table_ptr);
break;
case ACPI_LOGICAL_POINTER:
if (table_info->type != ACPI_TABLE_FACS) {
status = acpi_tb_verify_table_checksum (full_table);
*table_ptr = address->pointer.logical;
*size = 0;
break;
#if (!ACPI_CHECKSUM_ABORT)
if (ACPI_FAILURE (status)) {
/* Ignore the error if configuration says so */
default:
return (AE_BAD_PARAMETER);
status = AE_OK;
}
#endif
}
else {
/* In Physical addressing mode, all pointers must be physical */
switch (address->pointer_type) {
case ACPI_PHYSICAL_POINTER:
*size = 0;
*table_ptr = address->pointer.logical;
break;
case ACPI_LOGICAL_POINTER:
/* Return values */
status = AE_BAD_PARAMETER;
break;
table_info->pointer = full_table;
table_info->length = (ACPI_SIZE) header->length;
table_info->allocation = allocation;
table_info->base_pointer = full_table;
default:
return (AE_BAD_PARAMETER);
}
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
full_table->signature,
ACPI_HIDWORD (address->pointer.physical),
ACPI_LODWORD (address->pointer.physical), full_table));
return (status);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_rsdt
* FUNCTION: Acpi_tb_get_table_ptr
*
* PARAMETERS: Number_of_tables - Where the table count is placed
* PARAMETERS: Table_type - one of the defined table types
* Instance - Which table of this type
* Table_ptr_loc - pointer to location to place the pointer for
* return
*
* RETURN: Status
*
* DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
* DESCRIPTION: This function is called to get the pointer to an ACPI table.
*
******************************************************************************/
acpi_status
acpi_tb_get_table_rsdt (
u32 *number_of_tables)
acpi_tb_get_table_ptr (
acpi_table_type table_type,
u32 instance,
acpi_table_header **table_ptr_loc)
{
acpi_table_desc table_info;
acpi_status status;
ACPI_POINTER address;
acpi_table_desc *table_desc;
u32 i;
ACPI_FUNCTION_TRACE ("Tb_get_table_rsdt");
ACPI_FUNCTION_TRACE ("Tb_get_table_ptr");
/* Get the RSDT/XSDT from the RSDP */
acpi_tb_get_rsdt_address (&address);
status = acpi_tb_get_table (&address, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the R/XSDT, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
if (!acpi_gbl_DSDT) {
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
acpi_gbl_RSDP,
ACPI_HIDWORD (address.pointer.value),
ACPI_LODWORD (address.pointer.value)));
/* Check the RSDT or XSDT signature */
status = acpi_tb_validate_rsdt (table_info.pointer);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
if (table_type > ACPI_TABLE_MAX) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* Valid RSDT signature, verify the checksum. If it fails, just
* print a warning and ignore it.
* For all table types (Single/Multiple), the first
* instance is always in the list head.
*/
status = acpi_tb_verify_table_checksum (table_info.pointer);
/* Convert and/or copy to an XSDT structure */
status = acpi_tb_convert_to_xsdt (&table_info, number_of_tables);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
if (instance == 1) {
/*
* Just pluck the pointer out of the global table!
* Will be null if no table is present
*/
*table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
return_ACPI_STATUS (AE_OK);
}
/* Save the table pointers and allocation info */
/*
* Check for instance out of range
*/
if (instance > acpi_gbl_acpi_tables[table_type].count) {
return_ACPI_STATUS (AE_NOT_EXIST);
}
status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
/* Walk the list to get the desired table
* Since the if (Instance == 1) check above checked for the
* first table, setting Table_desc equal to the .Next member
* is actually pointing to the second table. Therefore, we
* need to walk from the 2nd table until we reach the Instance
* that the user is looking for and return its table pointer.
*/
table_desc = acpi_gbl_acpi_tables[table_type].next;
for (i = 2; i < instance; i++) {
table_desc = table_desc->next;
}
acpi_gbl_XSDT = (xsdt_descriptor *) table_info.pointer;
/* We are now pointing to the requested table's descriptor */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
return_ACPI_STATUS (status);
}
*table_ptr_loc = table_desc->pointer;
return_ACPI_STATUS (AE_OK);
}
/******************************************************************************
*
* Module Name: tbgetall - Get all required ACPI tables
* $Revision: 1 $
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2002, R. Byron Moore
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "acpi.h"
#include "actables.h"
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbgetall")
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_primary_table
*
* PARAMETERS: Address - Physical address of table to retrieve
* *Table_info - Where the table info is returned
*
* RETURN: Status
*
* DESCRIPTION: Maps the physical address of table into a logical address
*
******************************************************************************/
acpi_status
acpi_tb_get_primary_table (
ACPI_POINTER *address,
acpi_table_desc *table_info)
{
acpi_status status;
acpi_table_header header;
ACPI_FUNCTION_TRACE ("Tb_get_primary_table");
/* Ignore a NULL address in the RSDT */
if (!address->pointer.value) {
return_ACPI_STATUS (AE_OK);
}
/*
* Get the header in order to get signature and table size
*/
status = acpi_tb_get_table_header (address, &header);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Clear the Table_info */
ACPI_MEMSET (table_info, 0, sizeof (acpi_table_desc));
/*
* Check the table signature and make sure it is recognized.
* Also checks the header checksum
*/
table_info->pointer = &header;
status = acpi_tb_recognize_table (table_info, ACPI_TABLE_PRIMARY);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Get the entire table */
status = acpi_tb_get_table_body (address, &header, table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Install the table */
status = acpi_tb_install_table (table_info);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_secondary_table
*
* PARAMETERS: Address - Physical address of table to retrieve
* *Table_info - Where the table info is returned
*
* RETURN: Status
*
* DESCRIPTION: Maps the physical address of table into a logical address
*
******************************************************************************/
acpi_status
acpi_tb_get_secondary_table (
ACPI_POINTER *address,
acpi_string signature,
acpi_table_desc *table_info)
{
acpi_status status;
acpi_table_header header;
ACPI_FUNCTION_TRACE_STR ("Tb_get_secondary_table", signature);
/* Get the header in order to match the signature */
status = acpi_tb_get_table_header (address, &header);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Signature must match request */
if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
ACPI_REPORT_ERROR (("Incorrect table signature - wanted [%s] found [%4.4s]\n",
signature, header.signature));
return_ACPI_STATUS (AE_BAD_SIGNATURE);
}
/*
* Check the table signature and make sure it is recognized.
* Also checks the header checksum
*/
table_info->pointer = &header;
status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Get the entire table */
status = acpi_tb_get_table_body (address, &header, table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Install the table */
status = acpi_tb_install_table (table_info);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_required_tables
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must
* already be loaded and validated.
*
* Get the minimum set of ACPI tables, namely:
*
* 1) FADT (via RSDT in loop below)
* 2) FACS (via FADT)
* 3) DSDT (via FADT)
*
******************************************************************************/
acpi_status
acpi_tb_get_required_tables (
void)
{
acpi_status status = AE_OK;
u32 i;
acpi_table_desc table_info;
ACPI_POINTER address;
ACPI_FUNCTION_TRACE ("Tb_get_required_tables");
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
acpi_gbl_rsdt_table_count));
address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
/*
* Loop through all table pointers found in RSDT.
* This will NOT include the FACS and DSDT - we must get
* them after the loop.
*
* The only tables we are interested in getting here is the FADT and
* any SSDTs.
*/
for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
/* Get the table addresss from the common internal XSDT */
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_XSDT->table_offset_entry[i]);
/*
* Get the tables needed by this subsystem (FADT and any SSDTs).
* NOTE: All other tables are completely ignored at this time.
*/
acpi_tb_get_primary_table (&address, &table_info);
}
/* We must have a FADT to continue */
if (!acpi_gbl_FADT) {
ACPI_REPORT_ERROR (("No FADT present in RSDT/XSDT\n"));
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
/*
* Convert the FADT to a common format. This allows earlier revisions of the
* table to coexist with newer versions, using common access code.
*/
status = acpi_tb_convert_table_fadt ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
return_ACPI_STATUS (status);
}
/*
* Get the FACS (Pointed to by the FADT)
*/
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_FADT->Xfirmware_ctrl);
status = acpi_tb_get_secondary_table (&address, FACS_SIG, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/*
* Create the common FACS pointer table
* (Contains pointers to the original table)
*/
status = acpi_tb_build_common_facs (&table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/*
* Get/install the DSDT (Pointed to by the FADT)
*/
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_FADT->Xdsdt);
status = acpi_tb_get_secondary_table (&address, DSDT_SIG, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get/install the DSDT\n"));
return_ACPI_STATUS (status);
}
/* Set Integer Width (32/64) based upon DSDT revision */
acpi_ut_set_integer_width (acpi_gbl_DSDT->revision);
/* Dump the entire DSDT */
ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
"Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width));
ACPI_DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);
/* Always delete the RSDP mapping, we are done with it */
acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);
return_ACPI_STATUS (status);
}
/******************************************************************************
*
* Module Name: tbinstal - ACPI table installation and removal
* $Revision: 61 $
* $Revision: 62 $
*
*****************************************************************************/
......@@ -49,7 +49,8 @@
acpi_status
acpi_tb_match_signature (
NATIVE_CHAR *signature,
acpi_table_desc *table_info)
acpi_table_desc *table_info,
u8 search_type)
{
NATIVE_UINT i;
......@@ -61,6 +62,10 @@ acpi_tb_match_signature (
* Search for a signature match among the known table types
*/
for (i = 0; i < NUM_ACPI_TABLES; i++) {
if ((acpi_gbl_acpi_table_data[i].flags & ACPI_TABLE_TYPE_MASK) != search_type) {
continue;
}
if (!ACPI_STRNCMP (signature, acpi_gbl_acpi_table_data[i].signature,
acpi_gbl_acpi_table_data[i].sig_length)) {
/* Found a signature match, return index if requested */
......@@ -69,13 +74,18 @@ acpi_tb_match_signature (
table_info->type = (u8) i;
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Signature match %4.4s\n",
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Table [%4.4s] matched and is a required ACPI table\n",
(char *) acpi_gbl_acpi_table_data[i].signature));
return_ACPI_STATUS (AE_OK);
}
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Table [%4.4s] is not a required ACPI table - ignored\n",
(char *) signature));
return_ACPI_STATUS (AE_TABLE_NOT_SUPPORTED);
}
......@@ -84,7 +94,7 @@ acpi_tb_match_signature (
*
* FUNCTION: Acpi_tb_install_table
*
* PARAMETERS: Table_info - Return value from Acpi_tb_get_table
* PARAMETERS: Table_info - Return value from Acpi_tb_get_table_body
*
* RETURN: Status
*
......@@ -103,25 +113,22 @@ acpi_tb_install_table (
ACPI_FUNCTION_TRACE ("Tb_install_table");
/*
* Check the table signature and make sure it is recognized
* Also checks the header checksum
*/
status = acpi_tb_recognize_table (table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Lock tables while installing */
status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not acquire table mutex for [%4.4s], %s\n",
table_info->pointer->signature, acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/* Install the table into the global data structure */
status = acpi_tb_init_table_descriptor (table_info->type, table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not install ACPI table [%s], %s\n",
table_info->pointer->signature, acpi_format_exception (status)));
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n",
acpi_gbl_acpi_table_data[table_info->type].name, table_info->pointer));
......@@ -135,7 +142,7 @@ acpi_tb_install_table (
*
* FUNCTION: Acpi_tb_recognize_table
*
* PARAMETERS: Table_info - Return value from Acpi_tb_get_table
* PARAMETERS: Table_info - Return value from Acpi_tb_get_table_body
*
* RETURN: Status
*
......@@ -153,7 +160,8 @@ acpi_tb_install_table (
acpi_status
acpi_tb_recognize_table (
acpi_table_desc *table_info)
acpi_table_desc *table_info,
u8 search_type)
{
acpi_table_header *table_header;
acpi_status status;
......@@ -177,7 +185,7 @@ acpi_tb_recognize_table (
* This can be any one of many valid ACPI tables, it just isn't one of
* the tables that is consumed by the core subsystem
*/
status = acpi_tb_match_signature (table_header->signature, table_info);
status = acpi_tb_match_signature (table_header->signature, table_info, search_type);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
......@@ -191,22 +199,6 @@ acpi_tb_recognize_table (
table_info->length = (ACPI_SIZE) table_header->length;
/*
* Validate checksum for _most_ tables,
* even the ones whose signature we don't recognize
*/
if (table_info->type != ACPI_TABLE_FACS) {
status = acpi_tb_verify_table_checksum (table_header);
#if (!ACPI_CHECKSUM_ABORT)
if (ACPI_FAILURE (status)) {
/* Ignore the error if configuration says so */
status = AE_OK;
}
#endif
}
return_ACPI_STATUS (status);
}
......
/******************************************************************************
*
* Module Name: tbrsdt - ACPI RSDT table utilities
* $Revision: 1 $
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2002, R. Byron Moore
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "acpi.h"
#include "actables.h"
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbrsdt")
/*******************************************************************************
*
* FUNCTION: Acpi_tb_verify_rsdp
*
* PARAMETERS: Address - RSDP (Pointer to RSDT)
*
* RETURN: Status
*
* DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
*
******************************************************************************/
acpi_status
acpi_tb_verify_rsdp (
ACPI_POINTER *address)
{
acpi_table_desc table_info;
acpi_status status;
RSDP_DESCRIPTOR *rsdp;
ACPI_FUNCTION_TRACE ("Tb_verify_rsdp");
switch (address->pointer_type) {
case ACPI_LOGICAL_POINTER:
rsdp = address->pointer.logical;
break;
case ACPI_PHYSICAL_POINTER:
/*
* Obtain access to the RSDP structure
*/
status = acpi_os_map_memory (address->pointer.physical, sizeof (RSDP_DESCRIPTOR),
(void **) &rsdp);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
break;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* The signature and checksum must both be correct
*/
if (ACPI_STRNCMP ((NATIVE_CHAR *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
/* Nope, BAD Signature */
status = AE_BAD_SIGNATURE;
goto cleanup;
}
/* Check the standard checksum */
if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
status = AE_BAD_CHECKSUM;
goto cleanup;
}
/* Check extended checksum if table version >= 2 */
if (rsdp->revision >= 2) {
if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
status = AE_BAD_CHECKSUM;
goto cleanup;
}
}
/* The RSDP supplied is OK */
table_info.pointer = ACPI_CAST_PTR (acpi_table_header, rsdp);
table_info.length = sizeof (RSDP_DESCRIPTOR);
table_info.allocation = ACPI_MEM_MAPPED;
table_info.base_pointer = rsdp;
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Save the RSDP in a global for easy access */
acpi_gbl_RSDP = ACPI_CAST_PTR (RSDP_DESCRIPTOR, table_info.pointer);
return_ACPI_STATUS (status);
/* Error exit */
cleanup:
if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) {
acpi_os_unmap_memory (rsdp, sizeof (RSDP_DESCRIPTOR));
}
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_rsdt_address
*
* PARAMETERS: None
*
* RETURN: RSDT physical address
*
* DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
* version of the RSDP
*
******************************************************************************/
void
acpi_tb_get_rsdt_address (
ACPI_POINTER *out_address)
{
ACPI_FUNCTION_ENTRY ();
out_address->pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
/*
* For RSDP revision 0 or 1, we use the RSDT.
* For RSDP revision 2 (and above), we use the XSDT
*/
if (acpi_gbl_RSDP->revision < 2) {
out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
}
else {
out_address->pointer.value = ACPI_GET_ADDRESS (acpi_gbl_RSDP->xsdt_physical_address);
}
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_validate_rsdt
*
* PARAMETERS: Table_ptr - Addressable pointer to the RSDT.
*
* RETURN: Status
*
* DESCRIPTION: Validate signature for the RSDT or XSDT
*
******************************************************************************/
acpi_status
acpi_tb_validate_rsdt (
acpi_table_header *table_ptr)
{
int no_match;
ACPI_FUNCTION_NAME ("Tb_validate_rsdt");
/*
* For RSDP revision 0 or 1, we use the RSDT.
* For RSDP revision 2 and above, we use the XSDT
*/
if (acpi_gbl_RSDP->revision < 2) {
no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG,
sizeof (RSDT_SIG) -1);
}
else {
no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG,
sizeof (XSDT_SIG) -1);
}
if (no_match) {
/* Invalid RSDT or XSDT signature */
ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
"RSDT/XSDT signature at %X (%p) is invalid\n",
acpi_gbl_RSDP->rsdt_physical_address,
(void *) (NATIVE_UINT) acpi_gbl_RSDP->rsdt_physical_address));
return (AE_BAD_SIGNATURE);
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_rsdt
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
*
******************************************************************************/
acpi_status
acpi_tb_get_table_rsdt (
void)
{
acpi_table_desc table_info;
acpi_status status;
ACPI_POINTER address;
ACPI_FUNCTION_TRACE ("Tb_get_table_rsdt");
/* Get the RSDT/XSDT via the RSDP */
acpi_tb_get_rsdt_address (&address);
status = acpi_tb_get_table (&address, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
acpi_gbl_RSDP,
ACPI_HIDWORD (address.pointer.value),
ACPI_LODWORD (address.pointer.value)));
/* Check the RSDT or XSDT signature */
status = acpi_tb_validate_rsdt (table_info.pointer);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/*
* Valid RSDT signature, verify the checksum. If it fails, just
* print a warning and ignore it.
*/
status = acpi_tb_verify_table_checksum (table_info.pointer);
/* Get the number of tables defined in the RSDT or XSDT */
acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer);
/* Convert and/or copy to an XSDT structure */
status = acpi_tb_convert_to_xsdt (&table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
acpi_gbl_XSDT = (xsdt_descriptor *) table_info.pointer;
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
return_ACPI_STATUS (status);
}
/******************************************************************************
*
* Module Name: tbutils - Table manipulation utilities
* $Revision: 54 $
* $Revision: 55 $
*
*****************************************************************************/
......@@ -121,7 +121,8 @@ acpi_tb_validate_table_header (
"Table signature at %p [%p] has invalid characters\n",
table_header, &signature));
ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n", (char *) &signature));
ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n",
(char *) &signature));
ACPI_DUMP_BUFFER (table_header, sizeof (acpi_table_header));
return (AE_BAD_SIGNATURE);
}
......@@ -133,7 +134,8 @@ acpi_tb_validate_table_header (
"Invalid length in table header %p name %4.4s\n",
table_header, (char *) &signature));
ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n", table_header->length));
ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n",
table_header->length));
ACPI_DUMP_BUFFER (table_header, sizeof (acpi_table_header));
return (AE_BAD_HEADER);
}
......@@ -142,91 +144,6 @@ acpi_tb_validate_table_header (
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_map_acpi_table
*
* PARAMETERS: Physical_address - Physical address of table to map
* *Size - Size of the table. If zero, the size
* from the table header is used.
* Actual size is returned here.
* **Logical_address - Logical address of mapped table
*
* RETURN: Logical address of the mapped table.
*
* DESCRIPTION: Maps the physical address of table into a logical address
*
******************************************************************************/
acpi_status
acpi_tb_map_acpi_table (
ACPI_PHYSICAL_ADDRESS physical_address,
ACPI_SIZE *size,
acpi_table_header **logical_address)
{
acpi_table_header *table;
ACPI_SIZE table_size = *size;
acpi_status status = AE_OK;
ACPI_FUNCTION_NAME ("Tb_map_acpi_table");
/* If size is zero, look at the table header to get the actual size */
if ((*size) == 0) {
/* Get the table header so we can extract the table length */
status = acpi_os_map_memory (physical_address, sizeof (acpi_table_header),
(void **) &table);
if (ACPI_FAILURE (status)) {
return (status);
}
/* Extract the full table length before we delete the mapping */
table_size = (ACPI_SIZE) table->length;
#if 0
/* We don't want to validate the header here. */
/*
* Validate the header and delete the mapping.
* We will create a mapping for the full table below.
*/
status = acpi_tb_validate_table_header (table);
#endif
/* Always unmap the memory for the header */
acpi_os_unmap_memory (table, sizeof (acpi_table_header));
#if 0
/* Exit if header invalid */
if (ACPI_FAILURE (status)) {
return (status);
}
#endif
}
/* Map the physical memory for the correct length */
status = acpi_os_map_memory (physical_address, table_size,
(void **) &table);
if (ACPI_FAILURE (status)) {
return (status);
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Mapped memory for ACPI table, length=%d(%X) at %p\n",
table_size, table_size, table));
*size = table_size;
*logical_address = table;
return (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_verify_table_checksum
......
......@@ -2,7 +2,7 @@
*
* Module Name: tbxface - Public interfaces to the ACPI subsystem
* ACPI table oriented interfaces
* $Revision: 57 $
* $Revision: 58 $
*
*****************************************************************************/
......@@ -52,7 +52,6 @@ acpi_load_tables (void)
{
ACPI_POINTER rsdp_address;
acpi_status status;
u32 number_of_tables = 0;
ACPI_FUNCTION_TRACE ("Acpi_load_tables");
......@@ -81,16 +80,16 @@ acpi_load_tables (void)
/* Get the RSDT via the RSDP */
status = acpi_tb_get_table_rsdt (&number_of_tables);
status = acpi_tb_get_table_rsdt ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Acpi_load_tables: Could not load RSDT: %s\n",
acpi_format_exception (status)));
goto error_exit;
}
/* Now get the rest of the tables */
/* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */
status = acpi_tb_get_all_tables (number_of_tables);
status = acpi_tb_get_required_tables ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
acpi_format_exception (status)));
......@@ -154,10 +153,10 @@ acpi_load_table (
/* Copy the table to a local buffer */
address.pointer_type = ACPI_LOGICAL_POINTER;
address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
address.pointer.logical = table_ptr;
status = acpi_tb_get_table (&address, &table_info);
status = acpi_tb_get_table_body (&address, table_ptr, &table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
......@@ -166,7 +165,7 @@ acpi_load_table (
status = acpi_tb_install_table (&table_info);
if (ACPI_FAILURE (status)) {
/* Free table allocated by Acpi_tb_get_table */
/* Free table allocated by Acpi_tb_get_table_body */
acpi_tb_delete_single_table (&table_info);
return_ACPI_STATUS (status);
......
/******************************************************************************
*
* Module Name: tbxfroot - Find the root ACPI table (RSDT)
* $Revision: 63 $
* $Revision: 64 $
*
*****************************************************************************/
......@@ -63,9 +63,9 @@ acpi_tb_find_table (
/* Validate string lengths */
if ((ACPI_STRLEN (signature) > 4) ||
(ACPI_STRLEN (oem_id) > 6) ||
(ACPI_STRLEN (oem_table_id) > 8)) {
if ((ACPI_STRLEN (signature) > ACPI_NAME_SIZE) ||
(ACPI_STRLEN (oem_id) > sizeof (table->oem_id)) ||
(ACPI_STRLEN (oem_table_id) > sizeof (table->oem_table_id))) {
return_ACPI_STATUS (AE_AML_STRING_LIMIT);
}
......@@ -96,7 +96,7 @@ acpi_tb_find_table (
* PARAMETERS: Signature - Any ACPI table signature
* Instance - the non zero instance of the table, allows
* support for multiple tables of the same type
* Flags - 0: Physical/Virtual support
* Flags - Physical/Virtual support
* Ret_buffer - pointer to a structure containing a buffer to
* receive the table
*
......@@ -120,11 +120,10 @@ acpi_get_firmware_table (
{
ACPI_POINTER rsdp_address;
ACPI_POINTER address;
acpi_table_header *rsdt_ptr = NULL;
acpi_table_header *table_ptr;
acpi_status status;
ACPI_SIZE rsdt_size = 0;
ACPI_SIZE table_size;
acpi_table_header header;
acpi_table_desc table_info;
acpi_table_desc rsdt_info;
u32 table_count;
u32 i;
u32 j;
......@@ -147,6 +146,8 @@ acpi_get_firmware_table (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
rsdt_info.pointer = NULL;
if (!acpi_gbl_RSDP) {
/* Get the RSDP */
......@@ -175,15 +176,13 @@ acpi_get_firmware_table (
if (ACPI_STRNCMP ((NATIVE_CHAR *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
/* Nope, BAD Signature */
status = AE_BAD_SIGNATURE;
goto cleanup;
return_ACPI_STATUS (AE_BAD_SIGNATURE);
}
if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
/* Nope, BAD Checksum */
status = AE_BAD_CHECKSUM;
goto cleanup;
return_ACPI_STATUS (AE_BAD_CHECKSUM);
}
}
......@@ -197,63 +196,65 @@ acpi_get_firmware_table (
ACPI_HIDWORD (address.pointer.value),
ACPI_LODWORD (address.pointer.value)));
status = acpi_tb_get_table_pointer (&address, flags, &rsdt_size, &rsdt_ptr);
/* Insert Processor_mode flags */
address.pointer_type |= flags;
status = acpi_tb_get_table (&address, &rsdt_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
status = acpi_tb_validate_rsdt (rsdt_ptr);
status = acpi_tb_validate_rsdt (rsdt_info.pointer);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Get the number of table pointers within the RSDT */
table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_ptr);
table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info.pointer);
address.pointer_type = acpi_gbl_table_flags | flags;
/*
* Search the RSDT/XSDT for the correct instance of the
* requested table
*/
for (i = 0, j = 0; i < table_count; i++) {
/* Get the next table pointer */
/* Get the next table pointer, handle RSDT vs. XSDT */
address.pointer_type = acpi_gbl_table_flags;
if (acpi_gbl_RSDP->revision < 2) {
address.pointer.value = ((RSDT_DESCRIPTOR *) rsdt_ptr)->table_offset_entry[i];
address.pointer.value = ((RSDT_DESCRIPTOR *) rsdt_info.pointer)->table_offset_entry[i];
}
else {
address.pointer.value = ACPI_GET_ADDRESS (
((xsdt_descriptor *) rsdt_ptr)->table_offset_entry[i]);
((xsdt_descriptor *) rsdt_info.pointer)->table_offset_entry[i]);
}
/* Get addressibility if necessary */
/* Get the table header */
status = acpi_tb_get_table_pointer (&address, flags, &table_size, &table_ptr);
status = acpi_tb_get_table_header (&address, &header);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Compare table signatures and table instance */
if (!ACPI_STRNCMP ((char *) table_ptr, signature, ACPI_STRLEN (signature))) {
if (!ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
/* An instance of the table was found */
j++;
if (j >= instance) {
/* Found the correct instance */
/* Found the correct instance, get the entire table */
*table_pointer = table_ptr;
status = acpi_tb_get_table_body (&address, &header, &table_info);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
}
/* Delete table mapping if using virtual addressing */
if ((table_size) &&
((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING)) {
acpi_os_unmap_memory (table_ptr, table_size);
*table_pointer = table_info.pointer;
goto cleanup;
}
}
}
......@@ -263,9 +264,7 @@ acpi_get_firmware_table (
cleanup:
if (rsdt_size) {
acpi_os_unmap_memory (rsdt_ptr, rsdt_size);
}
acpi_os_unmap_memory (rsdt_info.pointer, (ACPI_SIZE) rsdt_info.pointer->length);
return_ACPI_STATUS (status);
}
......
/*
* acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 39 $)
* acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 40 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -231,7 +231,7 @@ acpi_thermal_set_cooling_mode (
arg0.integer.value = mode;
status = acpi_evaluate(handle, NULL, &arg_list, NULL);
status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
......
/*
* toshiba_acpi.c - Toshiba Laptop ACPI Extras
*
*
* Copyright (C) 2002 John Belmonte
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* The devolpment page for this driver is located at
* http://memebeam.org/toys/ToshibaAcpiDriver.
*
* Credits:
* Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse
* engineering the Windows drivers
* Yasushi Nagato - changes for linux kernel 2.4 -> 2.5
*
*
* TODO
* provide version info in proc
* add Fn key status
*
*/
#define TOSHIBA_ACPI_VERSION "0.12"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/version.h>
#define KERNEL24 (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0))
#if KERNEL24
#include <acpi.h>
extern struct proc_dir_entry* bm_proc_root;
#define acpi_root_dir bm_proc_root
#else
#include "acpi_drivers.h"
#endif
MODULE_AUTHOR("John Belmonte");
MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver");
MODULE_LICENSE("GPL");
/* Toshiba ACPI method paths */
#define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM"
#define METHOD_HCI "\\_SB_.VALD.GHCI"
#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX"
/* Toshiba HCI interface definitions
*
* HCI is Toshiba's "Hardware Control Interface" which is supposed to
* be uniform across all their models. Ideally we would just call
* dedicated ACPI methods instead of using this primitive interface.
* However the ACPI methods seem to be incomplete in some areas (for
* example they allow setting, but not reading, the LCD brightness value),
* so this is still useful.
*/
#define HCI_WORDS 6
/* operations */
#define HCI_SET 0xff00
#define HCI_GET 0xfe00
/* return codes */
#define HCI_SUCCESS 0x0000
#define HCI_FAILURE 0x1000
#define HCI_NOT_SUPPORTED 0x8000
/* registers */
#define HCI_FAN 0x0004
#define HCI_VIDEO_OUT 0x001c
#define HCI_LCD_BRIGHTNESS 0x002a
/* field definitions */
#define HCI_LCD_BRIGHTNESS_BITS 3
#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS)
#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS)
#define HCI_VIDEO_OUT_LCD 0x1
#define HCI_VIDEO_OUT_CRT 0x2
/* utility
*/
static __inline__ void
_set_bit(u32* word, u32 mask, int value)
{
*word = (*word & ~mask) | (mask * value);
}
/* This is the common code at the end of every proc read handler. I don't
* understand it yet.
*/
static int
end_proc_read(const char* p, char* page, off_t off, int count,
char** start, int* eof)
{
int len = (p - page);
if (len <= off+count) *eof = 1;
*start = page + off;
len -= off;
if (len>count) len = count;
if (len<0) len = 0;
return len;
}
/* acpi interface wrappers
*/
static int
write_acpi_int(const char* methodName, int val)
{
acpi_object_list params;
acpi_object in_objs[1];
acpi_status status;
params.count = sizeof(in_objs)/sizeof(in_objs[0]);
params.pointer = in_objs;
in_objs[0].type = ACPI_TYPE_INTEGER;
in_objs[0].integer.value = val;
status = acpi_evaluate_object(0, (char*)methodName, &params, 0);
return (status == AE_OK);
}
#if 0
static int
read_acpi_int(const char* methodName, int* pVal)
{
acpi_buffer results;
acpi_object out_objs[1];
acpi_status status;
results.length = sizeof(out_objs);
results.pointer = out_objs;
status = acpi_evaluate_object(0, (char*)methodName, 0, &results);
*pVal = out_objs[0].integer.value;
return (status == AE_OK) && (out_objs[0].type == ACPI_TYPE_INTEGER);
}
#endif
/* Perform a raw HCI call. Here we don't care about input or output buffer
* format.
*/
static acpi_status
hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
{
acpi_object_list params;
acpi_object in_objs[HCI_WORDS];
acpi_buffer results;
acpi_object out_objs[HCI_WORDS+1];
acpi_status status;
int i;
params.count = HCI_WORDS;
params.pointer = in_objs;
for (i = 0; i < HCI_WORDS; ++i) {
in_objs[i].type = ACPI_TYPE_INTEGER;
in_objs[i].integer.value = in[i];
/*printk("%04x ", in[i]);*/
}
/*printk("\n");*/
results.length = sizeof(out_objs);
results.pointer = out_objs;
status = acpi_evaluate_object(0, METHOD_HCI, &params,
&results);
if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) {
for (i = 0; i < out_objs->package.count; ++i) {
out[i] = out_objs->package.elements[i].integer.value;
/*printk("%04x ", out[i]);*/
}
/*printk("\n");*/
}
return status;
}
/* common hci tasks (get or set one value)
*
* In addition to the ACPI status, the HCI system returns a result which
* may be useful (such as "not supported").
*/
static acpi_status
hci_write1(u32 reg, u32 in1, u32* result)
{
u32 in[HCI_WORDS] = { HCI_SET, reg, in1, 0, 0, 0 };
u32 out[HCI_WORDS];
acpi_status status = hci_raw(in, out);
*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
return status;
}
static acpi_status
hci_read1(u32 reg, u32* out1, u32* result)
{
u32 in[HCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 };
u32 out[HCI_WORDS];
acpi_status status = hci_raw(in, out);
*out1 = out[2];
*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
return status;
}
#define PROC_TOSHIBA "toshiba"
#define PROC_LCD "lcd"
#define PROC_VIDEO "video"
#define PROC_FAN "fan"
static struct proc_dir_entry* toshiba_proc_dir = NULL;
static int force_fan;
/* proc file handlers
*
* WARNING: The write handlers are using sscanf on non-zero-terminated
* buffers. This may result in memory reads past the buffer bounds.
*/
static int
proc_read_lcd(char* page, char** start, off_t off, int count, int* eof,
void* context)
{
char* p = page;
u32 hci_result;
u32 value;
if (off != 0) goto end;
hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result);
if (hci_result == HCI_SUCCESS) {
value = value >> HCI_LCD_BRIGHTNESS_SHIFT;
p += sprintf(p, "brightness: %d\n", value);
p += sprintf(p, "brightness_levels: %d\n",
HCI_LCD_BRIGHTNESS_LEVELS);
} else {
p += sprintf(p, "ERROR\n");
goto end;
}
end:
return end_proc_read(p, page, off, count, start, eof);
}
static int
proc_write_lcd(struct file* file, const char* buffer, unsigned long count,
void* data)
{
int value;
/*int byte_count;*/
u32 hci_result;
/* ISSUE: %i doesn't work with hex values as advertised */
if (sscanf(buffer, " brightness : %i", &value) == 1 &&
value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
value = value << HCI_LCD_BRIGHTNESS_SHIFT;
hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result);
if (hci_result != HCI_SUCCESS)
return -EFAULT;
} else {
return -EINVAL;
}
return count;
}
static int
proc_read_video(char* page, char** start, off_t off, int count, int* eof,
void* context)
{
char* p = page;
u32 hci_result;
u32 value;
if (off != 0) goto end;
hci_read1(HCI_VIDEO_OUT, &value, &hci_result);
if (hci_result == HCI_SUCCESS) {
int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
p += sprintf(p, "lcd_out: %d\n", is_lcd);
p += sprintf(p, "crt_out: %d\n", is_crt);
} else {
p += sprintf(p, "ERROR\n");
goto end;
}
end:
return end_proc_read(p, page, off, count, start, eof);
}
static int
proc_write_video(struct file* file, const char* buffer, unsigned long count,
void* data)
{
int value;
const char* buffer_end = buffer + count;
int lcd_out = -1;
int crt_out = -1;
u32 hci_result;
int video_out;
/* scan expression. Multiple expressions may be delimited with ; */
do {
if (sscanf(buffer, " lcd_out : %i", &value) == 1)
lcd_out = value & 1;
else if (sscanf(buffer, " crt_out : %i", &value) == 1)
crt_out = value & 1;
/* advance to one character past the next ; */
do ++buffer;
while ((buffer < buffer_end) && (*(buffer-1) != ';'));
} while (buffer < buffer_end);
hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
if (hci_result == HCI_SUCCESS) {
int new_video_out = video_out;
if (lcd_out != -1)
_set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out);
if (crt_out != -1)
_set_bit(&new_video_out, HCI_VIDEO_OUT_CRT, crt_out);
/* To avoid unnecessary video disruption, only write the new
* video setting if something changed. */
if (new_video_out != video_out)
write_acpi_int(METHOD_VIDEO_OUT, new_video_out);
}
return count;
}
static int
proc_read_fan(char* page, char** start, off_t off, int count, int* eof,
void* context)
{
char* p = page;
u32 hci_result;
u32 value;
if (off != 0) goto end;
hci_read1(HCI_FAN, &value, &hci_result);
if (hci_result == HCI_SUCCESS) {
p += sprintf(p, "running: %d\n", (value > 0));
p += sprintf(p, "force_on: %d\n", force_fan);
} else {
p += sprintf(p, "ERROR\n");
goto end;
}
end:
return end_proc_read(p, page, off, count, start, eof);
}
static int
proc_write_fan(struct file* file, const char* buffer, unsigned long count,
void* data)
{
int value;
u32 hci_result;
if (sscanf(buffer, " force_on : %i", &value) == 1 &&
value >= 0 && value <= 1) {
hci_write1(HCI_FAN, value, &hci_result);
if (hci_result != HCI_SUCCESS)
return -EFAULT;
else
force_fan = value;
} else {
return -EINVAL;
}
return count;
}
/* proc and module init
*/
static acpi_status
add_device(void)
{
struct proc_dir_entry* proc;
proc = create_proc_read_entry(PROC_LCD, S_IFREG | S_IRUGO | S_IWUSR,
toshiba_proc_dir, proc_read_lcd, 0);
if (proc) proc->write_proc = proc_write_lcd;
proc = create_proc_read_entry(PROC_VIDEO, S_IFREG | S_IRUGO | S_IWUSR,
toshiba_proc_dir, proc_read_video, 0);
if (proc) proc->write_proc = proc_write_video;
proc = create_proc_read_entry(PROC_FAN, S_IFREG | S_IRUGO | S_IWUSR,
toshiba_proc_dir, proc_read_fan, 0);
if (proc) proc->write_proc = proc_write_fan;
return(AE_OK);
}
static acpi_status
remove_device(void)
{
remove_proc_entry(PROC_LCD, toshiba_proc_dir);
remove_proc_entry(PROC_VIDEO, toshiba_proc_dir);
remove_proc_entry(PROC_FAN, toshiba_proc_dir);
return(AE_OK);
}
static int __init
toshiba_acpi_init(void)
{
acpi_status status = AE_OK;
int value;
u32 hci_result;
/* simple device detection: try reading an HCI register */
hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result);
if (hci_result != HCI_SUCCESS)
return -ENODEV;
printk("Toshiba Laptop ACPI Extras version %s\n", TOSHIBA_ACPI_VERSION);
force_fan = 0;
toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir);
if (!toshiba_proc_dir) {
status = AE_ERROR;
} else {
status = add_device();
if (ACPI_FAILURE(status))
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
}
return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
}
static void __exit
toshiba_acpi_exit(void)
{
remove_device();
if (toshiba_proc_dir)
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
return;
}
module_init(toshiba_acpi_init);
module_exit(toshiba_acpi_exit);
/******************************************************************************
*
* Module Name: utcopy - Internal to external object translation utilities
* $Revision: 101 $
* $Revision: 103 $
*
*****************************************************************************/
......@@ -286,19 +286,21 @@ acpi_ut_copy_ipackage_to_epackage (
/*
* Free space begins right after the first package
*/
info.length = 0;
info.length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
info.object_space = 0;
info.num_packages = 1;
info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
external_object->package.count = internal_object->package.count;
external_object->package.elements = ACPI_CAST_PTR (acpi_object, info.free_space);
/*
* Build an array of ACPI_OBJECTS in the buffer
* Leave room for an array of ACPI_OBJECTS in the buffer
* and move the free space past it
*/
info.length += (ACPI_SIZE) external_object->package.count *
ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
info.free_space += external_object->package.count *
ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
......@@ -517,7 +519,6 @@ acpi_ut_copy_epackage_to_ipackage (
external_object->package.count = internal_object->package.count;
external_object->package.elements = (acpi_object *)free_space;
/*
* Build an array of ACPI_OBJECTS in the buffer
* and move the free space past it
......
/******************************************************************************
*
* Module Name: utglobal - Global variables for the ACPI subsystem
* $Revision: 163 $
* $Revision: 164 $
*
*****************************************************************************/
......@@ -286,15 +286,15 @@ acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
ACPI_TABLE_SUPPORT acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] =
{
/*********** Name, Signature, Global typed pointer Signature size, How many allowed?, Contains valid AML? */
/* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_SINGLE},
/* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void **) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE},
/* FADT 2 */ {FADT_SIG, FADT_SIG, (void **) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_SINGLE},
/* FACS 3 */ {FACS_SIG, FACS_SIG, (void **) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SINGLE},
/* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
/* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
/* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof (RSDT_SIG)-1, ACPI_TABLE_SINGLE},
/*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */
/* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE},
/* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void **) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE},
/* FADT 2 */ {FADT_SIG, FADT_SIG, (void **) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE},
/* FACS 3 */ {FACS_SIG, FACS_SIG, (void **) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE},
/* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
/* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
/* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof (RSDT_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE},
};
......
/******************************************************************************
*
* Module Name: utxface - External interfaces for "global" ACPI functions
* $Revision: 96 $
* $Revision: 97 $
*
*****************************************************************************/
......@@ -192,6 +192,31 @@ acpi_enable_subsystem (
}
}
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_initialize_objects
*
* PARAMETERS: Flags - Init/enable Options
*
* RETURN: Status
*
* DESCRIPTION: Completes namespace initialization by initializing device
* objects and executing AML code for Regions, buffers, etc.
*
******************************************************************************/
acpi_status
acpi_initialize_objects (
u32 flags)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE ("Acpi_initialize_objects");
/*
* Initialize all device objects in the namespace
* This runs the _STA and _INI methods.
......
/*
* acpi_utils.c - ACPI Utility Functions ($Revision: 7 $)
* acpi_utils.c - ACPI Utility Functions ($Revision: 10 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -235,59 +235,6 @@ acpi_extract_package (
}
acpi_status
acpi_evaluate (
acpi_handle handle,
acpi_string pathname,
acpi_object_list *arguments,
acpi_buffer *buffer)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE("acpi_evaluate");
/* If caller provided a buffer it must be unallocated/zero'd. */
if (buffer && (buffer->length != 0 || buffer->pointer))
return_ACPI_STATUS(AE_BAD_PARAMETER);
/*
* Evalute object. The first attempt is just to get the size of the
* object data (that is unless there's no return data); the second
* gets the data.
*/
status = acpi_evaluate_object(handle, pathname, arguments, buffer);
if (ACPI_SUCCESS(status)) {
return_ACPI_STATUS(status);
}
else if (buffer && (status == AE_BUFFER_OVERFLOW)) {
/* Gotta allocate - CALLER MUST FREE! */
buffer->pointer = kmalloc(buffer->length, GFP_KERNEL);
if (!buffer->pointer) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
memset(buffer->pointer, 0, buffer->length);
/* Re-evaluate - this time it should work. */
status = acpi_evaluate_object(handle, pathname, arguments,
buffer);
}
if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND)
acpi_util_eval_error(handle, pathname, status);
if (buffer && buffer->pointer) {
kfree(buffer->pointer);
buffer->length = 0;
}
}
return_ACPI_STATUS(status);
}
acpi_status
acpi_evaluate_integer (
acpi_handle handle,
......@@ -366,6 +313,8 @@ acpi_evaluate_string (
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data));
acpi_os_free(buffer.pointer);
return_ACPI_STATUS(AE_OK);
}
#endif
......@@ -381,7 +330,7 @@ acpi_evaluate_reference (
acpi_status status = AE_OK;
acpi_object *package = NULL;
acpi_object *element = NULL;
acpi_buffer buffer = {0, NULL};
acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
u32 i = 0;
ACPI_FUNCTION_TRACE("acpi_evaluate_reference");
......@@ -392,42 +341,53 @@ acpi_evaluate_reference (
/* Evaluate object. */
status = acpi_evaluate(handle, pathname, arguments, &buffer);
status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
if (ACPI_FAILURE(status))
goto end;
package = (acpi_object *) buffer.pointer;
if (!package || (package->type != ACPI_TYPE_PACKAGE)
|| (package->package.count == 0)) {
if ((buffer.length == 0) || !package) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"No return object (len %X ptr %p)\n",
buffer.length, package));
status = AE_BAD_DATA;
acpi_util_eval_error(handle, pathname, status);
goto end;
}
if (package->type != ACPI_TYPE_PACKAGE) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Expecting a [Package], found type %X\n",
package->type));
status = AE_BAD_DATA;
acpi_util_eval_error(handle, pathname, status);
goto end;
}
if (!package->package.count) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"[Package] has zero elements (%p)\n",
package));
status = AE_BAD_DATA;
acpi_util_eval_error(handle, pathname, status);
goto end;
}
/* Allocate list - CALLER MUST FREE! */
list->count = package->package.count;
if (list->count > 10) {
if (package->package.count > ACPI_MAX_HANDLES) {
return AE_NO_MEMORY;
}
/* TBD: dynamically allocate */
/*
list->handles = kmalloc(sizeof(acpi_handle)*(list->count), GFP_KERNEL);
if (!list->handles) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
memset(list->handles, 0, sizeof(acpi_handle)*(list->count));
*/
list->count = package->package.count;
/* Parse package data. */
/* Extract package data. */
for (i = 0; i < list->count; i++) {
element = &(package->package.elements[i]);
if (!element || (element->type != ACPI_TYPE_ANY)) {
if (element->type != ACPI_TYPE_ANY) {
status = AE_BAD_DATA;
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid element in package (not a device reference)\n"));
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Expecting a [Reference] package element, found type %X\n",
element->type));
acpi_util_eval_error(handle, pathname, status);
break;
}
......@@ -435,7 +395,8 @@ acpi_evaluate_reference (
/* Get the acpi_handle. */
list->handles[i] = element->reference.handle;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resolved reference [%s]->[%p]\n", element->string.pointer, list->handles[i]));
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n",
list->handles[i]));
}
end:
......@@ -444,7 +405,7 @@ acpi_evaluate_reference (
//kfree(list->handles);
}
kfree(buffer.pointer);
acpi_os_free(buffer.pointer);
return_ACPI_STATUS(status);
}
......
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