From c5f0231ee6b0441e4c45f461f2b6652b10195494 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 6 Aug 2010 08:57:53 +0800 Subject: ACPICA: Fix acpi_os_read_pci_configuration prototype Prototype in acpiosxf.h had the output value pointer as a (u32 *). Should be a (u64 *). Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 8819d2a..de17e10 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -353,7 +353,6 @@ acpi_ex_pci_config_space_handler(u32 function, acpi_status status = AE_OK; struct acpi_pci_id *pci_id; u16 pci_register; - u32 value32; ACPI_FUNCTION_TRACE(ex_pci_config_space_handler); @@ -381,8 +380,7 @@ acpi_ex_pci_config_space_handler(u32 function, case ACPI_READ: status = acpi_os_read_pci_configuration(pci_id, pci_register, - &value32, bit_width); - *value = value32; + value, bit_width); break; case ACPI_WRITE: diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 65b25a3..a351291 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -547,9 +547,10 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) acpi_status acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, - u32 *value, u32 width) + u64 *value, u32 width) { int result, size; + u32 value32; if (!value) return AE_BAD_PARAMETER; @@ -570,7 +571,8 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, result = raw_pci_read(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), - reg, size, value); + reg, size, &value32); + *value = value32; return (result ? AE_ERROR : AE_OK); } @@ -626,7 +628,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &temp); if (ACPI_SUCCESS(status)) { - u32 val; + u64 val; pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp)); pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp)); diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 29bf945..5e22577 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -223,7 +223,7 @@ acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width); */ acpi_status acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, - u32 reg, u32 *value, u32 width); + u32 reg, u64 *value, u32 width); acpi_status acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, -- cgit v0.10.2 From 09387b43153953006471dbb06ece6bf779d10937 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 6 Aug 2010 09:09:33 +0800 Subject: ACPICA: Revert "Revert "Enable multi-byte EC transfers This reverts commit f23b9c7(http://git.moblin.org/cgit.cgi/acpica/commit/?id=f23b9c7) The problem with this change was determined to be a problem with the FreeBSD host OSL (OS services layer), not with this patch itself. Therefore, re-introducing this change into the main ACPICA code. See ACPICA bugzilla 863. http://www.acpica.org/bugzilla/show_bug.cgi?id=863 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 54857fa..bdbfaf22b 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -248,7 +248,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO}; u32 base_byte_offset; /* Byte offset within containing object */\ u32 value; /* Value to store into the Bank or Index register */\ u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ - u8 access_bit_width; /* Read/Write size in bits (8-64) */ + struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */ diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 0472173..38293fd 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -119,8 +119,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, } /* - * Exit now for SMBus or IPMI address space, it has a non-linear address space - * and the request cannot be directly validated + * Exit now for SMBus or IPMI address space, it has a non-linear + * address space and the request cannot be directly validated */ if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { @@ -147,8 +147,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, * (Region length is specified in bytes) */ if (rgn_desc->region.length < - (obj_desc->common_field.base_byte_offset + - field_datum_byte_offset + + (obj_desc->common_field.base_byte_offset + field_datum_byte_offset + obj_desc->common_field.access_byte_width)) { if (acpi_gbl_enable_interpreter_slack) { /* @@ -680,6 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, u32 buffer_tail_bits; u32 datum_count; u32 field_datum_count; + u32 access_bit_width; u32 i; ACPI_FUNCTION_TRACE(ex_extract_from_field); @@ -694,16 +694,36 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_BUFFER_OVERFLOW); } + ACPI_MEMSET(buffer, 0, buffer_length); + access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); + + /* Handle the simple case here */ + + if ((obj_desc->common_field.start_field_bit_offset == 0) && + (obj_desc->common_field.bit_length == access_bit_width)) { + status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ); + return_ACPI_STATUS(status); + } + +/* TBD: Move to common setup code */ + + /* Field algorithm is limited to sizeof(u64), truncate if needed */ + + if (obj_desc->common_field.access_byte_width > sizeof(u64)) { + obj_desc->common_field.access_byte_width = sizeof(u64); + access_bit_width = sizeof(u64) * 8; + } /* Compute the number of datums (access width data items) */ - datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, - obj_desc->common_field.access_bit_width); + datum_count = + ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, + access_bit_width); + field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + obj_desc->common_field. start_field_bit_offset, - obj_desc->common_field. access_bit_width); /* Priming read from the field */ @@ -738,12 +758,11 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, * This avoids the differences in behavior between different compilers * concerning shift values larger than the target data width. */ - if ((obj_desc->common_field.access_bit_width - - obj_desc->common_field.start_field_bit_offset) < + if (access_bit_width - + obj_desc->common_field.start_field_bit_offset < ACPI_INTEGER_BIT_SIZE) { merged_datum |= - raw_datum << (obj_desc->common_field. - access_bit_width - + raw_datum << (access_bit_width - obj_desc->common_field. start_field_bit_offset); } @@ -765,8 +784,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, /* Mask off any extra bits in the last datum */ - buffer_tail_bits = obj_desc->common_field.bit_length % - obj_desc->common_field.access_bit_width; + buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width; if (buffer_tail_bits) { merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); } @@ -798,6 +816,7 @@ acpi_status acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { + void *new_buffer; acpi_status status; u64 mask; u64 width_mask; @@ -808,9 +827,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, u32 buffer_tail_bits; u32 datum_count; u32 field_datum_count; - u32 i; + u32 access_bit_width; u32 required_length; - void *new_buffer; + u32 i; ACPI_FUNCTION_TRACE(ex_insert_into_field); @@ -844,17 +863,24 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, buffer_length = required_length; } +/* TBD: Move to common setup code */ + + /* Algo is limited to sizeof(u64), so cut the access_byte_width */ + if (obj_desc->common_field.access_byte_width > sizeof(u64)) { + obj_desc->common_field.access_byte_width = sizeof(u64); + } + + access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); + /* * Create the bitmasks used for bit insertion. * Note: This if/else is used to bypass compiler differences with the * shift operator */ - if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) { + if (access_bit_width == ACPI_INTEGER_BIT_SIZE) { width_mask = ACPI_UINT64_MAX; } else { - width_mask = - ACPI_MASK_BITS_ABOVE(obj_desc->common_field. - access_bit_width); + width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width); } mask = width_mask & @@ -863,12 +889,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, /* Compute the number of datums (access width data items) */ datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, - obj_desc->common_field.access_bit_width); + access_bit_width); field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + obj_desc->common_field. start_field_bit_offset, - obj_desc->common_field. access_bit_width); /* Get initial Datum from the input buffer */ @@ -905,12 +930,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, * This avoids the differences in behavior between different compilers * concerning shift values larger than the target data width. */ - if ((obj_desc->common_field.access_bit_width - + if ((access_bit_width - obj_desc->common_field.start_field_bit_offset) < ACPI_INTEGER_BIT_SIZE) { merged_datum = - raw_datum >> (obj_desc->common_field. - access_bit_width - + raw_datum >> (access_bit_width - obj_desc->common_field. start_field_bit_offset); } else { @@ -929,6 +953,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); + merged_datum |= raw_datum << obj_desc->common_field.start_field_bit_offset; } @@ -937,7 +962,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, buffer_tail_bits = (obj_desc->common_field.bit_length + obj_desc->common_field.start_field_bit_offset) % - obj_desc->common_field.access_bit_width; + access_bit_width; if (buffer_tail_bits) { mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); } diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 98a331d..7aae29f 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -355,12 +355,10 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } - /* Setup width (access granularity) fields */ + /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */ obj_desc->common_field.access_byte_width = (u8) - ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */ - - obj_desc->common_field.access_bit_width = (u8) access_bit_width; + ACPI_DIV_8(access_bit_width); /* * base_byte_offset is the address of the start of the field within the @@ -405,8 +403,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) { union acpi_operand_object *obj_desc; union acpi_operand_object *second_desc = NULL; - u32 type; acpi_status status; + u32 access_byte_width; + u32 type; ACPI_FUNCTION_TRACE(ex_prep_field_value); @@ -421,8 +420,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) type = acpi_ns_get_type(info->region_node); if (type != ACPI_TYPE_REGION) { ACPI_ERROR((AE_INFO, - "Needed Region, found type 0x%X (%s)", - type, acpi_ut_get_type_name(type))); + "Needed Region, found type 0x%X (%s)", type, + acpi_ut_get_type_name(type))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -438,7 +437,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) /* Initialize areas of the object that are common to all fields */ obj_desc->common_field.node = info->field_node; - status = acpi_ex_prep_common_field_object(obj_desc, info->field_flags, + status = acpi_ex_prep_common_field_object(obj_desc, + info->field_flags, info->attribute, info->field_bit_position, info->field_bit_length); @@ -455,26 +455,25 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) obj_desc->field.region_obj = acpi_ns_get_attached_object(info->region_node); - /* An additional reference for the container */ + /* Allow full data read from EC address space */ - acpi_ut_add_reference(obj_desc->field.region_obj); + if ((obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_EC) + && (obj_desc->common_field.bit_length > 8)) { + access_byte_width = + ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field. + bit_length); + + /* Maximum byte width supported is 255 */ - /* allow full data read from EC address space */ - if (obj_desc->field.region_obj->region.space_id == - ACPI_ADR_SPACE_EC) { - if (obj_desc->common_field.bit_length > 8) { - unsigned width = - ACPI_ROUND_BITS_UP_TO_BYTES( - obj_desc->common_field.bit_length); - // access_bit_width is u8, don't overflow it - if (width > 8) - width = 8; + if (access_byte_width < 256) { obj_desc->common_field.access_byte_width = - width; - obj_desc->common_field.access_bit_width = - 8 * width; + (u8)access_byte_width; } } + /* An additional reference for the container */ + + acpi_ut_add_reference(obj_desc->field.region_obj); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", -- cgit v0.10.2 From b0ed7a915abac309fcb5a51bccd3782e3daa7417 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Fri, 6 Aug 2010 09:35:51 +0800 Subject: ACPICA/ACPI: Add new host interfaces for _OSI support Adds install/remove interfaces so that the host can dynamically alter the global _OSI table. Also adds support for _OSI handlers. Additional support: new debugger command (osi), and test support in the acpiexec utility. Adds new file, utilities/utosi.c. ACPICA bugzilla 836. The Linux OSL _OSI code is also changed. acpi_osi_setup can't call acpi_install/remove_interface because ACPICA is not initialized yet at this early time. So we just save the osi string in acpi_osi_setup and will handle it later in a new function acpi_osi_setup_late. http://www.acpica.org/bugzilla/show_bug.cgi?id=836 Signed-off-by: Lin Ming Signed-off-by: Bob Moore diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index d93cc06..262903e 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -44,4 +44,5 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ - utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o + utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \ + utosi.o diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 48faf3e..72e9d5e 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -105,6 +105,8 @@ void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg); acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg); +void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg); + acpi_status acpi_db_find_name_in_namespace(char *name_arg); void acpi_db_set_scope(char *name); diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 1d19214..fe50f57 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -187,6 +187,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width; ACPI_EXTERN u8 acpi_gbl_integer_byte_width; ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; +/* Mutex for _OSI support */ + +ACPI_EXTERN acpi_mutex acpi_gbl_osi_mutex; + /* Reader/Writer lock is used for namespace walk and dynamic table unload */ ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock; @@ -255,6 +259,7 @@ ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler; ACPI_EXTERN void *acpi_gbl_table_handler_context; ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; +ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler; /* Owner ID support */ @@ -275,6 +280,7 @@ ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; ACPI_EXTERN u8 acpi_gbl_events_initialized; ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; ACPI_EXTERN u8 acpi_gbl_osi_data; +ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces; #ifndef DEFINE_ACPI_GLOBALS diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index df85b53..53f7512 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -914,9 +914,14 @@ struct acpi_bit_register_info { struct acpi_interface_info { char *name; + struct acpi_interface_info *next; + u8 flags; u8 value; }; +#define ACPI_OSI_INVALID 0x01 +#define ACPI_OSI_DYNAMIC 0x02 + struct acpi_port_info { char *name; u16 start; diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 35df755..78e0121 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -312,8 +312,6 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list); /* * uteval - object evaluation */ -acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state); - acpi_status acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, char *path, @@ -395,6 +393,21 @@ acpi_status acpi_ut_get_object_size(union acpi_operand_object *obj, acpi_size * obj_length); /* + * utosi - Support for the _OSI predefined control method + */ +acpi_status acpi_ut_initialize_interfaces(void); + +void acpi_ut_interface_terminate(void); + +acpi_status acpi_ut_install_interface(acpi_string interface_name); + +acpi_status acpi_ut_remove_interface(acpi_string interface_name); + +struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name); + +acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state); + +/* * utstate - Generic state creation/cache routines */ void diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 6dfdeb6..22f59ef 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -48,153 +48,6 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("uteval") -/* - * Strings supported by the _OSI predefined (internal) method. - * - * March 2009: Removed "Linux" as this host no longer wants to respond true - * for this string. Basically, the only safe OS strings are windows-related - * and in many or most cases represent the only test path within the - * BIOS-provided ASL code. - * - * The second element of each entry is used to track the newest version of - * Windows that the BIOS has requested. - */ -static struct acpi_interface_info acpi_interfaces_supported[] = { - /* Operating System Vendor Strings */ - - {"Windows 2000", ACPI_OSI_WIN_2000}, /* Windows 2000 */ - {"Windows 2001", ACPI_OSI_WIN_XP}, /* Windows XP */ - {"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */ - {"Windows 2001.1", ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */ - {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ - {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ - {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ - {"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ - {"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ - {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ - - /* Feature Group Strings */ - - {"Extended Address Space Descriptor", 0} - - /* - * All "optional" feature group strings (features that are implemented - * by the host) should be implemented in the host version of - * acpi_os_validate_interface and should not be added here. - */ -}; - -/******************************************************************************* - * - * FUNCTION: acpi_ut_osi_implementation - * - * PARAMETERS: walk_state - Current walk state - * - * RETURN: Status - * - * DESCRIPTION: Implementation of the _OSI predefined control method - * - ******************************************************************************/ - -acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) -{ - acpi_status status; - union acpi_operand_object *string_desc; - union acpi_operand_object *return_desc; - u32 return_value; - u32 i; - - ACPI_FUNCTION_TRACE(ut_osi_implementation); - - /* Validate the string input argument */ - - string_desc = walk_state->arguments[0].object; - if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { - return_ACPI_STATUS(AE_TYPE); - } - - /* Create a return object */ - - return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); - if (!return_desc) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* Default return value is 0, NOT SUPPORTED */ - - return_value = 0; - - /* Compare input string to static table of supported interfaces */ - - for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { - if (!ACPI_STRCMP(string_desc->string.pointer, - acpi_interfaces_supported[i].name)) { - /* - * The interface is supported. - * Update the osi_data if necessary. We keep track of the latest - * version of Windows that has been requested by the BIOS. - */ - if (acpi_interfaces_supported[i].value > - acpi_gbl_osi_data) { - acpi_gbl_osi_data = - acpi_interfaces_supported[i].value; - } - - return_value = ACPI_UINT32_MAX; - goto exit; - } - } - - /* - * Did not match the string in the static table, call the host OSL to - * check for a match with one of the optional strings (such as - * "Module Device", "3.0 Thermal Model", etc.) - */ - status = acpi_os_validate_interface(string_desc->string.pointer); - if (ACPI_SUCCESS(status)) { - - /* The interface is supported */ - - return_value = ACPI_UINT32_MAX; - } - -exit: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, - "ACPI: BIOS _OSI(%s) is %ssupported\n", - string_desc->string.pointer, return_value == 0 ? "not " : "")); - - /* Complete the return value */ - - return_desc->integer.value = return_value; - walk_state->return_desc = return_desc; - return_ACPI_STATUS (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_osi_invalidate - * - * PARAMETERS: interface_string - * - * RETURN: Status - * - * DESCRIPTION: invalidate string in pre-defiend _OSI string list - * - ******************************************************************************/ - -acpi_status acpi_osi_invalidate(char *interface) -{ - int i; - - for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { - if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) { - *acpi_interfaces_supported[i].name = '\0'; - return AE_OK; - } - } - return AE_NOT_FOUND; -} - /******************************************************************************* * * FUNCTION: acpi_ut_evaluate_object diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 0558747..45f6334 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -774,6 +774,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_exception_handler = NULL; acpi_gbl_init_handler = NULL; acpi_gbl_table_handler = NULL; + acpi_gbl_interface_handler = NULL; /* Global Lock support */ @@ -800,6 +801,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_debugger_configuration = DEBUGGER_THREADING; acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; acpi_gbl_osi_data = 0; + acpi_gbl_osi_mutex = NULL; /* Hardware oriented */ diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index a39c93d..c1b1c80 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -117,6 +117,10 @@ void acpi_ut_subsystem_shutdown(void) /* Close the acpi_event Handling */ acpi_ev_terminate(); + + /* Delete any dynamic _OSI interfaces */ + + acpi_ut_interface_terminate(); #endif /* Close the Namespace */ diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index f5cca3a..b07b425 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -86,6 +86,12 @@ acpi_status acpi_ut_mutex_initialize(void) spin_lock_init(acpi_gbl_gpe_lock); spin_lock_init(acpi_gbl_hardware_lock); + /* Mutex for _OSI support */ + status = acpi_os_create_mutex(&acpi_gbl_osi_mutex); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + /* Create the reader/writer lock for namespace access */ status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock); @@ -117,6 +123,8 @@ void acpi_ut_mutex_terminate(void) acpi_ut_delete_mutex(i); } + acpi_os_delete_mutex(acpi_gbl_osi_mutex); + /* Delete the spinlocks */ acpi_os_delete_lock(acpi_gbl_gpe_lock); diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c new file mode 100644 index 0000000..0a37950c --- /dev/null +++ b/drivers/acpi/acpica/utosi.c @@ -0,0 +1,379 @@ +/****************************************************************************** + * + * Module Name: utosi - Support for the _OSI predefined control method + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2010, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utosi") + +/* + * Strings supported by the _OSI predefined control method (which is + * implemented internally within this module.) + * + * March 2009: Removed "Linux" as this host no longer wants to respond true + * for this string. Basically, the only safe OS strings are windows-related + * and in many or most cases represent the only test path within the + * BIOS-provided ASL code. + * + * The last element of each entry is used to track the newest version of + * Windows that the BIOS has requested. + */ +static struct acpi_interface_info acpi_default_supported_interfaces[] = { + /* Operating System Vendor Strings */ + + {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */ + {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */ + {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */ + {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */ + {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ + {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ + {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ + {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ + {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ + {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ + + /* Feature Group Strings */ + + {"Extended Address Space Descriptor", NULL, 0, 0} + + /* + * All "optional" feature group strings (features that are implemented + * by the host) should be dynamically added by the host via + * acpi_install_interface and should not be manually added here. + * + * Examples of optional feature group strings: + * + * "Module Device" + * "Processor Device" + * "3.0 Thermal Model" + * "3.0 _SCP Extensions" + * "Processor Aggregator Device" + */ +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ut_initialize_interfaces + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize the global _OSI supported interfaces list + * + ******************************************************************************/ + +acpi_status acpi_ut_initialize_interfaces(void) +{ + u32 i; + + (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + acpi_gbl_supported_interfaces = acpi_default_supported_interfaces; + + /* Link the static list of supported interfaces */ + + for (i = 0; + i < (ACPI_ARRAY_LENGTH(acpi_default_supported_interfaces) - 1); + i++) { + acpi_default_supported_interfaces[i].next = + &acpi_default_supported_interfaces[(acpi_size) i + 1]; + } + + acpi_os_release_mutex(acpi_gbl_osi_mutex); + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_interface_terminate + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Delete all interfaces in the global list. Sets + * acpi_gbl_supported_interfaces to NULL. + * + ******************************************************************************/ + +void acpi_ut_interface_terminate(void) +{ + struct acpi_interface_info *next_interface; + + (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + next_interface = acpi_gbl_supported_interfaces; + + while (next_interface) { + acpi_gbl_supported_interfaces = next_interface->next; + + /* Only interfaces added at runtime can be freed */ + + if (next_interface->flags & ACPI_OSI_DYNAMIC) { + ACPI_FREE(next_interface->name); + ACPI_FREE(next_interface); + } + + next_interface = acpi_gbl_supported_interfaces; + } + + acpi_os_release_mutex(acpi_gbl_osi_mutex); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_install_interface + * + * PARAMETERS: interface_name - The interface to install + * + * RETURN: Status + * + * DESCRIPTION: Install the interface into the global interface list. + * Caller MUST hold acpi_gbl_osi_mutex + * + ******************************************************************************/ + +acpi_status acpi_ut_install_interface(acpi_string interface_name) +{ + struct acpi_interface_info *interface_info; + + /* Allocate info block and space for the name string */ + + interface_info = + ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_interface_info)); + if (!interface_info) { + return (AE_NO_MEMORY); + } + + interface_info->name = + ACPI_ALLOCATE_ZEROED(ACPI_STRLEN(interface_name) + 1); + if (!interface_info->name) { + ACPI_FREE(interface_info); + return (AE_NO_MEMORY); + } + + /* Initialize new info and insert at the head of the global list */ + + ACPI_STRCPY(interface_info->name, interface_name); + interface_info->flags = ACPI_OSI_DYNAMIC; + interface_info->next = acpi_gbl_supported_interfaces; + + acpi_gbl_supported_interfaces = interface_info; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_remove_interface + * + * PARAMETERS: interface_name - The interface to remove + * + * RETURN: Status + * + * DESCRIPTION: Remove the interface from the global interface list. + * Caller MUST hold acpi_gbl_osi_mutex + * + ******************************************************************************/ + +acpi_status acpi_ut_remove_interface(acpi_string interface_name) +{ + struct acpi_interface_info *previous_interface; + struct acpi_interface_info *next_interface; + + previous_interface = next_interface = acpi_gbl_supported_interfaces; + while (next_interface) { + if (!ACPI_STRCMP(interface_name, next_interface->name)) { + + /* Found: name is in either the static list or was added at runtime */ + + if (next_interface->flags & ACPI_OSI_DYNAMIC) { + + /* Interface was added dynamically, remove and free it */ + + if (previous_interface == next_interface) { + acpi_gbl_supported_interfaces = + next_interface->next; + } else { + previous_interface->next = + next_interface->next; + } + + ACPI_FREE(next_interface->name); + ACPI_FREE(next_interface); + } else { + /* + * Interface is in static list. If marked invalid, then it + * does not actually exist. Else, mark it invalid. + */ + if (next_interface->flags & ACPI_OSI_INVALID) { + return (AE_NOT_EXIST); + } + + next_interface->flags |= ACPI_OSI_INVALID; + } + + return (AE_OK); + } + + previous_interface = next_interface; + next_interface = next_interface->next; + } + + /* Interface was not found */ + + return (AE_NOT_EXIST); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_interface + * + * PARAMETERS: interface_name - The interface to find + * + * RETURN: struct acpi_interface_info if found. NULL if not found. + * + * DESCRIPTION: Search for the specified interface name in the global list. + * Caller MUST hold acpi_gbl_osi_mutex + * + ******************************************************************************/ + +struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name) +{ + struct acpi_interface_info *next_interface; + + next_interface = acpi_gbl_supported_interfaces; + while (next_interface) { + if (!ACPI_STRCMP(interface_name, next_interface->name)) { + return (next_interface); + } + + next_interface = next_interface->next; + } + + return (NULL); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_osi_implementation + * + * PARAMETERS: walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Implementation of the _OSI predefined control method. When + * an invocation of _OSI is encountered in the system AML, + * control is transferred to this function. + * + ******************************************************************************/ + +acpi_status acpi_ut_osi_implementation(struct acpi_walk_state * walk_state) +{ + union acpi_operand_object *string_desc; + union acpi_operand_object *return_desc; + struct acpi_interface_info *interface_info; + acpi_interface_handler interface_handler; + u32 return_value; + + ACPI_FUNCTION_TRACE(ut_osi_implementation); + + /* Validate the string input argument (from the AML caller) */ + + string_desc = walk_state->arguments[0].object; + if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { + return_ACPI_STATUS(AE_TYPE); + } + + /* Create a return object */ + + return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); + if (!return_desc) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Default return value is 0, NOT SUPPORTED */ + + return_value = 0; + (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + + /* Lookup the interface in the global _OSI list */ + + interface_info = acpi_ut_get_interface(string_desc->string.pointer); + if (interface_info && !(interface_info->flags & ACPI_OSI_INVALID)) { + /* + * The interface is supported. + * Update the osi_data if necessary. We keep track of the latest + * version of Windows that has been requested by the BIOS. + */ + if (interface_info->value > acpi_gbl_osi_data) { + acpi_gbl_osi_data = interface_info->value; + } + + return_value = ACPI_UINT32_MAX; + } + + acpi_os_release_mutex(acpi_gbl_osi_mutex); + + /* + * Invoke an optional _OSI interface handler. The host OS may wish + * to do some interface-specific handling. For example, warn about + * certain interfaces or override the true/false support value. + */ + interface_handler = acpi_gbl_interface_handler; + if (interface_handler) { + return_value = + interface_handler(string_desc->string.pointer, + return_value); + } + + ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, + "ACPI: BIOS _OSI(\"%s\") is %ssupported\n", + string_desc->string.pointer, + return_value == 0 ? "not " : "")); + + /* Complete the return object */ + + return_desc->integer.value = return_value; + walk_state->return_desc = return_desc; + return_ACPI_STATUS(AE_OK); +} diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 7f8cefc..c2da90f 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -110,6 +110,15 @@ acpi_status __init acpi_initialize_subsystem(void) return_ACPI_STATUS(status); } + /* Initialize the global OSI interfaces list with the static names */ + + status = acpi_ut_initialize_interfaces(); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "During OSI interfaces initialization")); + return_ACPI_STATUS(status); + } + /* If configured, initialize the AML debugger */ ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); @@ -506,6 +515,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function) ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) #endif /* ACPI_FUTURE_USAGE */ + /***************************************************************************** * * FUNCTION: acpi_purge_cached_objects @@ -529,4 +539,117 @@ acpi_status acpi_purge_cached_objects(void) } ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) -#endif + +/***************************************************************************** + * + * FUNCTION: acpi_install_interface + * + * PARAMETERS: interface_name - The interface to install + * + * RETURN: Status + * + * DESCRIPTION: Install an _OSI interface to the global list + * + ****************************************************************************/ +acpi_status acpi_install_interface(acpi_string interface_name) +{ + acpi_status status; + struct acpi_interface_info *interface_info; + + /* Parameter validation */ + + if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) { + return (AE_BAD_PARAMETER); + } + + (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + + /* Check if the interface name is already in the global list */ + + interface_info = acpi_ut_get_interface(interface_name); + if (interface_info) { + /* + * The interface already exists in the list. This is OK if the + * interface has been marked invalid -- just clear the bit. + */ + if (interface_info->flags & ACPI_OSI_INVALID) { + interface_info->flags &= ~ACPI_OSI_INVALID; + status = AE_OK; + } else { + status = AE_ALREADY_EXISTS; + } + } else { + /* New interface name, install into the global list */ + + status = acpi_ut_install_interface(interface_name); + } + + acpi_os_release_mutex(acpi_gbl_osi_mutex); + return (status); +} + +ACPI_EXPORT_SYMBOL(acpi_install_interface) + +/***************************************************************************** + * + * FUNCTION: acpi_remove_interface + * + * PARAMETERS: interface_name - The interface to remove + * + * RETURN: Status + * + * DESCRIPTION: Remove an _OSI interface from the global list + * + ****************************************************************************/ +acpi_status acpi_remove_interface(acpi_string interface_name) +{ + acpi_status status; + + /* Parameter validation */ + + if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) { + return (AE_BAD_PARAMETER); + } + + (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + + status = acpi_ut_remove_interface(interface_name); + + acpi_os_release_mutex(acpi_gbl_osi_mutex); + return (status); +} + +ACPI_EXPORT_SYMBOL(acpi_remove_interface) + +/***************************************************************************** + * + * FUNCTION: acpi_install_interface_handler + * + * PARAMETERS: Handler - The _OSI interface handler to install + * NULL means "remove existing handler" + * + * RETURN: Status + * + * DESCRIPTION: Install a handler for the predefined _OSI ACPI method. + * invoked during execution of the internal implementation of + * _OSI. A NULL handler simply removes any existing handler. + * + ****************************************************************************/ +acpi_status acpi_install_interface_handler(acpi_interface_handler handler) +{ + acpi_status status = AE_OK; + + (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + + if (handler && acpi_gbl_interface_handler) { + status = AE_ALREADY_EXISTS; + } else { + acpi_gbl_interface_handler = handler; + } + + acpi_os_release_mutex(acpi_gbl_osi_mutex); + return (status); +} + +ACPI_EXPORT_SYMBOL(acpi_install_interface_handler) +#endif /* !ACPI_ASL_COMPILER */ diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index a351291..6652c49 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -96,7 +96,9 @@ static LIST_HEAD(resource_list_head); static DEFINE_SPINLOCK(acpi_res_lock); #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ -static char osi_additional_string[OSI_STRING_LENGTH_MAX]; +static char osi_setup_string[OSI_STRING_LENGTH_MAX]; + +static void __init acpi_osi_setup_late(void); /* * The story of _OSI(Linux) @@ -138,6 +140,20 @@ static struct osi_linux { unsigned int known:1; } osi_linux = { 0, 0, 0, 0}; +static u32 acpi_osi_handler(acpi_string interface, u32 supported) +{ + if (!strcmp("Linux", interface)) { + + printk(KERN_NOTICE PREFIX + "BIOS _OSI(Linux) query %s%s\n", + osi_linux.enable ? "honored" : "ignored", + osi_linux.cmdline ? " via cmdline" : + osi_linux.dmi ? " via DMI" : ""); + } + + return supported; +} + static void __init acpi_request_region (struct acpi_generic_address *addr, unsigned int length, char *desc) { @@ -198,6 +214,8 @@ acpi_status acpi_os_initialize1(void) BUG_ON(!kacpid_wq); BUG_ON(!kacpi_notify_wq); BUG_ON(!kacpi_hotplug_wq); + acpi_install_interface_handler(acpi_osi_handler); + acpi_osi_setup_late(); return AE_OK; } @@ -979,6 +997,12 @@ static void __init set_osi_linux(unsigned int enable) printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", enable ? "Add": "Delet"); } + + if (osi_linux.enable) + acpi_osi_setup("Linux"); + else + acpi_osi_setup("!Linux"); + return; } @@ -1013,21 +1037,33 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) * string starting with '!' disables that string * otherwise string is added to list, augmenting built-in strings */ -int __init acpi_osi_setup(char *str) +static void __init acpi_osi_setup_late(void) { - if (str == NULL || *str == '\0') { - printk(KERN_INFO PREFIX "_OSI method disabled\n"); - acpi_gbl_create_osi_method = FALSE; - } else if (!strcmp("!Linux", str)) { + char *str = osi_setup_string; + + if (*str == '\0') + return; + + if (!strcmp("!Linux", str)) { acpi_cmdline_osi_linux(0); /* !enable */ } else if (*str == '!') { - if (acpi_osi_invalidate(++str) == AE_OK) + if (acpi_remove_interface(++str) == AE_OK) printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); } else if (!strcmp("Linux", str)) { acpi_cmdline_osi_linux(1); /* enable */ - } else if (*osi_additional_string == '\0') { - strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); - printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); + } else { + if (acpi_install_interface(str) == AE_OK) + printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); + } +} + +int __init acpi_osi_setup(char *str) +{ + if (str == NULL || *str == '\0') { + printk(KERN_INFO PREFIX "_OSI method disabled\n"); + acpi_gbl_create_osi_method = FALSE; + } else { + strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); } return 1; @@ -1284,38 +1320,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) return (AE_OK); } -/****************************************************************************** - * - * FUNCTION: acpi_os_validate_interface - * - * PARAMETERS: interface - Requested interface to be validated - * - * RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise - * - * DESCRIPTION: Match an interface string to the interfaces supported by the - * host. Strings originate from an AML call to the _OSI method. - * - *****************************************************************************/ - -acpi_status -acpi_os_validate_interface (char *interface) -{ - if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) - return AE_OK; - if (!strcmp("Linux", interface)) { - - printk(KERN_NOTICE PREFIX - "BIOS _OSI(Linux) query %s%s\n", - osi_linux.enable ? "honored" : "ignored", - osi_linux.cmdline ? " via cmdline" : - osi_linux.dmi ? " via DMI" : ""); - - if (osi_linux.enable) - return AE_OK; - } - return AE_SUPPORT; -} - static inline int acpi_res_list_add(struct acpi_res_list *res) { struct acpi_res_list *res_list_elem; diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 5e22577..c29b0af 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -239,9 +239,6 @@ acpi_os_derive_pci_id(acpi_handle device, /* * Miscellaneous */ -acpi_status acpi_os_validate_interface(char *interface); -acpi_status acpi_osi_invalidate(char* interface); - acpi_status acpi_os_validate_address(u8 space_id, acpi_physical_address address, acpi_size length, char *name); diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index c0786d4..e4d6cc8 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -105,6 +105,10 @@ const char *acpi_format_exception(acpi_status exception); acpi_status acpi_purge_cached_objects(void); +acpi_status acpi_install_interface(acpi_string interface_name); + +acpi_status acpi_remove_interface(acpi_string interface_name); + /* * ACPI Memory management */ @@ -263,6 +267,8 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, acpi_status acpi_install_exception_handler(acpi_exception_handler handler); #endif +acpi_status acpi_install_interface_handler(acpi_interface_handler handler); + /* * Event interfaces */ diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 5db8f47..332d076 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -950,6 +950,9 @@ acpi_status(*acpi_walk_callback) (acpi_handle object, u32 nesting_level, void *context, void **return_value); +typedef +u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported); + /* Interrupt handler return values */ #define ACPI_INTERRUPT_NOT_HANDLED 0x00 -- cgit v0.10.2 From 6087658d7d576b8aeed8f9188cd9917db29aa0dd Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 11 Aug 2010 10:14:35 +0800 Subject: ACPICA: Update version to 20100806 Version 20100806. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index e4d6cc8..bfa252b 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20100702 +#define ACPI_CA_VERSION 0x20100806 #include "actypes.h" #include "actbl.h" -- cgit v0.10.2 From 95abccb576c44bc593e05fa1245d0ad26ce6107b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 15 Sep 2010 13:22:46 +0800 Subject: ACPICA: Obsolete the acpi_os_derive_pci_id OSL interface This function is not OS-dependent and has been replaced by acpi_hw_derive_pci_id, which is now in the ACPICA core code. Local implementations of acpi_os_derive_pci_id are no longer necessary and are removed. ACPICA BZ 857. http://www.acpica.org/bugzilla/show_bug.cgi?id=857 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 262903e..4fdcfdb 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -21,7 +21,7 @@ acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.o -acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o +acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o hwpci.o acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 120b3af..e7c5545 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -123,6 +123,13 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, #ifdef ACPI_FUTURE_USAGE /* + * hwpci - PCI configuration support + */ +acpi_status +acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, + acpi_handle root_pci_device, acpi_handle pci_region); + +/* * hwtimer - ACPI Timer prototypes */ acpi_status acpi_get_timer_resolution(u32 * resolution); diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index f40d271..0b47a6d 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -289,8 +289,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, } /* - * Get the PCI device and function numbers from the _ADR object contained - * in the parent's scope. + * Get the PCI device and function numbers from the _ADR object + * contained in the parent's scope. */ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node, &pci_value); @@ -320,9 +320,15 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, pci_id->bus = ACPI_LOWORD(pci_value); } - /* Complete this device's pci_id */ + /* Complete/update the PCI ID for this device */ - acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id); + status = + acpi_hw_derive_pci_id(pci_id, pci_root_node, + region_obj->region.node); + if (ACPI_FAILURE(status)) { + ACPI_FREE(pci_id); + return_ACPI_STATUS(status); + } *region_context = pci_id; return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c new file mode 100644 index 0000000..ad21c7d --- /dev/null +++ b/drivers/acpi/acpica/hwpci.c @@ -0,0 +1,412 @@ +/******************************************************************************* + * + * Module Name: hwpci - Obtain PCI bus, device, and function numbers + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2010, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" + +#define _COMPONENT ACPI_NAMESPACE +ACPI_MODULE_NAME("hwpci") + +/* PCI configuration space values */ +#define PCI_CFG_HEADER_TYPE_REG 0x0E +#define PCI_CFG_PRIMARY_BUS_NUMBER_REG 0x18 +#define PCI_CFG_SECONDARY_BUS_NUMBER_REG 0x19 +/* PCI header values */ +#define PCI_HEADER_TYPE_MASK 0x7F +#define PCI_TYPE_BRIDGE 0x01 +#define PCI_TYPE_CARDBUS_BRIDGE 0x02 +typedef struct acpi_pci_device { + acpi_handle device; + struct acpi_pci_device *next; + +} acpi_pci_device; + +/* Local prototypes */ + +static acpi_status +acpi_hw_build_pci_list(acpi_handle root_pci_device, + acpi_handle pci_region, + struct acpi_pci_device **return_list_head); + +static acpi_status +acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, + struct acpi_pci_device *list_head); + +static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head); + +static acpi_status +acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, + acpi_handle pci_device, + u16 *bus_number, u8 *is_bridge); + +/******************************************************************************* + * + * FUNCTION: acpi_hw_derive_pci_id + * + * PARAMETERS: pci_id - Initial values for the PCI ID. May be + * modified by this function. + * root_pci_device - A handle to a PCI device object. This + * object must be a PCI Root Bridge having a + * _HID value of either PNP0A03 or PNP0A08 + * pci_region - A handle to a PCI configuration space + * Operation Region being initialized + * + * RETURN: Status + * + * DESCRIPTION: This function derives a full PCI ID for a PCI device, + * consisting of a Segment number, Bus number, Device number, + * and function code. + * + * The PCI hardware dynamically configures PCI bus numbers + * depending on the bus topology discovered during system + * initialization. This function is invoked during configuration + * of a PCI_Config Operation Region in order to (possibly) update + * the Bus/Device/Function numbers in the pci_id with the actual + * values as determined by the hardware and operating system + * configuration. + * + * The pci_id parameter is initially populated during the Operation + * Region initialization. This function is then called, and is + * will make any necessary modifications to the Bus, Device, or + * Function number PCI ID subfields as appropriate for the + * current hardware and OS configuration. + * + * NOTE: Created 08/2010. Replaces the previous OSL acpi_os_derive_pci_id + * interface since this feature is OS-independent. This module + * specifically avoids any use of recursion by building a local + * temporary device list. + * + ******************************************************************************/ + +acpi_status +acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, + acpi_handle root_pci_device, acpi_handle pci_region) +{ + acpi_status status; + struct acpi_pci_device *list_head = NULL; + + ACPI_FUNCTION_TRACE(hw_derive_pci_id); + + if (!pci_id) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Build a list of PCI devices, from pci_region up to root_pci_device */ + + status = + acpi_hw_build_pci_list(root_pci_device, pci_region, &list_head); + if (ACPI_SUCCESS(status)) { + + /* Walk the list, updating the PCI device/function/bus numbers */ + + status = acpi_hw_process_pci_list(pci_id, list_head); + } + + /* Always delete the list */ + + acpi_hw_delete_pci_list(list_head); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_hw_build_pci_list + * + * PARAMETERS: root_pci_device - A handle to a PCI device object. This + * object is guaranteed to be a PCI Root + * Bridge having a _HID value of either + * PNP0A03 or PNP0A08 + * pci_region - A handle to the PCI configuration space + * Operation Region + * return_list_head - Where the PCI device list is returned + * + * RETURN: Status + * + * DESCRIPTION: Builds a list of devices from the input PCI region up to the + * Root PCI device for this namespace subtree. + * + ******************************************************************************/ + +static acpi_status +acpi_hw_build_pci_list(acpi_handle root_pci_device, + acpi_handle pci_region, + struct acpi_pci_device **return_list_head) +{ + acpi_handle current_device; + acpi_handle parent_device; + acpi_status status; + struct acpi_pci_device *list_element; + struct acpi_pci_device *list_head = NULL; + + /* + * Ascend namespace branch until the root_pci_device is reached, building + * a list of device nodes. Loop will exit when either the PCI device is + * found, or the root of the namespace is reached. + */ + current_device = pci_region; + while (1) { + status = acpi_get_parent(current_device, &parent_device); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Finished when we reach the PCI root device (PNP0A03 or PNP0A08) */ + + if (parent_device == root_pci_device) { + *return_list_head = list_head; + return (AE_OK); + } + + list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device)); + if (!list_element) { + return (AE_NO_MEMORY); + } + + /* Put new element at the head of the list */ + + list_element->next = list_head; + list_element->device = parent_device; + list_head = list_element; + + current_device = parent_device; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_hw_process_pci_list + * + * PARAMETERS: pci_id - Initial values for the PCI ID. May be + * modified by this function. + * list_head - Device list created by + * acpi_hw_build_pci_list + * + * RETURN: Status + * + * DESCRIPTION: Walk downward through the PCI device list, getting the device + * info for each, via the PCI configuration space and updating + * the PCI ID as necessary. Deletes the list during traversal. + * + ******************************************************************************/ + +static acpi_status +acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, + struct acpi_pci_device *list_head) +{ + acpi_status status = AE_OK; + struct acpi_pci_device *info; + u16 bus_number; + u8 is_bridge = TRUE; + + ACPI_FUNCTION_NAME(hw_process_pci_list); + + ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, + "Input PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X\n", + pci_id->segment, pci_id->bus, pci_id->device, + pci_id->function)); + + bus_number = pci_id->bus; + + /* + * Descend down the namespace tree, collecting PCI device, function, + * and bus numbers. bus_number is only important for PCI bridges. + * Algorithm: As we descend the tree, use the last valid PCI device, + * function, and bus numbers that are discovered, and assign them + * to the PCI ID for the target device. + */ + info = list_head; + while (info) { + status = acpi_hw_get_pci_device_info(pci_id, info->device, + &bus_number, &is_bridge); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + info = info->next; + } + + ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, + "Output PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X " + "Status %X BusNumber %X IsBridge %X\n", + pci_id->segment, pci_id->bus, pci_id->device, + pci_id->function, status, bus_number, is_bridge)); + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_hw_delete_pci_list + * + * PARAMETERS: list_head - Device list created by + * acpi_hw_build_pci_list + * + * RETURN: None + * + * DESCRIPTION: Free the entire PCI list. + * + ******************************************************************************/ + +static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head) +{ + struct acpi_pci_device *next; + struct acpi_pci_device *previous; + + next = list_head; + while (next) { + previous = next; + next = previous->next; + ACPI_FREE(previous); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_hw_get_pci_device_info + * + * PARAMETERS: pci_id - Initial values for the PCI ID. May be + * modified by this function. + * pci_device - Handle for the PCI device object + * bus_number - Where a PCI bridge bus number is returned + * is_bridge - Return value, indicates if this PCI + * device is a PCI bridge + * + * RETURN: Status + * + * DESCRIPTION: Get the device info for a single PCI device object. Get the + * _ADR (contains PCI device and function numbers), and for PCI + * bridge devices, get the bus number from PCI configuration + * space. + * + ******************************************************************************/ + +static acpi_status +acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, + acpi_handle pci_device, + u16 *bus_number, u8 *is_bridge) +{ + acpi_status status; + acpi_object_type object_type; + u64 return_value; + u64 pci_value; + + /* We only care about objects of type Device */ + + status = acpi_get_type(pci_device, &object_type); + if (ACPI_FAILURE(status)) { + return (status); + } + + if (object_type != ACPI_TYPE_DEVICE) { + return (AE_OK); + } + + /* We need an _ADR. Ignore device if not present */ + + status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, + pci_device, &return_value); + if (ACPI_FAILURE(status)) { + return (AE_OK); + } + + /* + * From _ADR, get the PCI Device and Function and + * update the PCI ID. + */ + pci_id->device = ACPI_HIWORD(ACPI_LODWORD(return_value)); + pci_id->function = ACPI_LOWORD(ACPI_LODWORD(return_value)); + + /* + * If the previous device was a bridge, use the previous + * device bus number + */ + if (*is_bridge) { + pci_id->bus = *bus_number; + } + + /* + * Get the bus numbers from PCI Config space: + * + * First, get the PCI header_type + */ + *is_bridge = FALSE; + status = acpi_os_read_pci_configuration(pci_id, + PCI_CFG_HEADER_TYPE_REG, + &pci_value, 8); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* We only care about bridges (1=pci_bridge, 2=card_bus_bridge) */ + + pci_value &= PCI_HEADER_TYPE_MASK; + + if ((pci_value != PCI_TYPE_BRIDGE) && + (pci_value != PCI_TYPE_CARDBUS_BRIDGE)) { + return (AE_OK); + } + + /* Bridge: Get the Primary bus_number */ + + status = acpi_os_read_pci_configuration(pci_id, + PCI_CFG_PRIMARY_BUS_NUMBER_REG, + &pci_value, 8); + if (ACPI_FAILURE(status)) { + return (status); + } + + *is_bridge = TRUE; + pci_id->bus = (u16)pci_value; + + /* Bridge: Get the Secondary bus_number */ + + status = acpi_os_read_pci_configuration(pci_id, + PCI_CFG_SECONDARY_BUS_NUMBER_REG, + &pci_value, 8); + if (ACPI_FAILURE(status)) { + return (status); + } + + *bus_number = (u16)pci_value; + return (AE_OK); +} diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6652c49..90a8e86 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -622,74 +622,6 @@ acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, return (result ? AE_ERROR : AE_OK); } -/* TODO: Change code to take advantage of driver model more */ -static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ - acpi_handle chandle, /* current node */ - struct acpi_pci_id **id, - int *is_bridge, u8 * bus_number) -{ - acpi_handle handle; - struct acpi_pci_id *pci_id = *id; - acpi_status status; - unsigned long long temp; - acpi_object_type type; - - acpi_get_parent(chandle, &handle); - if (handle != rhandle) { - acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, - bus_number); - - status = acpi_get_type(handle, &type); - if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE)) - return; - - status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, - &temp); - if (ACPI_SUCCESS(status)) { - u64 val; - pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp)); - pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp)); - - if (*is_bridge) - pci_id->bus = *bus_number; - - /* any nicer way to get bus number of bridge ? */ - status = - acpi_os_read_pci_configuration(pci_id, 0x0e, &val, - 8); - if (ACPI_SUCCESS(status) - && ((val & 0x7f) == 1 || (val & 0x7f) == 2)) { - status = - acpi_os_read_pci_configuration(pci_id, 0x18, - &val, 8); - if (!ACPI_SUCCESS(status)) { - /* Certainly broken... FIX ME */ - return; - } - *is_bridge = 1; - pci_id->bus = val; - status = - acpi_os_read_pci_configuration(pci_id, 0x19, - &val, 8); - if (ACPI_SUCCESS(status)) { - *bus_number = val; - } - } else - *is_bridge = 0; - } - } -} - -void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ - acpi_handle chandle, /* current node */ - struct acpi_pci_id **id) -{ - int is_bridge = 1; - u8 bus_number = (*id)->bus; - - acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number); -} - static void acpi_os_execute_deferred(struct work_struct *work) { struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index c29b0af..4302743 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -230,13 +230,6 @@ acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, u32 reg, u64 value, u32 width); /* - * Interim function needed for PCI IRQ routing - */ -void -acpi_os_derive_pci_id(acpi_handle device, - acpi_handle region, struct acpi_pci_id **pci_id); - -/* * Miscellaneous */ acpi_status -- cgit v0.10.2 From 8f40f171a29d0d2ae1ca8bd4a0c3fc9f514d1e20 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Wed, 15 Sep 2010 13:36:55 +0800 Subject: ACPICA: Add ACPI_INLINE configuration parameter The C inline keyword is not standardized, ACPI_INLINE allows this to be configured on a per-compiler basis. Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 1728cb9..d2ff432 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -49,7 +49,7 @@ ACPI_MODULE_NAME("tbfadt") /* Local prototypes */ -static inline void +static ACPI_INLINE void acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, u8 space_id, u8 byte_width, u64 address); @@ -181,7 +181,7 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = { * ******************************************************************************/ -static inline void +static ACPI_INLINE void acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, u8 space_id, u8 byte_width, u64 address) { diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index c05aeba..a3e334a 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -193,6 +193,12 @@ #define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE #endif +/* "inline" keywords - configurable since inline is not standardized */ + +#ifndef ACPI_INLINE +#define ACPI_INLINE +#endif + /* * Debugger threading model * Use single threaded if the entire subsystem is contained in an application diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 0cd53e3..5dcb953 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h @@ -44,6 +44,8 @@ #ifndef __ACGCC_H__ #define __ACGCC_H__ +#define ACPI_INLINE __inline__ + /* Function name is used for debug output. Non-ANSI, compiler-dependent */ #define ACPI_GET_FUNCTION_NAME __func__ -- cgit v0.10.2 From 28eb3fcf8762a3b52f4fef5af29dce50d23c7151 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Wed, 15 Sep 2010 13:55:13 +0800 Subject: ACPICA: Make acpi_thread_id no longer configurable, always u64 Change definition of acpi_thread_id to always be a u64. This simplifies the code, especially any printf output. u64 is the only common data type for all thread_id types across all operating systems. We now force the OSL to cast the native thread_id type to u64 before returning the value to ACPICA (via acpi_os_get_thread_id). Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index e7c5545..167470a 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -121,7 +121,6 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block, void *context); -#ifdef ACPI_FUTURE_USAGE /* * hwpci - PCI configuration support */ @@ -129,6 +128,7 @@ acpi_status acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, acpi_handle root_pci_device, acpi_handle pci_region); +#ifdef ACPI_FUTURE_USAGE /* * hwtimer - ACPI Timer prototypes */ diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 53f7512..04ce322 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -1001,7 +1001,7 @@ struct acpi_port_info { struct acpi_db_method_info { acpi_handle main_thread_gate; acpi_handle thread_complete_gate; - u32 *threads; + acpi_thread_id *threads; u32 num_threads; u32 num_created; u32 num_completed; diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 64750ee..d94dd89 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -573,7 +573,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, acpi_os_release_mutex(method_desc->method. mutex->mutex.os_mutex); - method_desc->method.mutex->mutex.thread_id = NULL; + method_desc->method.mutex->mutex.thread_id = 0; } } diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index df0aea9..fcaed9f 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c @@ -553,7 +553,7 @@ acpi_status acpi_ev_release_global_lock(void) acpi_gbl_global_lock_acquired = FALSE; /* Release the local GL mutex */ - acpi_ev_global_lock_thread_id = NULL; + acpi_ev_global_lock_thread_id = 0; acpi_ev_global_lock_acquired = 0; acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); return_ACPI_STATUS(status); diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index f73be97..6af14e4 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -336,7 +336,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc) /* Clear mutex info */ - obj_desc->mutex.thread_id = NULL; + obj_desc->mutex.thread_id = 0; return_ACPI_STATUS(status); } @@ -393,10 +393,10 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, if ((owner_thread->thread_id != walk_state->thread->thread_id) && (obj_desc != acpi_gbl_global_lock_mutex)) { ACPI_ERROR((AE_INFO, - "Thread %p cannot release Mutex [%4.4s] acquired by thread %p", - ACPI_CAST_PTR(void, walk_state->thread->thread_id), + "Thread %u cannot release Mutex [%4.4s] acquired by thread %u", + (u32)walk_state->thread->thread_id, acpi_ut_get_node_name(obj_desc->mutex.node), - ACPI_CAST_PTR(void, owner_thread->thread_id))); + (u32)owner_thread->thread_id)); return_ACPI_STATUS(AE_AML_NOT_OWNER); } @@ -488,7 +488,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) /* Mark mutex unowned */ obj_desc->mutex.owner_thread = NULL; - obj_desc->mutex.thread_id = NULL; + obj_desc->mutex.thread_id = 0; /* Update Thread sync_level (Last mutex is the important one) */ diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 9835106..f21c486 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -179,9 +179,8 @@ acpi_debug_print(u32 requested_debug_level, if (thread_id != acpi_gbl_prev_thread_id) { if (ACPI_LV_THREADS & acpi_dbg_level) { acpi_os_printf - ("\n**** Context Switch from TID %p to TID %p ****\n\n", - ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id), - ACPI_CAST_PTR(void, thread_id)); + ("\n**** Context Switch from TID %u to TID %u ****\n\n", + (u32)acpi_gbl_prev_thread_id, (u32)thread_id); } acpi_gbl_prev_thread_id = thread_id; @@ -194,7 +193,7 @@ acpi_debug_print(u32 requested_debug_level, acpi_os_printf("%8s-%04ld ", module_name, line_number); if (ACPI_LV_THREADS & acpi_dbg_level) { - acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id)); + acpi_os_printf("[%u] ", (u32)thread_id); } acpi_os_printf("[%02ld] %-22.22s: ", diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index b07b425..d9efa49 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -228,18 +228,17 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { ACPI_ERROR((AE_INFO, - "Mutex [%s] already acquired by this thread [%p]", + "Mutex [%s] already acquired by this thread [%u]", acpi_ut_get_mutex_name (mutex_id), - ACPI_CAST_PTR(void, - this_thread_id))); + (u32)this_thread_id)); return (AE_ALREADY_ACQUIRED); } ACPI_ERROR((AE_INFO, - "Invalid acquire order: Thread %p owns [%s], wants [%s]", - ACPI_CAST_PTR(void, this_thread_id), + "Invalid acquire order: Thread %u owns [%s], wants [%s]", + (u32)this_thread_id, acpi_ut_get_mutex_name(i), acpi_ut_get_mutex_name(mutex_id))); @@ -250,24 +249,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) #endif ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %p attempting to acquire Mutex [%s]\n", - ACPI_CAST_PTR(void, this_thread_id), + "Thread %u attempting to acquire Mutex [%s]\n", + (u32)this_thread_id, acpi_ut_get_mutex_name(mutex_id))); status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, ACPI_WAIT_FOREVER); if (ACPI_SUCCESS(status)) { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %p acquired Mutex [%s]\n", - ACPI_CAST_PTR(void, this_thread_id), + "Thread %u acquired Mutex [%s]\n", + (u32)this_thread_id, acpi_ut_get_mutex_name(mutex_id))); acpi_gbl_mutex_info[mutex_id].use_count++; acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; } else { ACPI_EXCEPTION((AE_INFO, status, - "Thread %p could not acquire Mutex [0x%X]", - ACPI_CAST_PTR(void, this_thread_id), mutex_id)); + "Thread %u could not acquire Mutex [0x%X]", + (u32)this_thread_id, mutex_id)); } return (status); @@ -287,10 +286,14 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) { + acpi_thread_id this_thread_id; + ACPI_FUNCTION_NAME(ut_release_mutex); - ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", - ACPI_CAST_PTR(void, acpi_os_get_thread_id()), + this_thread_id = acpi_os_get_thread_id(); + + ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n", + (u32)this_thread_id, acpi_ut_get_mutex_name(mutex_id))); if (mutex_id > ACPI_MAX_MUTEX) { diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 332d076..864cfae 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -115,7 +115,6 @@ * * ACPI_SIZE 16/32/64-bit unsigned value * ACPI_NATIVE_INT 16/32/64-bit signed value - * */ /******************************************************************************* @@ -132,6 +131,16 @@ typedef COMPILER_DEPENDENT_INT64 INT64; /*! [End] no source code translation !*/ +/* + * Value returned by acpi_os_get_thread_id. There is no standard "thread_id" + * across operating systems or even the various UNIX systems. Since ACPICA + * only needs the thread ID as a unique thread identifier, we use a u64 + * as the only common data type - it will accommodate any type of pointer or + * any type of integer. It is up to the host-dependent OSL to cast the + * native thread ID type to a u64 (in acpi_os_get_thread_id). + */ +#define acpi_thread_id u64 + /******************************************************************************* * * Types specific to 64-bit targets @@ -211,12 +220,6 @@ typedef u32 acpi_physical_address; * ******************************************************************************/ -/* Value returned by acpi_os_get_thread_id */ - -#ifndef acpi_thread_id -#define acpi_thread_id acpi_size -#endif - /* Flags for acpi_os_acquire_lock/acpi_os_release_lock */ #ifndef acpi_cpu_flags diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 103f08a..572189e 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -75,7 +75,6 @@ #define acpi_cache_t struct kmem_cache #define acpi_spinlock spinlock_t * #define acpi_cpu_flags unsigned long -#define acpi_thread_id struct task_struct * #else /* !__KERNEL__ */ @@ -88,7 +87,7 @@ /* Host-dependent types and defines for user-space ACPICA */ #define ACPI_FLUSH_CPU_CACHE() -#define acpi_thread_id pthread_t +#define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread)) #if defined(__ia64__) || defined(__x86_64__) #define ACPI_MACHINE_WIDTH 64 @@ -113,12 +112,13 @@ #ifdef __KERNEL__ +#include /* * Overrides for in-kernel ACPICA */ static inline acpi_thread_id acpi_os_get_thread_id(void) { - return current; + return (acpi_thread_id)(unsigned long)current; } /* @@ -127,7 +127,6 @@ static inline acpi_thread_id acpi_os_get_thread_id(void) * However, boot has (system_state != SYSTEM_RUNNING) * to quiet __might_sleep() in kmalloc() and resume does not. */ -#include static inline void *acpi_os_allocate(acpi_size size) { return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); -- cgit v0.10.2 From e786db75406b30fa74dea095c571c8c164a2f3dd Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 15 Sep 2010 14:00:53 +0800 Subject: ACPICA: Update math module; no functional change Move the 64-bit overlay structures to the utmath module since they are used nowhere else. Update module comment. ACPICA BZ 829. http://www.acpica.org/bugzilla/show_bug.cgi?id=829 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index 35059a1..49cf7b7 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -48,11 +48,27 @@ ACPI_MODULE_NAME("utmath") /* - * Support for double-precision integer divide. This code is included here - * in order to support kernel environments where the double-precision math - * library is not available. + * Optional support for 64-bit double-precision integer divide. This code + * is configurable and is implemented in order to support 32-bit kernel + * environments where a 64-bit double-precision math library is not available. + * + * Support for a more normal 64-bit divide/modulo (with check for a divide- + * by-zero) appears after this optional section of code. */ #ifndef ACPI_USE_NATIVE_DIVIDE +/* Structures used only for 64-bit divide */ +typedef struct uint64_struct { + u32 lo; + u32 hi; + +} uint64_struct; + +typedef union uint64_overlay { + u64 full; + struct uint64_struct part; + +} uint64_overlay; + /******************************************************************************* * * FUNCTION: acpi_ut_short_divide @@ -69,6 +85,7 @@ ACPI_MODULE_NAME("utmath") * 32-bit remainder. * ******************************************************************************/ + acpi_status acpi_ut_short_divide(u64 dividend, u32 divisor, u64 *out_quotient, u32 *out_remainder) diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 864cfae..2b134b6 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -378,16 +378,6 @@ typedef void *acpi_handle; /* Actually a ptr to a NS Node */ typedef u8 acpi_owner_id; #define ACPI_OWNER_ID_MAX 0xFF -struct uint64_struct { - u32 lo; - u32 hi; -}; - -union uint64_overlay { - u64 full; - struct uint64_struct part; -}; - #define ACPI_INTEGER_BIT_SIZE 64 #define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */ -- cgit v0.10.2 From 31b3d4c3b3c599a2329c3e66ffab7a045b169c85 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 15 Sep 2010 14:02:56 +0800 Subject: ACPICA: Make acpi_gbl_system_awake_and_running publically available Added extern for this boolean in acpixf.h. Some hosts utilize this value during suspend/restore operations. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index fe50f57..b8dbb9b 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -132,6 +132,7 @@ struct acpi_table_fadt acpi_gbl_FADT; u32 acpi_current_gpe_count; u32 acpi_gbl_trace_flags; acpi_name acpi_gbl_trace_method_name; +u8 acpi_gbl_system_awake_and_running; #endif @@ -278,7 +279,6 @@ ACPI_EXTERN u8 acpi_gbl_debugger_configuration; ACPI_EXTERN u8 acpi_gbl_step_to_next_call; ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; ACPI_EXTERN u8 acpi_gbl_events_initialized; -ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; ACPI_EXTERN u8 acpi_gbl_osi_data; ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces; diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index bfa252b..c156e5e 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -72,6 +72,7 @@ extern u8 acpi_gbl_truncate_io_addresses; extern u32 acpi_current_gpe_count; extern struct acpi_table_fadt acpi_gbl_FADT; +extern u8 acpi_gbl_system_awake_and_running; extern u32 acpi_rsdt_forced; /* -- cgit v0.10.2 From cc84e262b71bab53c3b2be2e71209c85b88b4b4d Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 15 Sep 2010 14:09:14 +0800 Subject: ACPICA: iASL/Disassembler: Write ACPI errors to stderr instead of output file This keeps the output files clean of random error messages that may originate from within the namespace/interpreter code. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 4fdcfdb..a7e1d1a 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -45,4 +45,4 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \ - utosi.o + utosi.o utxferror.o diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 9894929..8d5c9e0 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -338,8 +338,8 @@ * the plist contains a set of parens to allow variable-length lists. * These macros are used for both the debug and non-debug versions of the code. */ -#define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); -#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); +#define ACPI_ERROR_NAMESPACE(s, e) acpi_ut_namespace_error (AE_INFO, s, e); +#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ut_method_error (AE_INFO, s, n, p, e); #define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist #define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 9f60ff0..d44d3bc 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -339,18 +339,6 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node); u32 acpi_ns_local(acpi_object_type type); void -acpi_ns_report_error(const char *module_name, - u32 line_number, - const char *internal_name, acpi_status lookup_status); - -void -acpi_ns_report_method_error(const char *module_name, - u32 line_number, - const char *message, - struct acpi_namespace_node *node, - const char *path, acpi_status lookup_status); - -void acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg); acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info); diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 78e0121..72e4183 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -486,17 +486,6 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position); acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer); -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_predefined_warning(const char *module_name, - u32 line_number, - char *pathname, - u8 node_flags, const char *format, ...); - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_predefined_info(const char *module_name, - u32 line_number, - char *pathname, u8 node_flags, const char *format, ...); - /* Values for Base above (16=Hex, 10=Decimal) */ #define ACPI_ANY_BASE 0 @@ -587,6 +576,32 @@ acpi_status acpi_ut_create_list(char *list_name, u16 object_size, struct acpi_memory_list **return_cache); -#endif +#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ + +/* + * utxferror - various error/warning output functions + */ +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_warning(const char *module_name, + u32 line_number, + char *pathname, + u8 node_flags, const char *format, ...); + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_info(const char *module_name, + u32 line_number, + char *pathname, u8 node_flags, const char *format, ...); + +void +acpi_ut_namespace_error(const char *module_name, + u32 line_number, + const char *internal_name, acpi_status lookup_status); + +void +acpi_ut_method_error(const char *module_name, + u32 line_number, + const char *message, + struct acpi_namespace_node *node, + const char *path, acpi_status lookup_status); #endif /* _ACUTILS_H */ diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index e1add34..a7d6ad9 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -60,104 +60,6 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); /******************************************************************************* * - * FUNCTION: acpi_ns_report_error - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * internal_name - Name or path of the namespace node - * lookup_status - Exception code from NS lookup - * - * RETURN: None - * - * DESCRIPTION: Print warning message with full pathname - * - ******************************************************************************/ - -void -acpi_ns_report_error(const char *module_name, - u32 line_number, - const char *internal_name, acpi_status lookup_status) -{ - acpi_status status; - u32 bad_name; - char *name = NULL; - - acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); - - if (lookup_status == AE_BAD_CHARACTER) { - - /* There is a non-ascii character in the name */ - - ACPI_MOVE_32_TO_32(&bad_name, - ACPI_CAST_PTR(u32, internal_name)); - acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); - } else { - /* Convert path to external format */ - - status = acpi_ns_externalize_name(ACPI_UINT32_MAX, - internal_name, NULL, &name); - - /* Print target name */ - - if (ACPI_SUCCESS(status)) { - acpi_os_printf("[%s]", name); - } else { - acpi_os_printf("[COULD NOT EXTERNALIZE NAME]"); - } - - if (name) { - ACPI_FREE(name); - } - } - - acpi_os_printf(" Namespace lookup failure, %s\n", - acpi_format_exception(lookup_status)); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ns_report_method_error - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Message - Error message to use on failure - * prefix_node - Prefix relative to the path - * Path - Path to the node (optional) - * method_status - Execution status - * - * RETURN: None - * - * DESCRIPTION: Print warning message with full pathname - * - ******************************************************************************/ - -void -acpi_ns_report_method_error(const char *module_name, - u32 line_number, - const char *message, - struct acpi_namespace_node *prefix_node, - const char *path, acpi_status method_status) -{ - acpi_status status; - struct acpi_namespace_node *node = prefix_node; - - acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); - - if (path) { - status = - acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, - &node); - if (ACPI_FAILURE(status)) { - acpi_os_printf("[Could not get node by pathname]"); - } - } - - acpi_ns_print_node_pathname(node, message); - acpi_os_printf(", %s\n", acpi_format_exception(method_status)); -} - -/******************************************************************************* - * * FUNCTION: acpi_ns_print_node_pathname * * PARAMETERS: Node - Object diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index e8d0724..c7d0e05 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -50,11 +50,6 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") -/* - * Common suffix for messages - */ -#define ACPI_COMMON_MSG_SUFFIX \ - acpi_os_printf(" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) /******************************************************************************* * * FUNCTION: acpi_ut_validate_exception @@ -1044,160 +1039,3 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, return_ACPI_STATUS(AE_AML_INTERNAL); } - -/******************************************************************************* - * - * FUNCTION: acpi_error, acpi_exception, acpi_warning, acpi_info - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Format - Printf format string + additional args - * - * RETURN: None - * - * DESCRIPTION: Print message with module/line/version info - * - ******************************************************************************/ - -void ACPI_INTERNAL_VAR_XFACE -acpi_error(const char *module_name, u32 line_number, const char *format, ...) -{ - va_list args; - - acpi_os_printf("ACPI Error: "); - - va_start(args, format); - acpi_os_vprintf(format, args); - ACPI_COMMON_MSG_SUFFIX; - va_end(args); -} - -void ACPI_INTERNAL_VAR_XFACE -acpi_exception(const char *module_name, - u32 line_number, acpi_status status, const char *format, ...) -{ - va_list args; - - acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status)); - - va_start(args, format); - acpi_os_vprintf(format, args); - ACPI_COMMON_MSG_SUFFIX; - va_end(args); -} - -void ACPI_INTERNAL_VAR_XFACE -acpi_warning(const char *module_name, u32 line_number, const char *format, ...) -{ - va_list args; - - acpi_os_printf("ACPI Warning: "); - - va_start(args, format); - acpi_os_vprintf(format, args); - ACPI_COMMON_MSG_SUFFIX; - va_end(args); -} - -void ACPI_INTERNAL_VAR_XFACE -acpi_info(const char *module_name, u32 line_number, const char *format, ...) -{ - va_list args; - - acpi_os_printf("ACPI: "); - - va_start(args, format); - acpi_os_vprintf(format, args); - acpi_os_printf("\n"); - va_end(args); -} - -ACPI_EXPORT_SYMBOL(acpi_error) -ACPI_EXPORT_SYMBOL(acpi_exception) -ACPI_EXPORT_SYMBOL(acpi_warning) -ACPI_EXPORT_SYMBOL(acpi_info) - -/******************************************************************************* - * - * FUNCTION: acpi_ut_predefined_warning - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Pathname - Full pathname to the node - * node_flags - From Namespace node for the method/object - * Format - Printf format string + additional args - * - * RETURN: None - * - * DESCRIPTION: Warnings for the predefined validation module. Messages are - * only emitted the first time a problem with a particular - * method/object is detected. This prevents a flood of error - * messages for methods that are repeatedly evaluated. - * -******************************************************************************/ - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_predefined_warning(const char *module_name, - u32 line_number, - char *pathname, - u8 node_flags, const char *format, ...) -{ - va_list args; - - /* - * Warning messages for this method/object will be disabled after the - * first time a validation fails or an object is successfully repaired. - */ - if (node_flags & ANOBJ_EVALUATED) { - return; - } - - acpi_os_printf("ACPI Warning for %s: ", pathname); - - va_start(args, format); - acpi_os_vprintf(format, args); - ACPI_COMMON_MSG_SUFFIX; - va_end(args); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_predefined_info - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Pathname - Full pathname to the node - * node_flags - From Namespace node for the method/object - * Format - Printf format string + additional args - * - * RETURN: None - * - * DESCRIPTION: Info messages for the predefined validation module. Messages - * are only emitted the first time a problem with a particular - * method/object is detected. This prevents a flood of - * messages for methods that are repeatedly evaluated. - * - ******************************************************************************/ - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_predefined_info(const char *module_name, - u32 line_number, - char *pathname, u8 node_flags, const char *format, ...) -{ - va_list args; - - /* - * Warning messages for this method/object will be disabled after the - * first time a validation fails or an object is successfully repaired. - */ - if (node_flags & ANOBJ_EVALUATED) { - return; - } - - acpi_os_printf("ACPI Info for %s: ", pathname); - - va_start(args, format); - acpi_os_vprintf(format, args); - ACPI_COMMON_MSG_SUFFIX; - va_end(args); -} diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c new file mode 100644 index 0000000..bf679c4 --- /dev/null +++ b/drivers/acpi/acpica/utxferror.c @@ -0,0 +1,415 @@ +/******************************************************************************* + * + * Module Name: utxferror - Various error/warning output functions + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2010, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" +#include "acnamesp.h" + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utxferror") + +/* + * This module is used for the in-kernel ACPICA as well as the ACPICA + * tools/applications. + * + * For the i_aSL compiler case, the output is redirected to stderr so that + * any of the various ACPI errors and warnings do not appear in the output + * files, for either the compiler or disassembler portions of the tool. + */ +#ifdef ACPI_ASL_COMPILER +#include +extern FILE *acpi_gbl_output_file; + +#define ACPI_MSG_REDIRECT_BEGIN \ + FILE *output_file = acpi_gbl_output_file; \ + acpi_os_redirect_output (stderr); + +#define ACPI_MSG_REDIRECT_END \ + acpi_os_redirect_output (output_file); + +#else +/* + * non-i_aSL case - no redirection, nothing to do + */ +#define ACPI_MSG_REDIRECT_BEGIN +#define ACPI_MSG_REDIRECT_END +#endif +/* + * Common message prefixes + */ +#define ACPI_MSG_ERROR "ACPI Error: " +#define ACPI_MSG_EXCEPTION "ACPI Exception: " +#define ACPI_MSG_WARNING "ACPI Warning: " +#define ACPI_MSG_INFO "ACPI: " +/* + * Common message suffix + */ +#define ACPI_MSG_SUFFIX \ + acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) +/******************************************************************************* + * + * FUNCTION: acpi_error + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print "ACPI Error" message with module/line/version info + * + ******************************************************************************/ +void ACPI_INTERNAL_VAR_XFACE +acpi_error(const char *module_name, u32 line_number, const char *format, ...) +{ + va_list arg_list; + + ACPI_MSG_REDIRECT_BEGIN; + acpi_os_printf(ACPI_MSG_ERROR); + + va_start(arg_list, format); + acpi_os_vprintf(format, arg_list); + ACPI_MSG_SUFFIX; + va_end(arg_list); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL(acpi_error) + +/******************************************************************************* + * + * FUNCTION: acpi_exception + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Status - Status to be formatted + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print "ACPI Exception" message with module/line/version info + * and decoded acpi_status. + * + ******************************************************************************/ +void ACPI_INTERNAL_VAR_XFACE +acpi_exception(const char *module_name, + u32 line_number, acpi_status status, const char *format, ...) +{ + va_list arg_list; + + ACPI_MSG_REDIRECT_BEGIN; + acpi_os_printf(ACPI_MSG_EXCEPTION "%s, ", + acpi_format_exception(status)); + + va_start(arg_list, format); + acpi_os_vprintf(format, arg_list); + ACPI_MSG_SUFFIX; + va_end(arg_list); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL(acpi_exception) + +/******************************************************************************* + * + * FUNCTION: acpi_warning + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print "ACPI Warning" message with module/line/version info + * + ******************************************************************************/ +void ACPI_INTERNAL_VAR_XFACE +acpi_warning(const char *module_name, u32 line_number, const char *format, ...) +{ + va_list arg_list; + + ACPI_MSG_REDIRECT_BEGIN; + acpi_os_printf(ACPI_MSG_WARNING); + + va_start(arg_list, format); + acpi_os_vprintf(format, arg_list); + ACPI_MSG_SUFFIX; + va_end(arg_list); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL(acpi_warning) + +/******************************************************************************* + * + * FUNCTION: acpi_info + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print generic "ACPI:" information message. There is no + * module/line/version info in order to keep the message simple. + * + * TBD: module_name and line_number args are not needed, should be removed. + * + ******************************************************************************/ +void ACPI_INTERNAL_VAR_XFACE +acpi_info(const char *module_name, u32 line_number, const char *format, ...) +{ + va_list arg_list; + + ACPI_MSG_REDIRECT_BEGIN; + acpi_os_printf(ACPI_MSG_INFO); + + va_start(arg_list, format); + acpi_os_vprintf(format, arg_list); + acpi_os_printf("\n"); + va_end(arg_list); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL(acpi_info) + +/* + * The remainder of this module contains internal error functions that may + * be configured out. + */ +#ifndef ACPI_NO_ERROR_MESSAGES +/******************************************************************************* + * + * FUNCTION: acpi_ut_predefined_warning + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Pathname - Full pathname to the node + * node_flags - From Namespace node for the method/object + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Warnings for the predefined validation module. Messages are + * only emitted the first time a problem with a particular + * method/object is detected. This prevents a flood of error + * messages for methods that are repeatedly evaluated. + * + ******************************************************************************/ +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_warning(const char *module_name, + u32 line_number, + char *pathname, + u8 node_flags, const char *format, ...) +{ + va_list arg_list; + + /* + * Warning messages for this method/object will be disabled after the + * first time a validation fails or an object is successfully repaired. + */ + if (node_flags & ANOBJ_EVALUATED) { + return; + } + + acpi_os_printf(ACPI_MSG_WARNING "For %s: ", pathname); + + va_start(arg_list, format); + acpi_os_vprintf(format, arg_list); + ACPI_MSG_SUFFIX; + va_end(arg_list); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_predefined_info + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Pathname - Full pathname to the node + * node_flags - From Namespace node for the method/object + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Info messages for the predefined validation module. Messages + * are only emitted the first time a problem with a particular + * method/object is detected. This prevents a flood of + * messages for methods that are repeatedly evaluated. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_info(const char *module_name, + u32 line_number, + char *pathname, u8 node_flags, const char *format, ...) +{ + va_list arg_list; + + /* + * Warning messages for this method/object will be disabled after the + * first time a validation fails or an object is successfully repaired. + */ + if (node_flags & ANOBJ_EVALUATED) { + return; + } + + acpi_os_printf(ACPI_MSG_INFO "For %s: ", pathname); + + va_start(arg_list, format); + acpi_os_vprintf(format, arg_list); + ACPI_MSG_SUFFIX; + va_end(arg_list); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_namespace_error + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * internal_name - Name or path of the namespace node + * lookup_status - Exception code from NS lookup + * + * RETURN: None + * + * DESCRIPTION: Print error message with the full pathname for the NS node. + * + ******************************************************************************/ + +void +acpi_ut_namespace_error(const char *module_name, + u32 line_number, + const char *internal_name, acpi_status lookup_status) +{ + acpi_status status; + u32 bad_name; + char *name = NULL; + + ACPI_MSG_REDIRECT_BEGIN; + acpi_os_printf(ACPI_MSG_ERROR); + + if (lookup_status == AE_BAD_CHARACTER) { + + /* There is a non-ascii character in the name */ + + ACPI_MOVE_32_TO_32(&bad_name, + ACPI_CAST_PTR(u32, internal_name)); + acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); + } else { + /* Convert path to external format */ + + status = acpi_ns_externalize_name(ACPI_UINT32_MAX, + internal_name, NULL, &name); + + /* Print target name */ + + if (ACPI_SUCCESS(status)) { + acpi_os_printf("[%s]", name); + } else { + acpi_os_printf("[COULD NOT EXTERNALIZE NAME]"); + } + + if (name) { + ACPI_FREE(name); + } + } + + acpi_os_printf(" Namespace lookup failure, %s", + acpi_format_exception(lookup_status)); + + ACPI_MSG_SUFFIX; + ACPI_MSG_REDIRECT_END; +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_method_error + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Message - Error message to use on failure + * prefix_node - Prefix relative to the path + * Path - Path to the node (optional) + * method_status - Execution status + * + * RETURN: None + * + * DESCRIPTION: Print error message with the full pathname for the method. + * + ******************************************************************************/ + +void +acpi_ut_method_error(const char *module_name, + u32 line_number, + const char *message, + struct acpi_namespace_node *prefix_node, + const char *path, acpi_status method_status) +{ + acpi_status status; + struct acpi_namespace_node *node = prefix_node; + + ACPI_MSG_REDIRECT_BEGIN; + acpi_os_printf(ACPI_MSG_ERROR); + + if (path) { + status = + acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, + &node); + if (ACPI_FAILURE(status)) { + acpi_os_printf("[Could not get node by pathname]"); + } + } + + acpi_ns_print_node_pathname(node, message); + acpi_os_printf(", %s", acpi_format_exception(method_status)); + + ACPI_MSG_SUFFIX; + ACPI_MSG_REDIRECT_END; +} + +#endif /* ACPI_NO_ERROR_MESSAGES */ -- cgit v0.10.2 From 77b23f712bc40a65160e7d02b045f1562bb43ff1 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 15 Sep 2010 14:11:02 +0800 Subject: ACPICA: Add repair for _HID and _CID strings This dynamic repair will fix these problems: 1) Remove a leading asterisk in the string 2) Uppercase the entire string Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 4009498..4ef9f43 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -74,10 +74,18 @@ acpi_ns_repair_ALR(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr); static acpi_status +acpi_ns_repair_CID(struct acpi_predefined_data *data, + union acpi_operand_object **return_object_ptr); + +static acpi_status acpi_ns_repair_FDE(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr); static acpi_status +acpi_ns_repair_HID(struct acpi_predefined_data *data, + union acpi_operand_object **return_object_ptr); + +static acpi_status acpi_ns_repair_PSS(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr); @@ -108,8 +116,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements, * As necessary: * * _ALR: Sort the list ascending by ambient_illuminance + * _CID: Strings: uppercase all, remove any leading asterisk * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs + * _HID: Strings: uppercase all, remove any leading asterisk * _PSS: Sort the list descending by Power * _TSS: Sort the list descending by Power * @@ -122,8 +132,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements, */ static const struct acpi_repair_info acpi_ns_repairable_names[] = { {"_ALR", acpi_ns_repair_ALR}, + {"_CID", acpi_ns_repair_CID}, {"_FDE", acpi_ns_repair_FDE}, {"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */ + {"_HID", acpi_ns_repair_HID}, {"_PSS", acpi_ns_repair_PSS}, {"_TSS", acpi_ns_repair_TSS}, {{0, 0, 0, 0}, NULL} /* Table terminator */ @@ -321,6 +333,157 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data, /****************************************************************************** * + * FUNCTION: acpi_ns_repair_CID + * + * PARAMETERS: Data - Pointer to validation data structure + * return_object_ptr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _CID object. If a string, ensure that all + * letters are uppercase and that there is no leading asterisk. + * If a Package, ensure same for all string elements. + * + *****************************************************************************/ + +static acpi_status +acpi_ns_repair_CID(struct acpi_predefined_data *data, + union acpi_operand_object **return_object_ptr) +{ + acpi_status status; + union acpi_operand_object *return_object = *return_object_ptr; + union acpi_operand_object **element_ptr; + union acpi_operand_object *original_element; + u16 original_ref_count; + u32 i; + + /* Check for _CID as a simple string */ + + if (return_object->common.type == ACPI_TYPE_STRING) { + status = acpi_ns_repair_HID(data, return_object_ptr); + return (status); + } + + /* Exit if not a Package */ + + if (return_object->common.type != ACPI_TYPE_PACKAGE) { + return (AE_OK); + } + + /* Examine each element of the _CID package */ + + element_ptr = return_object->package.elements; + for (i = 0; i < return_object->package.count; i++) { + original_element = *element_ptr; + original_ref_count = original_element->common.reference_count; + + status = acpi_ns_repair_HID(data, element_ptr); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Take care with reference counts */ + + if (original_element != *element_ptr) { + + /* Element was replaced */ + + (*element_ptr)->common.reference_count = + original_ref_count; + + acpi_ut_remove_reference(original_element); + } + + element_ptr++; + } + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_ns_repair_HID + * + * PARAMETERS: Data - Pointer to validation data structure + * return_object_ptr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _HID object. If a string, ensure that all + * letters are uppercase and that there is no leading asterisk. + * + *****************************************************************************/ + +static acpi_status +acpi_ns_repair_HID(struct acpi_predefined_data *data, + union acpi_operand_object **return_object_ptr) +{ + union acpi_operand_object *return_object = *return_object_ptr; + union acpi_operand_object *new_string; + char *source; + char *dest; + + ACPI_FUNCTION_NAME(ns_repair_HID); + + /* We only care about string _HID objects (not integers) */ + + if (return_object->common.type != ACPI_TYPE_STRING) { + return (AE_OK); + } + + if (return_object->string.length == 0) { + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Invalid zero-length _HID or _CID string")); + + /* Return AE_OK anyway, let driver handle it */ + + data->flags |= ACPI_OBJECT_REPAIRED; + return (AE_OK); + } + + /* It is simplest to always create a new string object */ + + new_string = acpi_ut_create_string_object(return_object->string.length); + if (!new_string) { + return (AE_NO_MEMORY); + } + + /* + * Remove a leading asterisk if present. For some unknown reason, there + * are many machines in the field that contains IDs like this. + * + * Examples: "*PNP0C03", "*ACPI0003" + */ + source = return_object->string.pointer; + if (*source == '*') { + source++; + new_string->string.length--; + + ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, + "%s: Removed invalid leading asterisk\n", + data->pathname)); + } + + /* + * Copy and uppercase the string. From the ACPI specification: + * + * A valid PNP ID must be of the form "AAA####" where A is an uppercase + * letter and # is a hex digit. A valid ACPI ID must be of the form + * "ACPI####" where # is a hex digit. + */ + for (dest = new_string->string.pointer; *source; dest++, source++) { + *dest = (char)ACPI_TOUPPER(*source); + } + + acpi_ut_remove_reference(return_object); + *return_object_ptr = new_string; + return (AE_OK); +} + +/****************************************************************************** + * * FUNCTION: acpi_ns_repair_TSS * * PARAMETERS: Data - Pointer to validation data structure -- cgit v0.10.2 From 75434a2ae37b78887b7a1d70d0a23bbd5e09fb01 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 17 Sep 2010 08:14:01 +0800 Subject: ACPICA: Increase configurability of error messages Update to utxferror.c Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index bf679c4..6f12e31 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c @@ -221,7 +221,7 @@ ACPI_EXPORT_SYMBOL(acpi_info) * The remainder of this module contains internal error functions that may * be configured out. */ -#ifndef ACPI_NO_ERROR_MESSAGES +#if !defined (ACPI_NO_ERROR_MESSAGES) && !defined (ACPI_BIN_APP) /******************************************************************************* * * FUNCTION: acpi_ut_predefined_warning -- cgit v0.10.2 From 846b44ad4ed11fe4dc1bddd484dde71c272bcf1b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 17 Sep 2010 08:15:02 +0800 Subject: ACPICA: Update version to 20100915 Version 20100915. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index c156e5e..c6bc604 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20100806 +#define ACPI_CA_VERSION 0x20100915 #include "actypes.h" #include "actbl.h" -- cgit v0.10.2 From 3af283e1141474925b33383425bbe038e75fd03a Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 15 Oct 2010 21:38:57 -0400 Subject: ACPI: add FW_BUG to OSI(Linux) message Linux-2.6.22 initiated a dmesg complaint when it saw BIOS that invoked OSI(Linux). Linux-2.6.23 continued that complaint and started our policy of ignoring the bogus BIOS request. Past-time for Linux to label that complaint with FW_BUG. Signed-off-by: Len Brown diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 90a8e86..d3bed219 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -144,7 +144,7 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported) { if (!strcmp("Linux", interface)) { - printk(KERN_NOTICE PREFIX + printk(KERN_NOTICE FW_BUG PREFIX "BIOS _OSI(Linux) query %s%s\n", osi_linux.enable ? "honored" : "ignored", osi_linux.cmdline ? " via cmdline" : -- cgit v0.10.2 From 3989170f8e3c1bd71d8f7ec6e3d52e46815ee096 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 18 Oct 2010 08:43:13 +0800 Subject: ACPICA: Comment update; no functional change Add a usage note to InstallAddressSpaceHandler. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index 541cbc1..ce9314f 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -64,6 +64,12 @@ ACPI_MODULE_NAME("evxfregn") * * DESCRIPTION: Install a handler for all op_regions of a given space_id. * + * NOTE: This function should only be called after acpi_enable_subsystem has + * been called. This is because any _REG methods associated with the Space ID + * are executed here, and these methods can only be safely executed after + * the default handlers have been installed and the hardware has been + * initialized (via acpi_enable_subsystem.) + * ******************************************************************************/ acpi_status acpi_install_address_space_handler(acpi_handle device, -- cgit v0.10.2 From 81256669aaaa8b06a617f8d0613cb7fb24f8b910 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 18 Oct 2010 08:44:34 +0800 Subject: ACPICA: Change type of _TZ from ThermalZone to Device The type of ThermalZone was confusing hosts as they process the various ThermalZone objects. ACPICA BZ 876. http://www.acpica.org/bugzilla/show_bug.cgi?id=876 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 45f6334..4a5dcaa 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -154,14 +154,16 @@ ACPI_EXPORT_SYMBOL(acpi_format_exception) * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run * during the initialization sequence. * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to - * perform a Notify() operation on it. + * perform a Notify() operation on it. 09/2010: Changed to type Device. + * This still allows notifies, but does not confuse host code that + * searches for valid thermal_zone objects. */ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_SB_", ACPI_TYPE_DEVICE, NULL}, {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, - {"_TZ_", ACPI_TYPE_THERMAL, NULL}, + {"_TZ_", ACPI_TYPE_DEVICE, NULL}, {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, -- cgit v0.10.2 From 34cf66e724a2bf0a406d59b18f5bfeed746d7979 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 18 Oct 2010 08:47:16 +0800 Subject: ACPICA: Eliminate duplicate code in acpi_ut_execute_* functions Now that the nsrepair code automatically repairs _HID-related strings, this type of code is no longer needed in acpi_ut_execute_HID, acpi_ut_execute_CID, and acpi_ut_execute_UID. ACPICA BZ 878. http://www.acpica.org/bugzilla/show_bug.cgi?id=878 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index 1397fad..d290632 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c @@ -48,42 +48,6 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utids") -/* Local prototypes */ -static void acpi_ut_copy_id_string(char *destination, char *source); - -/******************************************************************************* - * - * FUNCTION: acpi_ut_copy_id_string - * - * PARAMETERS: Destination - Where to copy the string - * Source - Source string - * - * RETURN: None - * - * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. - * Performs removal of a leading asterisk if present -- workaround - * for a known issue on a bunch of machines. - * - ******************************************************************************/ - -static void acpi_ut_copy_id_string(char *destination, char *source) -{ - - /* - * Workaround for ID strings that have a leading asterisk. This construct - * is not allowed by the ACPI specification (ID strings must be - * alphanumeric), but enough existing machines have this embedded in their - * ID strings that the following code is useful. - */ - if (*source == '*') { - source++; - } - - /* Do the actual copy */ - - ACPI_STRCPY(destination, source); -} - /******************************************************************************* * * FUNCTION: acpi_ut_execute_HID @@ -101,7 +65,6 @@ static void acpi_ut_copy_id_string(char *destination, char *source) * NOTE: Internal function, no parameter validation * ******************************************************************************/ - acpi_status acpi_ut_execute_HID(struct acpi_namespace_node *device_node, struct acpica_device_id **return_id) @@ -147,7 +110,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node, if (obj_desc->common.type == ACPI_TYPE_INTEGER) { acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); } else { - acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer); + ACPI_STRCPY(hid->string, obj_desc->string.pointer); } hid->length = length; @@ -224,7 +187,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, if (obj_desc->common.type == ACPI_TYPE_INTEGER) { acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); } else { - acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer); + ACPI_STRCPY(uid->string, obj_desc->string.pointer); } uid->length = length; @@ -357,8 +320,8 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node, /* Copy the String CID from the returned object */ - acpi_ut_copy_id_string(next_id_string, - cid_objects[i]->string.pointer); + ACPI_STRCPY(next_id_string, + cid_objects[i]->string.pointer); length = cid_objects[i]->string.length + 1; } -- cgit v0.10.2 From 23ebbf07068f84b7ed119a0bef4a3f0ebb82c894 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 18 Oct 2010 08:50:47 +0800 Subject: ACPICA: Add Vista SP2 to supported _OSI strings Added "Windows 2006 SP2" for Vista SP2. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 04ce322..1bb18c0 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -908,7 +908,8 @@ struct acpi_bit_register_info { #define ACPI_OSI_WIN_VISTA 0x07 #define ACPI_OSI_WINSRV_2008 0x08 #define ACPI_OSI_WIN_VISTA_SP1 0x09 -#define ACPI_OSI_WIN_7 0x0A +#define ACPI_OSI_WIN_VISTA_SP2 0x0A +#define ACPI_OSI_WIN_7 0x0B #define ACPI_ALWAYS_ILLEGAL 0x00 diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 0a37950c..18c59a8 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c @@ -71,6 +71,7 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = { {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ + {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */ {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ /* Feature Group Strings */ -- cgit v0.10.2 From 49b3c1e04e1dd3cd9a428b0d8367193b73e472c1 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 18 Oct 2010 09:38:36 +0800 Subject: ACPICA: Clear PCIEXP_WAKE_STS when clearing ACPI events When clearing status bits via acpi_hw_clear_acpi_status, also clear the PCIEXP_WAKE_STS bit. Original change from Colin King. ACPICA BZ 880. http://www.acpica.org/bugzilla/show_bug.cgi?id=880 http://bugs.launchpad.net/bugs/613381 Signed-off-by: Colin Ian King Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 1bb18c0..8acf1e8 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -854,6 +854,7 @@ struct acpi_bit_register_info { ACPI_BITMASK_POWER_BUTTON_STATUS | \ ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ ACPI_BITMASK_RT_CLOCK_STATUS | \ + ACPI_BITMASK_PCIEXP_WAKE_STATUS | \ ACPI_BITMASK_WAKE_STATUS) #define ACPI_BITMASK_TIMER_ENABLE 0x0001 -- cgit v0.10.2 From 8af2cdeaeefb2712b752e223c6d3396b9894b80d Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 18 Oct 2010 09:10:58 +0800 Subject: ACPICA: Update version to 20101013 Version 20101013. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index c6bc604..12fe979 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20100915 +#define ACPI_CA_VERSION 0x20101013 #include "actypes.h" #include "actbl.h" -- cgit v0.10.2 From 8df3fc981dc12d9fdcaef4100a2193b605024d7a Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sat, 23 Oct 2010 01:36:40 -0400 Subject: Subject: [PATCH] ACPICA: Fix Scope() op in module level code Some Panasonic Toughbooks create nodes in module level code. Module level code is the executable AML code outside of control method, for example, below AML code creates a node \_SB.PCI0.GFX0.DD02.CUBL If (\_OSI ("Windows 2006")) { Scope (\_SB.PCI0.GFX0.DD02) { Name (CUBL, Ones) ... } } Scope() op does not actually create a new object, it refers to an existing object(\_SB.PCI0.GFX0.DD02 in above example). However, for Scope(), we want to indeed open a new scope, so the child nodes(CUBL in above example) can be created correctly under it. https://bugzilla.kernel.org/show_bug.cgi?id=19462 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index d555b37..6b0b5d0 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -300,10 +300,25 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, * we must enter this object into the namespace. The created * object is temporary and will be deleted upon completion of * the execution of this method. + * + * Note 10/2010: Except for the Scope() op. This opcode does + * not actually create a new object, it refers to an existing + * object. However, for Scope(), we want to indeed open a + * new scope. */ - status = acpi_ds_load2_begin_op(walk_state, NULL); + if (op->common.aml_opcode != AML_SCOPE_OP) { + status = + acpi_ds_load2_begin_op(walk_state, NULL); + } else { + status = + acpi_ds_scope_stack_push(op->named.node, + op->named.node-> + type, walk_state); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } } - break; case AML_CLASS_EXECUTE: -- cgit v0.10.2