diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-07-14 03:42:40 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-07-14 03:42:40 -0700 |
| commit | 2a5cc977515725d409ade211b120891f1d23b3d4 (patch) | |
| tree | 860f1eaefe5adde3f90941ffd093a61aa2141577 /drivers | |
| parent | 72785ef74af0ec8afc1c344981ca9ba609796f5d (diff) | |
| parent | 3469e90143ba6f56fcbbcd6e06537433c134480c (diff) | |
Merge http://linux-acpi.bkbits.net/linux-acpi
into home.transmeta.com:/home/torvalds/v2.5/linux
Diffstat (limited to 'drivers')
67 files changed, 2587 insertions, 1176 deletions
diff --git a/drivers/acpi/Config.help b/drivers/acpi/Config.help index 95ba5bb48dd8..4f4f0ffe4524 100644 --- a/drivers/acpi/Config.help +++ b/drivers/acpi/Config.help @@ -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. diff --git a/drivers/acpi/Config.in b/drivers/acpi/Config.in index 7aaccceb64c5..223cbc33bb14 100644 --- a/drivers/acpi/Config.in +++ b/drivers/acpi/Config.in @@ -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 diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 5a62ba40c419..189443a1eb2c 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -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 diff --git a/drivers/acpi/acpi_bus.h b/drivers/acpi/acpi_bus.h index f0221075857f..a51829cfdddb 100644 --- a/drivers/acpi/acpi_bus.h +++ b/drivers/acpi/acpi_bus.h @@ -1,5 +1,5 @@ /* - * 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 *); diff --git a/drivers/acpi/acpi_drivers.h b/drivers/acpi/acpi_drivers.h index 62c005b87231..d7a3c8066ab0 100644 --- a/drivers/acpi/acpi_drivers.h +++ b/drivers/acpi/acpi_drivers.h @@ -1,5 +1,5 @@ /* - * 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); diff --git a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c index 219553dffaa0..f67a090c3fee 100644 --- a/drivers/acpi/acpi_ksyms.c +++ b/drivers/acpi/acpi_ksyms.c @@ -1,5 +1,5 @@ /* - * 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); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 13c6f9293c23..6684da84decd 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1,5 +1,5 @@ /* - * 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); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9112291f75d8..900cbe0de6b2 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1,5 +1,5 @@ /* - * 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,11 +1052,17 @@ 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,116 +1935,99 @@ 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 - * ACPI namespace. + * Install drivers required for proper enumeration of the + * ACPI namespace. */ acpi_system_init(); /* ACPI System */ acpi_power_init(); /* ACPI Bus Power Management */ @@ -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); } diff --git a/drivers/acpi/debugger/dbdisasm.c b/drivers/acpi/debugger/dbdisasm.c index bd65226da239..610b0e8048ea 100644 --- a/drivers/acpi/debugger/dbdisasm.c +++ b/drivers/acpi/debugger/dbdisasm.c @@ -1,7 +1,7 @@ /******************************************************************************* * * 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; diff --git a/drivers/acpi/debugger/dbdisply.c b/drivers/acpi/debugger/dbdisply.c index 6ae4cca6fc50..96fd866826a9 100644 --- a/drivers/acpi/debugger/dbdisply.c +++ b/drivers/acpi/debugger/dbdisply.c @@ -1,7 +1,7 @@ /******************************************************************************* * * 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,7 +341,8 @@ acpi_db_decode_internal_object ( default: - /* No additional display for other types */ + + acpi_os_printf ("%p", obj_desc); break; } } @@ -344,6 +350,38 @@ acpi_db_decode_internal_object ( /******************************************************************************* * + * 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 * * PARAMETERS: Obj_desc - Object to be displayed @@ -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_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); diff --git a/drivers/acpi/debugger/dbexec.c b/drivers/acpi/debugger/dbexec.c index 08bcb7ec3fa4..2fd69f6836a0 100644 --- a/drivers/acpi/debugger/dbexec.c +++ b/drivers/acpi/debugger/dbexec.c @@ -1,7 +1,7 @@ /******************************************************************************* * * 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); diff --git a/drivers/acpi/debugger/dbfileio.c b/drivers/acpi/debugger/dbfileio.c index ee7a0d0fadb4..d9c7406c7f0c 100644 --- a/drivers/acpi/debugger/dbfileio.c +++ b/drivers/acpi/debugger/dbfileio.c @@ -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)) { diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 094ba815e04b..43ae10c03cd1 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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; diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index b9932cd1bc4c..a78f428efe25 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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; diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 6a6d5581f46d..c73bbcaf6213 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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); - } } diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 0f5af0be3e24..3dba2994bd6a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1,5 +1,5 @@ /* - * 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); } @@ -704,6 +725,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) { int result = 0; @@ -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; } diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 9b11d9d4325e..f403300f6ded 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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 */ diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 7cb741f95d95..49c68d410a68 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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 */ diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 4e0efea22b28..3102139f409d 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes - * $Revision: 106 $ + * $Revision: 107 $ * *****************************************************************************/ @@ -39,8 +39,9 @@ * * FUNCTION: Acpi_ex_get_object_reference * - * PARAMETERS: Obj_desc - Create a reference to this object - * Return_desc - Where to store the reference + * 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); } diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index 497e7e18933e..688e2b80c892 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c @@ -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 */ diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index 02361f1fba0d..67f29f7c3beb 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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; } diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c index d4917693b3f8..6e970603016f 100644 --- a/drivers/acpi/executer/exresnte.c +++ b/drivers/acpi/executer/exresnte.c @@ -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); diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index e3a7c6b25455..8c7993fe1b3a 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/executer/exresolv.c @@ -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; diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index 531b0d305e4f..b6ce0461900e 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c @@ -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: diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 83cee00d5dfa..4de933e0eb27 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c @@ -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" */ diff --git a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h index e313fb11bbff..3987706d5ecf 100644 --- a/drivers/acpi/include/acconfig.h +++ b/drivers/acpi/include/acconfig.h @@ -1,7 +1,7 @@ /****************************************************************************** * * 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 */ diff --git a/drivers/acpi/include/acdebug.h b/drivers/acpi/include/acdebug.h index cdeccc3e73d8..e76ad4b956fc 100644 --- a/drivers/acpi/include/acdebug.h +++ b/drivers/acpi/include/acdebug.h @@ -1,7 +1,7 @@ /****************************************************************************** * * 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); diff --git a/drivers/acpi/include/acglobal.h b/drivers/acpi/include/acglobal.h index 6c01afbcecf8..1d10c1b4203a 100644 --- a/drivers/acpi/include/acglobal.h +++ b/drivers/acpi/include/acglobal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * 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; diff --git a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h index a0a355102e8c..54eb05fc66c8 100644 --- a/drivers/acpi/include/aclocal.h +++ b/drivers/acpi/include/aclocal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * 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 diff --git a/drivers/acpi/include/acparser.h b/drivers/acpi/include/acparser.h index 2d4ee6bbe70f..b565650d0e12 100644 --- a/drivers/acpi/include/acparser.h +++ b/drivers/acpi/include/acparser.h @@ -1,7 +1,7 @@ /****************************************************************************** * * 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, diff --git a/drivers/acpi/include/acpixf.h b/drivers/acpi/include/acpixf.h index 8bf74d31072e..4340ba6a9a73 100644 --- a/drivers/acpi/include/acpixf.h +++ b/drivers/acpi/include/acpixf.h @@ -44,6 +44,10 @@ acpi_enable_subsystem ( u32 flags); acpi_status +acpi_initialize_objects ( + u32 flags); + +acpi_status acpi_terminate ( void); diff --git a/drivers/acpi/include/actables.h b/drivers/acpi/include/actables.h index bec0094bebef..0ac896455faf 100644 --- a/drivers/acpi/include/actables.h +++ b/drivers/acpi/include/actables.h @@ -1,7 +1,7 @@ /****************************************************************************** * * 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 @@ -79,11 +96,6 @@ acpi_tb_get_table_ptr ( 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 ( @@ -190,12 +203,6 @@ acpi_tb_find_table ( 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); diff --git a/drivers/acpi/include/actbl.h b/drivers/acpi/include/actbl.h index ce729fcd78c6..dc29ecc31e6c 100644 --- a/drivers/acpi/include/actbl.h +++ b/drivers/acpi/include/actbl.h @@ -1,7 +1,7 @@ /****************************************************************************** * * 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 */ diff --git a/drivers/acpi/include/actypes.h b/drivers/acpi/include/actypes.h index bb146cabf359..36388095e5b8 100644 --- a/drivers/acpi/include/actypes.h +++ b/drivers/acpi/include/actypes.h @@ -1,7 +1,7 @@ /****************************************************************************** * * 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 /* diff --git a/drivers/acpi/include/amlresrc.h b/drivers/acpi/include/amlresrc.h new file mode 100644 index 000000000000..d8aa2befb2c1 --- /dev/null +++ b/drivers/acpi/include/amlresrc.h @@ -0,0 +1,512 @@ + +/****************************************************************************** + * + * 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 + diff --git a/drivers/acpi/include/platform/aclinux.h b/drivers/acpi/include/platform/aclinux.h index 8e405f38a872..9b48ebe18edb 100644 --- a/drivers/acpi/include/platform/aclinux.h +++ b/drivers/acpi/include/platform/aclinux.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: aclinux.h - OS specific defines, etc. - * $Revision: 25 $ + * $Revision: 26 $ * *****************************************************************************/ diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index cb4a3474a916..04daed52ac83 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -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))); } } diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index 149a713dc38f..cfbb32ba5779 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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 */ diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index cf51ec2129cc..223e5c9f41b1 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -1,7 +1,7 @@ /******************************************************************************* * * 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); } diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 03cbd7886bff..985deb64cbeb 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1,5 +1,5 @@ /* - * 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)) { - iomem = 1; - virt_addr = ioremap(phys_addr,width); - } - else + 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); #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 = (void *)(dpc+1); + INIT_TQUEUE(task, acpi_os_schedule_exec, (void*)dpc); - task.routine = acpi_os_schedule_exec; - task.data = (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 diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 18d3b6f4882a..0e24c31c6135 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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), diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c index d556abe96fb6..d8df196e3080 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/parser/psutils.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psutils - Parser miscellaneous utilities (Parser only) - * $Revision: 51 $ + * $Revision: 52 $ * *****************************************************************************/ @@ -27,6 +27,7 @@ #include "acpi.h" #include "acparser.h" #include "amlcode.h" +#include "acnamesp.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME ("psutils") @@ -34,6 +35,36 @@ /******************************************************************************* * + * 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 * * PARAMETERS: Op - A newly allocated Op object diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index fa5ef392a3f9..c8b68ebebd7c 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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); } diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 064fd36d6c05..a2b1cd595057 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -1,5 +1,5 @@ /* - * 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,13 +339,18 @@ 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)); diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index b4da3eddf62e..2320a8e016bd 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -1,5 +1,5 @@ /* - * 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; } @@ -435,8 +439,8 @@ acpi_pci_link_check (void) acpi_irq_penalty[link->irq.active] += 100; printk(PREFIX "%s [%s] enabled at IRQ %d\n", - acpi_device_name(link->device), - acpi_device_bid(link->device), irq); + acpi_device_name(link->device), + acpi_device_bid(link->device), link->irq.active); } return_VALUE(0); diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 82799081c55f..7fef16be6d47 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -1,5 +1,5 @@ /* - * 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); } diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 77f84ea5af05..5e4f55dbfc90 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -1,5 +1,5 @@ /* - * 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); diff --git a/drivers/acpi/processor.c b/drivers/acpi/processor.c index 4817e43fb488..3d5fb04358af 100644 --- a/drivers/acpi/processor.c +++ b/drivers/acpi/processor.c @@ -1,5 +1,5 @@ /* - * 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); diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 21f77402d788..6347b7ec1a46 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -1,7 +1,7 @@ /******************************************************************************* * * 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 @@ -244,7 +242,7 @@ acpi_rs_create_pci_routing_table ( case INTERNAL_TYPE_REFERENCE: if ((*sub_object_list)->reference.opcode != AML_INT_NAMEPATH_OP) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need name, found reference op %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Need name, found reference op %X\n", (*sub_object_list)->reference.opcode)); return_ACPI_STATUS (AE_BAD_DATA); } diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index 67bf92135ba0..11b2382e6ec2 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c @@ -1,7 +1,7 @@ /******************************************************************************* * * 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); } diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 6ef919942e02..5366f27dcad7 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c @@ -1,7 +1,7 @@ /******************************************************************************* * * 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); } } diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 28bb26bb5297..6617ee0984ca 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -1,7 +1,7 @@ /******************************************************************************* * * 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; diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index d69a1fa2881f..3c5eb0d421ef 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -1,5 +1,5 @@ /* - * 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; diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c index bc995a1efe5e..882b116c2c27 100644 --- a/drivers/acpi/tables/tbconvrt.c +++ b/drivers/acpi/tables/tbconvrt.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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]); diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c index 1b40b2813214..a5ce316b3d5c 100644 --- a/drivers/acpi/tables/tbget.c +++ b/drivers/acpi/tables/tbget.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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. - */ - size = SIZE_IN_HEADER; - - 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; - + /* + * Attempt table override. + */ + status = acpi_tb_table_override (header, table_info); + if (ACPI_SUCCESS (status)) { + /* Table was overridden by the host OS */ - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); + return_ACPI_STATUS (status); } - /* 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]); - - status = acpi_tb_get_table (&address, &table_info); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + ACPI_FUNCTION_TRACE ("Tb_table_override"); - /* 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_FUNCTION_TRACE ("Tb_verify_rsdp"); - - - switch (address->pointer_type) { - case ACPI_LOGICAL_POINTER: + acpi_table_header *full_table = NULL; + u8 allocation; + acpi_status status = AE_OK; - 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; + ACPI_FUNCTION_TRACE ("Tb_get_this_table"); - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); - } /* - * The signature and checksum must both be correct + * Flags contains the current processor mode (Virtual or Physical addressing) + * The Pointer_type is either Logical or Physical */ - 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; - } + switch (address->pointer_type) { + case ACPI_PHYSMODE_PHYSPTR: + case ACPI_LOGMODE_LOGPTR: - /* Check extended checksum if table version >= 2 */ + /* Pointer matches processor mode, copy the table to a new buffer */ - if (rsdp->revision >= 2) { - if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) { - status = AE_BAD_CHECKSUM; - goto cleanup; + 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); } - } - - /* 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; - - /* - * 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); - } -} + /* 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 - */ - 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); - } + /* + * Just map the table's physical memory + * into our address space. + */ + 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; + if (table_info->type != ACPI_TABLE_FACS) { + status = acpi_tb_verify_table_checksum (full_table); - case ACPI_LOGICAL_POINTER: - - *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); +} diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c new file mode 100644 index 000000000000..cd61c0f52fc2 --- /dev/null +++ b/drivers/acpi/tables/tbgetall.c @@ -0,0 +1,290 @@ +/****************************************************************************** + * + * 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); +} + + diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 6d02e5702e32..700faea35638 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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); } diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c new file mode 100644 index 000000000000..9aa4f425f2c2 --- /dev/null +++ b/drivers/acpi/tables/tbrsdt.c @@ -0,0 +1,304 @@ +/****************************************************************************** + * + * 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); +} + + diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 7684b6913dd2..616a81b2d7ee 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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); } @@ -144,91 +146,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 * * PARAMETERS: *Table_header - ACPI table to verify diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 99de3856c5ee..60516f89dd72 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -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); diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index f49b2bbdbcc1..6f3d2189ac15 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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,64 +196,66 @@ 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; + } + + *table_pointer = table_info.pointer; 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); - } } /* Did not find the table */ @@ -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); } diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 6c7d35db5275..0836b31843ca 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -1,5 +1,5 @@ /* - * 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); diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c new file mode 100644 index 000000000000..48f3b32dbfa9 --- /dev/null +++ b/drivers/acpi/toshiba_acpi.c @@ -0,0 +1,465 @@ +/* + * 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, ¶ms, 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, ¶ms, + &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); diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 662f558a75ee..b5715007038d 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: utcopy - Internal to external object translation utilities - * $Revision: 101 $ + * $Revision: 103 $ * *****************************************************************************/ @@ -286,21 +286,23 @@ 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); + 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)); + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object)); status = acpi_ut_walk_package_tree (internal_object, external_object, acpi_ut_copy_ielement_to_eelement, &info); @@ -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 diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index d9d74956815a..3641d106b886 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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}, }; diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index df3a71f5d57c..69e0e8f4f749 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c @@ -1,7 +1,7 @@ /****************************************************************************** * * 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. diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 012addb8c7bb..f641ed61f2ed 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -1,5 +1,5 @@ /* - * 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> @@ -236,59 +236,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, acpi_string pathname, @@ -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 @@ end: //kfree(list->handles); } - kfree(buffer.pointer); + acpi_os_free(buffer.pointer); return_ACPI_STATUS(status); } |
