NATIVE_CHAR * AcpiNsGetExternalPathname ( ACPI_NAMESPACE_NODE *Node) { NATIVE_CHAR *NameBuffer; ACPI_SIZE Size; ACPI_FUNCTION_TRACE_PTR ("NsGetExternalPathname", Node); /* Calculate required buffer size based on depth below root */ Size = AcpiNsGetPathnameLength (Node); /* Allocate a buffer to be returned to caller */ NameBuffer = ACPI_MEM_CALLOCATE (Size); if (!NameBuffer) { ACPI_REPORT_ERROR (("NsGetTablePathname: allocation failure\n")); return_PTR (NULL); } /* Build the path in the allocated buffer */ AcpiNsBuildExternalPath (Node, Size, NameBuffer); return_PTR (NameBuffer); }
union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size) { union acpi_operand_object *string_desc; char *string; ACPI_FUNCTION_TRACE_U32("ut_create_string_object", string_size); /* Create a new String object */ string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING); if (!string_desc) { return_PTR(NULL); } /* * Allocate the actual string buffer -- (Size + 1) for NULL terminator. * NOTE: Zero-length strings are NULL terminated */ string = ACPI_MEM_CALLOCATE(string_size + 1); if (!string) { ACPI_REPORT_ERROR(("create_string: could not allocate size %X\n", (u32) string_size)); acpi_ut_remove_reference(string_desc); return_PTR(NULL); } /* Complete string object initialization */ string_desc->string.pointer = string; string_desc->string.length = (u32) string_size; /* Return the new string descriptor */ return_PTR(string_desc); }
acpi_status acpi_ut_copy_ipackage_to_ipackage ( acpi_operand_object *source_obj, acpi_operand_object *dest_obj, acpi_walk_state *walk_state) { acpi_status status = AE_OK; FUNCTION_TRACE ("Ut_copy_ipackage_to_ipackage"); dest_obj->common.type = source_obj->common.type; dest_obj->package.count = source_obj->package.count; /* * Create the object array and walk the source package tree */ dest_obj->package.elements = ACPI_MEM_CALLOCATE ((source_obj->package.count + 1) * sizeof (void *)); dest_obj->package.next_element = dest_obj->package.elements; if (!dest_obj->package.elements) { REPORT_ERROR ( ("Aml_build_copy_internal_package_object: Package allocation failure\n")); return_ACPI_STATUS (AE_NO_MEMORY); } status = acpi_ut_walk_package_tree (source_obj, dest_obj, acpi_ut_copy_ielement_to_ielement, walk_state); return_ACPI_STATUS (status); }
ACPI_PARSE_STATE * AcpiPsCreateState ( UINT8 *Aml, UINT32 AmlSize) { ACPI_PARSE_STATE *ParserState; FUNCTION_TRACE ("PsCreateState"); ParserState = ACPI_MEM_CALLOCATE (sizeof (ACPI_PARSE_STATE)); if (!ParserState) { return_PTR (NULL); } ParserState->Aml = Aml; ParserState->AmlEnd = Aml + AmlSize; ParserState->PkgEnd = ParserState->AmlEnd; ParserState->AmlStart = Aml; return_PTR (ParserState); }
char * acpi_ns_get_external_pathname ( struct acpi_namespace_node *node) { char *name_buffer; acpi_size size; ACPI_FUNCTION_TRACE_PTR ("ns_get_external_pathname", node); /* Calculate required buffer size based on depth below root */ size = acpi_ns_get_pathname_length (node); /* Allocate a buffer to be returned to caller */ name_buffer = ACPI_MEM_CALLOCATE (size); if (!name_buffer) { ACPI_REPORT_ERROR (("ns_get_table_pathname: allocation failure\n")); return_PTR (NULL); } /* Build the path in the allocated buffer */ acpi_ns_build_external_path (node, size, name_buffer); return_PTR (name_buffer); }
acpi_status acpi_ex_store_string_to_string ( union acpi_operand_object *source_desc, union acpi_operand_object *target_desc) { u32 length; u8 *buffer; ACPI_FUNCTION_TRACE_PTR ("ex_store_string_to_string", source_desc); /* * We know that source_desc is a string by now. */ buffer = (u8 *) source_desc->string.pointer; length = source_desc->string.length; /* * Replace existing string value if it will fit and the string * pointer is not a static pointer (part of an ACPI table) */ if ((length < target_desc->string.length) && (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) { /* * String will fit in existing non-static buffer. * Clear old string and copy in the new one */ ACPI_MEMSET (target_desc->string.pointer, 0, (acpi_size) target_desc->string.length + 1); ACPI_MEMCPY (target_desc->string.pointer, buffer, length); } else { /* * Free the current buffer, then allocate a new buffer * large enough to hold the value */ if (target_desc->string.pointer && (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) { /* * Only free if not a pointer into the DSDT */ ACPI_MEM_FREE (target_desc->string.pointer); } target_desc->string.pointer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1); if (!target_desc->string.pointer) { return_ACPI_STATUS (AE_NO_MEMORY); } target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER; ACPI_MEMCPY (target_desc->string.pointer, buffer, length); } /* Set the new target length */ target_desc->string.length = length; return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiTbConvertToXsdt ( ACPI_TABLE_DESC *TableInfo) { ACPI_SIZE TableSize; UINT32 i; XSDT_DESCRIPTOR *NewTable; ACPI_FUNCTION_ENTRY (); /* Compute size of the converted XSDT */ TableSize = ((ACPI_SIZE) AcpiGbl_RsdtTableCount * sizeof (UINT64)) + sizeof (ACPI_TABLE_HEADER); /* Allocate an XSDT */ NewTable = ACPI_MEM_CALLOCATE (TableSize); if (!NewTable) { return (AE_NO_MEMORY); } /* Copy the header and set the length */ ACPI_MEMCPY (NewTable, TableInfo->Pointer, sizeof (ACPI_TABLE_HEADER)); NewTable->Header.Length = (UINT32) TableSize; /* Copy the table pointers */ for (i = 0; i < AcpiGbl_RsdtTableCount; i++) { if (AcpiGbl_RSDP->Revision < 2) { ACPI_STORE_ADDRESS (NewTable->TableOffsetEntry[i], ((RSDT_DESCRIPTOR_REV1 *) TableInfo->Pointer)->TableOffsetEntry[i]); } else { NewTable->TableOffsetEntry[i] = ((XSDT_DESCRIPTOR *) TableInfo->Pointer)->TableOffsetEntry[i]; } } /* Delete the original table (either mapped or in a buffer) */ AcpiTbDeleteSingleTable (TableInfo); /* Point the table descriptor to the new table */ TableInfo->Pointer = (ACPI_TABLE_HEADER *) NewTable; TableInfo->Length = TableSize; TableInfo->Allocation = ACPI_MEM_ALLOCATED; return (AE_OK); }
void * AcpiUtAcquireFromCache ( UINT32 ListId) { ACPI_MEMORY_LIST *CacheInfo; void *Object; PROC_NAME ("UtAcquireFromCache"); CacheInfo = &AcpiGbl_MemoryLists[ListId]; AcpiUtAcquireMutex (ACPI_MTX_CACHES); ACPI_MEM_TRACKING (CacheInfo->CacheRequests++); /* Check the cache first */ if (CacheInfo->ListHead) { /* There is an object available, use it */ Object = CacheInfo->ListHead; CacheInfo->ListHead = * (char **) (((char *) Object) + CacheInfo->LinkOffset); ACPI_MEM_TRACKING (CacheInfo->CacheHits++); CacheInfo->CacheDepth--; #ifdef ACPI_DBG_TRACK_ALLOCATIONS ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n", Object, AcpiGbl_MemoryLists[ListId].ListName)); #endif AcpiUtReleaseMutex (ACPI_MTX_CACHES); /* Clear (zero) the previously used Object */ MEMSET (Object, 0, CacheInfo->ObjectSize); } else { /* The cache is empty, create a new object */ /* Avoid deadlock with ACPI_MEM_CALLOCATE */ AcpiUtReleaseMutex (ACPI_MTX_CACHES); Object = ACPI_MEM_CALLOCATE (CacheInfo->ObjectSize); ACPI_MEM_TRACKING (CacheInfo->TotalAllocated++); } return (Object); }
acpi_status acpi_ns_internalize_name ( NATIVE_CHAR *external_name, NATIVE_CHAR **converted_name) { NATIVE_CHAR *internal_name; acpi_namestring_info info; acpi_status status; FUNCTION_TRACE ("Ns_internalize_name"); if ((!external_name) || (*external_name == 0) || (!converted_name)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get the length of the new internal name */ info.external_name = external_name; acpi_ns_get_internal_name_length (&info); /* We need a segment to store the internal name */ internal_name = ACPI_MEM_CALLOCATE (info.length); if (!internal_name) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Build the name */ info.internal_name = internal_name; status = acpi_ns_build_internal_name (&info); if (ACPI_FAILURE (status)) { ACPI_MEM_FREE (internal_name); return_ACPI_STATUS (status); } *converted_name = internal_name; return_ACPI_STATUS (AE_OK); }
acpi_status acpi_ut_copy_ipackage_to_ipackage ( union acpi_operand_object *source_obj, union acpi_operand_object *dest_obj, struct acpi_walk_state *walk_state) { acpi_status status = AE_OK; ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_ipackage"); dest_obj->common.type = ACPI_GET_OBJECT_TYPE (source_obj); dest_obj->common.flags = source_obj->common.flags; dest_obj->package.count = source_obj->package.count; /* * Create the object array and walk the source package tree */ dest_obj->package.elements = ACPI_MEM_CALLOCATE ( ((acpi_size) source_obj->package.count + 1) * sizeof (void *)); if (!dest_obj->package.elements) { ACPI_REPORT_ERROR ( ("aml_build_copy_internal_package_object: Package allocation failure\n")); return_ACPI_STATUS (AE_NO_MEMORY); } /* * Copy the package element-by-element by walking the package "tree". * This handles nested packages of arbitrary depth. */ status = acpi_ut_walk_package_tree (source_obj, dest_obj, acpi_ut_copy_ielement_to_ielement, walk_state); if (ACPI_FAILURE (status)) { /* On failure, delete the destination package object */ acpi_ut_remove_reference (dest_obj); } return_ACPI_STATUS (status); }
union acpi_operand_object * acpi_ut_create_buffer_object ( acpi_size buffer_size) { union acpi_operand_object *buffer_desc; u8 *buffer = NULL; ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size); /* Create a new Buffer object */ buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); if (!buffer_desc) { return_PTR (NULL); } /* Create an actual buffer only if size > 0 */ if (buffer_size > 0) { /* Allocate the actual buffer */ buffer = ACPI_MEM_CALLOCATE (buffer_size); if (!buffer) { ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n", (u32) buffer_size)); acpi_ut_remove_reference (buffer_desc); return_PTR (NULL); } } /* Complete buffer object initialization */ buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID; buffer_desc->buffer.pointer = buffer; buffer_desc->buffer.length = (u32) buffer_size; /* Return the new buffer descriptor */ return_PTR (buffer_desc); }
ACPI_OPERAND_OBJECT * AcpiUtCreateBufferObject ( ACPI_SIZE BufferSize) { ACPI_OPERAND_OBJECT *BufferDesc; UINT8 *Buffer; ACPI_FUNCTION_TRACE_U32 ("UtCreateBufferObject", BufferSize); /* * Create a new Buffer object */ BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER); if (!BufferDesc) { return_PTR (NULL); } /* Allocate the actual buffer */ Buffer = ACPI_MEM_CALLOCATE (BufferSize); if (!Buffer) { ACPI_REPORT_ERROR (("CreateBuffer: could not allocate size %X\n", (UINT32) BufferSize)); AcpiUtRemoveReference (BufferDesc); return_PTR (NULL); } /* Complete buffer object initialization */ BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID; BufferDesc->Buffer.Pointer = Buffer; BufferDesc->Buffer.Length = (UINT32) BufferSize; /* Return the new buffer descriptor */ return_PTR (BufferDesc); }
ACPI_STATUS AcpiEvSystemMemoryRegionSetup ( ACPI_HANDLE Handle, UINT32 Function, void *HandlerContext, void **RegionContext) { ACPI_OPERAND_OBJECT *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle; ACPI_MEM_SPACE_CONTEXT *LocalRegionContext; ACPI_FUNCTION_TRACE ("EvSystemMemoryRegionSetup"); if (Function == ACPI_REGION_DEACTIVATE) { if (*RegionContext) { ACPI_MEM_FREE (*RegionContext); *RegionContext = NULL; } return_ACPI_STATUS (AE_OK); } /* Create a new context */ LocalRegionContext = ACPI_MEM_CALLOCATE (sizeof (ACPI_MEM_SPACE_CONTEXT)); if (!(LocalRegionContext)) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Save the region length and address for use in the handler */ LocalRegionContext->Length = RegionDesc->Region.Length; LocalRegionContext->Address = RegionDesc->Region.Address; *RegionContext = LocalRegionContext; return_ACPI_STATUS (AE_OK); }
struct acpi_namespace_node * acpi_ns_create_node ( u32 name) { struct acpi_namespace_node *node; ACPI_FUNCTION_TRACE ("ns_create_node"); node = ACPI_MEM_CALLOCATE (sizeof (struct acpi_namespace_node)); if (!node) { return_PTR (NULL); } ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_allocated++); node->name.integer = name; node->reference_count = 1; ACPI_SET_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED); return_PTR (node); }
acpi_status acpi_tb_convert_to_xsdt ( struct acpi_table_desc *table_info) { acpi_size table_size; u32 i; XSDT_DESCRIPTOR *new_table; ACPI_FUNCTION_ENTRY (); /* Compute size of the converted XSDT */ table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof (u64)) + sizeof (struct acpi_table_header); /* Allocate an XSDT */ new_table = ACPI_MEM_CALLOCATE (table_size); if (!new_table) { return (AE_NO_MEMORY); } /* Copy the header and set the length */ ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header)); new_table->length = (u32) table_size; /* Copy the table pointers */ for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { if (acpi_gbl_RSDP->revision < 2) { ACPI_STORE_ADDRESS (new_table->table_offset_entry[i], (ACPI_CAST_PTR (struct rsdt_descriptor_rev1, table_info->pointer))->table_offset_entry[i]); } else {
acpi_status acpi_ev_system_memory_region_setup ( acpi_handle handle, u32 function, void *handler_context, void **region_context) { union acpi_operand_object *region_desc = (union acpi_operand_object *) handle; struct acpi_mem_space_context *local_region_context; ACPI_FUNCTION_TRACE ("ev_system_memory_region_setup"); if (function == ACPI_REGION_DEACTIVATE) { if (*region_context) { ACPI_MEM_FREE (*region_context); *region_context = NULL; } return_ACPI_STATUS (AE_OK); } /* Create a new context */ local_region_context = ACPI_MEM_CALLOCATE (sizeof (struct acpi_mem_space_context)); if (!(local_region_context)) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Save the region length and address for use in the handler */ local_region_context->length = region_desc->region.length; local_region_context->address = region_desc->region.address; *region_context = local_region_context; return_ACPI_STATUS (AE_OK); }
static struct acpi_gpe_xrupt_info * acpi_ev_get_gpe_xrupt_block ( u32 interrupt_level) { struct acpi_gpe_xrupt_info *next_gpe_xrupt; struct acpi_gpe_xrupt_info *gpe_xrupt; acpi_status status; ACPI_FUNCTION_TRACE ("ev_get_gpe_xrupt_block"); /* No need for spin lock since we are not changing any list elements here */ next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head; while (next_gpe_xrupt) { if (next_gpe_xrupt->interrupt_level == interrupt_level) { return_PTR (next_gpe_xrupt); } next_gpe_xrupt = next_gpe_xrupt->next; } /* Not found, must allocate a new xrupt descriptor */ gpe_xrupt = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_xrupt_info)); if (!gpe_xrupt) { return_PTR (NULL); } gpe_xrupt->interrupt_level = interrupt_level; /* Install new interrupt descriptor with spin lock */ acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); if (acpi_gbl_gpe_xrupt_list_head) { next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head; while (next_gpe_xrupt->next) { next_gpe_xrupt = next_gpe_xrupt->next; } next_gpe_xrupt->next = gpe_xrupt; gpe_xrupt->previous = next_gpe_xrupt; } else { acpi_gbl_gpe_xrupt_list_head = gpe_xrupt; } acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); /* Install new interrupt handler if not SCI_INT */ if (interrupt_level != acpi_gbl_FADT->sci_int) { status = acpi_os_install_interrupt_handler (interrupt_level, acpi_ev_gpe_xrupt_handler, gpe_xrupt); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not install GPE interrupt handler at level 0x%X\n", interrupt_level)); return_PTR (NULL); } } return_PTR (gpe_xrupt); }
acpi_status acpi_tb_init_table_descriptor ( acpi_table_type table_type, acpi_table_desc *table_info) { acpi_table_desc *list_head; acpi_table_desc *table_desc; FUNCTION_TRACE_U32 ("Tb_init_table_descriptor", table_type); /* * Install the table into the global data structure */ list_head = &acpi_gbl_acpi_tables[table_type]; table_desc = list_head; /* * Two major types of tables: 1) Only one instance is allowed. This * includes most ACPI tables such as the DSDT. 2) Multiple instances of * the table are allowed. This includes SSDT and PSDTs. */ if (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) { /* * Only one table allowed, and a table has alread been installed * at this location, so return an error. */ if (list_head->pointer) { return_ACPI_STATUS (AE_EXIST); } table_desc->count = 1; } else { /* * Multiple tables allowed for this table type, we must link * the new table in to the list of tables of this type. */ if (list_head->pointer) { table_desc = ACPI_MEM_CALLOCATE (sizeof (acpi_table_desc)); if (!table_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } list_head->count++; /* Update the original previous */ list_head->prev->next = table_desc; /* Update new entry */ table_desc->prev = list_head->prev; table_desc->next = list_head; /* Update list head */ list_head->prev = table_desc; } else { table_desc->count = 1; } } /* Common initialization of the table descriptor */ table_desc->pointer = table_info->pointer; table_desc->base_pointer = table_info->base_pointer; table_desc->length = table_info->length; table_desc->allocation = table_info->allocation; table_desc->aml_start = (u8 *) (table_desc->pointer + 1), table_desc->aml_length = (u32) (table_desc->length - (u32) sizeof (acpi_table_header)); table_desc->table_id = acpi_ut_allocate_owner_id (OWNER_TYPE_TABLE); table_desc->loaded_into_namespace = FALSE; /* * Set the appropriate global pointer (if there is one) to point to the * newly installed table */ if (acpi_gbl_acpi_table_data[table_type].global_ptr) { *(acpi_gbl_acpi_table_data[table_type].global_ptr) = table_info->pointer; } /* Return Data */ table_info->table_id = table_desc->table_id; table_info->installed_desc = table_desc; return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiRsSetSrsMethodData ( ACPI_HANDLE Handle, ACPI_BUFFER *InBuffer) { ACPI_OPERAND_OBJECT *Params[2]; ACPI_OPERAND_OBJECT ParamObj; ACPI_STATUS Status; UINT8 *ByteStream = NULL; UINT32 BufferSizeNeeded = 0; FUNCTION_TRACE ("RsSetSrsMethodData"); /* already validated params, so we won't repeat here */ /* * The InBuffer parameter will point to a linked list of * resource parameters. It needs to be formatted into a * byte stream to be sent in as an input parameter. */ BufferSizeNeeded = 0; /* * First call is to get the buffer size needed */ Status = AcpiRsCreateByteStream (InBuffer->Pointer, ByteStream, &BufferSizeNeeded); /* * We expect a return of AE_BUFFER_OVERFLOW * if not, exit with the error */ if (AE_BUFFER_OVERFLOW != Status) { return_ACPI_STATUS (Status); } /* * Allocate the buffer needed */ ByteStream = ACPI_MEM_CALLOCATE (BufferSizeNeeded); if (NULL == ByteStream) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * Now call to convert the linked list into a byte stream */ Status = AcpiRsCreateByteStream (InBuffer->Pointer, ByteStream, &BufferSizeNeeded); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* * Init the param object */ AcpiUtInitStaticObject (&ParamObj); /* * Method requires one parameter. Set it up */ Params [0] = &ParamObj; Params [1] = NULL; /* * Set up the parameter object */ ParamObj.Common.Type = ACPI_TYPE_BUFFER; ParamObj.Buffer.Length = BufferSizeNeeded; ParamObj.Buffer.Pointer = ByteStream; /* * Execute the method, no return value */ Status = AcpiNsEvaluateRelative (Handle, "_SRS", Params, NULL); /* * Clean up and return the status from AcpiNsEvaluateRelative */ Cleanup: ACPI_MEM_FREE (ByteStream); return_ACPI_STATUS (Status); }
acpi_status acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) { acpi_status status; struct acpi_namespace_node *node; struct acpi_device_info *info; struct acpi_device_info *return_info; struct acpi_compatible_id_list *cid_list = NULL; acpi_size size; /* Parameter validation */ if (!handle || !buffer) { return (AE_BAD_PARAMETER); } status = acpi_ut_validate_buffer(buffer); if (ACPI_FAILURE(status)) { return (status); } info = ACPI_MEM_CALLOCATE(sizeof(struct acpi_device_info)); if (!info) { return (AE_NO_MEMORY); } status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { goto cleanup; } node = acpi_ns_map_handle_to_node(handle); if (!node) { (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); goto cleanup; } /* Init return structure */ size = sizeof(struct acpi_device_info); info->type = node->type; info->name = node->name.integer; info->valid = 0; status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { goto cleanup; } /* If not a device, we are all done */ if (info->type == ACPI_TYPE_DEVICE) { /* * Get extra info for ACPI Devices objects only: * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. * * Note: none of these methods are required, so they may or may * not be present for this device. The Info->Valid bitfield is used * to indicate which methods were found and ran successfully. */ /* Execute the Device._HID method */ status = acpi_ut_execute_HID(node, &info->hardware_id); if (ACPI_SUCCESS(status)) { info->valid |= ACPI_VALID_HID; } /* Execute the Device._UID method */ status = acpi_ut_execute_UID(node, &info->unique_id); if (ACPI_SUCCESS(status)) { info->valid |= ACPI_VALID_UID; } /* Execute the Device._CID method */ status = acpi_ut_execute_CID(node, &cid_list); if (ACPI_SUCCESS(status)) { size += ((acpi_size) cid_list->count - 1) * sizeof(struct acpi_compatible_id); info->valid |= ACPI_VALID_CID; } /* Execute the Device._STA method */ status = acpi_ut_execute_STA(node, &info->current_status); if (ACPI_SUCCESS(status)) { info->valid |= ACPI_VALID_STA; } /* Execute the Device._ADR method */ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, &info->address); if (ACPI_SUCCESS(status)) { info->valid |= ACPI_VALID_ADR; } /* Execute the Device._sx_d methods */ status = acpi_ut_execute_sxds(node, info->highest_dstates); if (ACPI_SUCCESS(status)) { info->valid |= ACPI_VALID_SXDS; } } /* Validate/Allocate/Clear caller buffer */ status = acpi_ut_initialize_buffer(buffer, size); if (ACPI_FAILURE(status)) { goto cleanup; } /* Populate the return buffer */ return_info = buffer->pointer; ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info)); if (cid_list) { ACPI_MEMCPY(&return_info->compatibility_id, cid_list, cid_list->size); } cleanup: ACPI_MEM_FREE(info); if (cid_list) { ACPI_MEM_FREE(cid_list); } return (status); }
ACPI_STATUS AcpiTbConvertTableFadt (void) { FADT_DESCRIPTOR_REV2 *LocalFadt; ACPI_TABLE_DESC *TableDesc; ACPI_FUNCTION_TRACE ("TbConvertTableFadt"); /* * AcpiGbl_FADT is valid * Allocate and zero the 2.0 FADT buffer */ LocalFadt = ACPI_MEM_CALLOCATE (sizeof (FADT_DESCRIPTOR_REV2)); if (LocalFadt == NULL) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * FADT length and version validation. The table must be at least as * long as the version 1.0 FADT */ if (AcpiGbl_FADT->Header.Length < sizeof (FADT_DESCRIPTOR_REV1)) { ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", AcpiGbl_FADT->Header.Length)); return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); } if (AcpiGbl_FADT->Header.Revision >= FADT2_REVISION_ID) { if (AcpiGbl_FADT->Header.Length < sizeof (FADT_DESCRIPTOR_REV2)) { /* Length is too short to be a V2.0 table */ ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n", AcpiGbl_FADT->Header.Length, AcpiGbl_FADT->Header.Revision)); AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT); } else { /* Valid V2.0 table */ AcpiTbConvertFadt2 (LocalFadt, AcpiGbl_FADT); } } else { /* Valid V1.0 table */ AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT); } /* * Global FADT pointer will point to the new common V2.0 FADT */ AcpiGbl_FADT = LocalFadt; AcpiGbl_FADT->Header.Length = sizeof (FADT_DESCRIPTOR); /* Free the original table */ TableDesc = &AcpiGbl_AcpiTables[ACPI_TABLE_FADT]; AcpiTbDeleteSingleTable (TableDesc); /* Install the new table */ TableDesc->Pointer = (ACPI_TABLE_HEADER *) AcpiGbl_FADT; TableDesc->Allocation = ACPI_MEM_ALLOCATED; TableDesc->Length = sizeof (FADT_DESCRIPTOR_REV2); /* Dump the entire FADT */ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Hex dump of common internal FADT, size %d (%X)\n", AcpiGbl_FADT->Header.Length, AcpiGbl_FADT->Header.Length)); ACPI_DUMP_BUFFER ((UINT8 *) (AcpiGbl_FADT), AcpiGbl_FADT->Header.Length); return_ACPI_STATUS (AE_OK); }
NATIVE_CHAR * acpi_ns_get_table_pathname ( acpi_namespace_node *node) { NATIVE_CHAR *name_buffer; u32 size; acpi_name name; acpi_namespace_node *child_node; acpi_namespace_node *parent_node; FUNCTION_TRACE_PTR ("Ns_get_table_pathname", node); if (!acpi_gbl_root_node || !node) { /* * If the name space has not been initialized, * this function should not have been called. */ return_PTR (NULL); } child_node = node->child; /* Calculate required buffer size based on depth below root */ size = 1; parent_node = child_node; while (parent_node) { parent_node = acpi_ns_get_parent_object (parent_node); if (parent_node) { size += ACPI_NAME_SIZE; } } /* Allocate a buffer to be returned to caller */ name_buffer = ACPI_MEM_CALLOCATE (size + 1); if (!name_buffer) { REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n")); return_PTR (NULL); } /* Store terminator byte, then build name backwards */ name_buffer[size] = '\0'; while ((size > ACPI_NAME_SIZE) && acpi_ns_get_parent_object (child_node)) { size -= ACPI_NAME_SIZE; name = acpi_ns_find_parent_name (child_node); /* Put the name into the buffer */ MOVE_UNALIGNED32_TO_32 ((name_buffer + size), &name); child_node = acpi_ns_get_parent_object (child_node); } name_buffer[--size] = AML_ROOT_PREFIX; if (size != 0) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad pointer returned; size=%X\n", size)); } return_PTR (name_buffer); }
acpi_status acpi_ut_copy_ielement_to_ielement ( u8 object_type, union acpi_operand_object *source_object, union acpi_generic_state *state, void *context) { acpi_status status = AE_OK; u32 this_index; union acpi_operand_object **this_target_ptr; union acpi_operand_object *target_object; ACPI_FUNCTION_ENTRY (); this_index = state->pkg.index; this_target_ptr = (union acpi_operand_object **) &state->pkg.dest_object->package.elements[this_index]; switch (object_type) { case ACPI_COPY_TYPE_SIMPLE: /* A null source object indicates a (legal) null package element */ if (source_object) { /* * This is a simple object, just copy it */ target_object = acpi_ut_create_internal_object ( ACPI_GET_OBJECT_TYPE (source_object)); if (!target_object) { return (AE_NO_MEMORY); } status = acpi_ut_copy_simple_object (source_object, target_object); if (ACPI_FAILURE (status)) { goto error_exit; } *this_target_ptr = target_object; } else { /* Pass through a null element */ *this_target_ptr = NULL; } break; case ACPI_COPY_TYPE_PACKAGE: /* * This object is a package - go down another nesting level * Create and build the package object */ target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE); if (!target_object) { return (AE_NO_MEMORY); } target_object->package.count = source_object->package.count; target_object->common.flags = source_object->common.flags; /* * Create the object array */ target_object->package.elements = ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) * sizeof (void *)); if (!target_object->package.elements) { status = AE_NO_MEMORY; goto error_exit; } /* * Pass the new package object back to the package walk routine */ state->pkg.this_target_obj = target_object; /* * Store the object pointer in the parent package object */ *this_target_ptr = target_object; break; default: return (AE_BAD_PARAMETER); } return (status); error_exit: acpi_ut_remove_reference (target_object); return (status); }
acpi_status acpi_ut_copy_esimple_to_isimple ( union acpi_object *external_object, union acpi_operand_object **ret_internal_object) { union acpi_operand_object *internal_object; ACPI_FUNCTION_TRACE ("ut_copy_esimple_to_isimple"); /* * Simple types supported are: String, Buffer, Integer */ switch (external_object->type) { case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: case ACPI_TYPE_INTEGER: internal_object = acpi_ut_create_internal_object ((u8) external_object->type); if (!internal_object) { return_ACPI_STATUS (AE_NO_MEMORY); } break; default: /* All other types are not supported */ return_ACPI_STATUS (AE_SUPPORT); } /* Must COPY string and buffer contents */ switch (external_object->type) { case ACPI_TYPE_STRING: internal_object->string.pointer = ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1); if (!internal_object->string.pointer) { goto error_exit; } ACPI_MEMCPY (internal_object->string.pointer, external_object->string.pointer, external_object->string.length); internal_object->string.length = external_object->string.length; break; case ACPI_TYPE_BUFFER: internal_object->buffer.pointer = ACPI_MEM_CALLOCATE (external_object->buffer.length); if (!internal_object->buffer.pointer) { goto error_exit; } ACPI_MEMCPY (internal_object->buffer.pointer, external_object->buffer.pointer, external_object->buffer.length); internal_object->buffer.length = external_object->buffer.length; break; case ACPI_TYPE_INTEGER: internal_object->integer.value = external_object->integer.value; break; default: /* Other types can't get here */ break; } *ret_internal_object = internal_object; return_ACPI_STATUS (AE_OK); error_exit: acpi_ut_remove_reference (internal_object); return_ACPI_STATUS (AE_NO_MEMORY); }
acpi_status acpi_ev_create_gpe_block ( struct acpi_namespace_node *gpe_device, struct acpi_generic_address *gpe_block_address, u32 register_count, u8 gpe_block_base_number, u32 interrupt_level, struct acpi_gpe_block_info **return_gpe_block) { struct acpi_gpe_block_info *gpe_block; acpi_status status; ACPI_FUNCTION_TRACE ("ev_create_gpe_block"); if (!register_count) { return_ACPI_STATUS (AE_OK); } /* Allocate a new GPE block */ gpe_block = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_block_info)); if (!gpe_block) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Initialize the new GPE block */ gpe_block->register_count = register_count; gpe_block->block_base_number = gpe_block_base_number; ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address)); /* Create the register_info and event_info sub-structures */ status = acpi_ev_create_gpe_info_blocks (gpe_block); if (ACPI_FAILURE (status)) { ACPI_MEM_FREE (gpe_block); return_ACPI_STATUS (status); } /* Install the new block in the global list(s) */ status = acpi_ev_install_gpe_block (gpe_block, interrupt_level); if (ACPI_FAILURE (status)) { ACPI_MEM_FREE (gpe_block); return_ACPI_STATUS (status); } /* Dump info about this GPE block */ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n", gpe_block->block_base_number, (u32) (gpe_block->block_base_number + ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)), gpe_device->name.ascii, gpe_block->register_count, ACPI_HIDWORD (gpe_block->block_address.address), ACPI_LODWORD (gpe_block->block_address.address), interrupt_level)); /* Find all GPE methods (_Lxx, _Exx) for this block */ status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ev_save_method_info, gpe_block, NULL); /* Return the new block */ if (return_gpe_block) { (*return_gpe_block) = gpe_block; } return_ACPI_STATUS (AE_OK); }
acpi_status acpi_ev_pci_config_region_setup ( acpi_handle handle, u32 function, void *handler_context, void **region_context) { acpi_status status = AE_OK; acpi_integer pci_value; struct acpi_pci_id *pci_id = *region_context; union acpi_operand_object *handler_obj; struct acpi_namespace_node *parent_node; struct acpi_namespace_node *pci_root_node; union acpi_operand_object *region_obj = (union acpi_operand_object *) handle; struct acpi_device_id object_hID; ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup"); handler_obj = region_obj->region.handler; if (!handler_obj) { /* * No installed handler. This shouldn't happen because the dispatch * routine checks before we get here, but we check again just in case. */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Attempting to init a region %p, with no handler\n", region_obj)); return_ACPI_STATUS (AE_NOT_EXIST); } *region_context = NULL; if (function == ACPI_REGION_DEACTIVATE) { if (pci_id) { ACPI_MEM_FREE (pci_id); } return_ACPI_STATUS (status); } parent_node = acpi_ns_get_parent_node (region_obj->region.node); /* * Get the _SEG and _BBN values from the device upon which the handler * is installed. * * We need to get the _SEG and _BBN objects relative to the PCI BUS device. * This is the device the handler has been registered to handle. */ /* * If the address_space.Node is still pointing to the root, we need * to scan upward for a PCI Root bridge and re-associate the op_region * handlers with that device. */ if (handler_obj->address_space.node == acpi_gbl_root_node) { /* Start search from the parent object */ pci_root_node = parent_node; while (pci_root_node != acpi_gbl_root_node) { status = acpi_ut_execute_HID (pci_root_node, &object_hID); if (ACPI_SUCCESS (status)) { /* Got a valid _HID, check if this is a PCI root */ if (!(ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING, sizeof (PCI_ROOT_HID_STRING)))) { /* Install a handler for this PCI root bridge */ status = acpi_install_address_space_handler ((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); if (ACPI_FAILURE (status)) { if (status == AE_SAME_HANDLER) { /* * It is OK if the handler is already installed on the root * bridge. Still need to return a context object for the * new PCI_Config operation region, however. */ status = AE_OK; } else { ACPI_REPORT_ERROR (( "Could not install pci_config handler for Root Bridge %4.4s, %s\n", acpi_ut_get_node_name (pci_root_node), acpi_format_exception (status))); } } break; } } pci_root_node = acpi_ns_get_parent_node (pci_root_node); } /* PCI root bridge not found, use namespace root node */ } else { pci_root_node = handler_obj->address_space.node; } /* * If this region is now initialized, we are done. * (install_address_space_handler could have initialized it) */ if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) { return_ACPI_STATUS (AE_OK); } /* Region is still not initialized. Create a new context */ pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id)); if (!pci_id) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * For PCI_Config space access, we need the segment, bus, * device and function numbers. Acquire them here. */ /* * 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, parent_node, &pci_value); /* * The default is zero, and since the allocation above zeroed * the data, just do nothing on failure. */ if (ACPI_SUCCESS (status)) { pci_id->device = ACPI_HIWORD (ACPI_LODWORD (pci_value)); pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value)); } /* The PCI segment number comes from the _SEG method */ status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, pci_root_node, &pci_value); if (ACPI_SUCCESS (status)) { pci_id->segment = ACPI_LOWORD (pci_value); } /* The PCI bus number comes from the _BBN method */ status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, pci_root_node, &pci_value); if (ACPI_SUCCESS (status)) { pci_id->bus = ACPI_LOWORD (pci_value); } /* Complete this device's pci_id */ acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id); *region_context = pci_id; return_ACPI_STATUS (AE_OK); }
acpi_status acpi_ns_externalize_name ( u32 internal_name_length, char *internal_name, u32 *converted_name_length, char **converted_name) { u32 prefix_length = 0; u32 names_index = 0; u32 names_count = 0; u32 i = 0; u32 j = 0; FUNCTION_TRACE ("Ns_externalize_name"); if (!internal_name_length || !internal_name || !converted_name_length || !converted_name) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* * Check for a prefix (one '\' | one or more '^'). */ switch (internal_name[0]) { case '\\': prefix_length = 1; break; case '^': for (i = 0; i < internal_name_length; i++) { if (internal_name[i] != '^') { prefix_length = i + 1; } } if (i == internal_name_length) { prefix_length = i; } break; } /* * Check for object names. Note that there could be 0-255 of these * 4-byte elements. */ if (prefix_length < internal_name_length) { switch (internal_name[prefix_length]) { /* <count> 4-byte names */ case AML_MULTI_NAME_PREFIX_OP: names_index = prefix_length + 2; names_count = (u32) internal_name[prefix_length + 1]; break; /* two 4-byte names */ case AML_DUAL_NAME_PREFIX: names_index = prefix_length + 1; names_count = 2; break; /* Null_name */ case 0: names_index = 0; names_count = 0; break; /* one 4-byte name */ default: names_index = prefix_length; names_count = 1; break; } } /* * Calculate the length of Converted_name, which equals the length * of the prefix, length of all object names, length of any required * punctuation ('.') between object names, plus the NULL terminator. */ *converted_name_length = prefix_length + (4 * names_count) + ((names_count > 0) ? (names_count - 1) : 0) + 1; /* * Check to see if we're still in bounds. If not, there's a problem * with Internal_name (invalid format). */ if (*converted_name_length > internal_name_length) { REPORT_ERROR (("Ns_externalize_name: Invalid internal name\n")); return_ACPI_STATUS (AE_BAD_PATHNAME); } /* * Build Converted_name... */ (*converted_name) = ACPI_MEM_CALLOCATE (*converted_name_length); if (!(*converted_name)) { return_ACPI_STATUS (AE_NO_MEMORY); } j = 0; for (i = 0; i < prefix_length; i++) { (*converted_name)[j++] = internal_name[i]; } if (names_count > 0) { for (i = 0; i < names_count; i++) { if (i > 0) { (*converted_name)[j++] = '.'; } (*converted_name)[j++] = internal_name[names_index++]; (*converted_name)[j++] = internal_name[names_index++]; (*converted_name)[j++] = internal_name[names_index++]; (*converted_name)[j++] = internal_name[names_index++]; } } return_ACPI_STATUS (AE_OK); }
acpi_status acpi_ns_externalize_name ( u32 internal_name_length, char *internal_name, u32 *converted_name_length, char **converted_name) { acpi_native_uint names_index = 0; acpi_native_uint num_segments = 0; acpi_native_uint required_length; acpi_native_uint prefix_length = 0; acpi_native_uint i = 0; acpi_native_uint j = 0; ACPI_FUNCTION_TRACE ("ns_externalize_name"); if (!internal_name_length || !internal_name || !converted_name) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* * Check for a prefix (one '\' | one or more '^'). */ switch (internal_name[0]) { case '\\': prefix_length = 1; break; case '^': for (i = 0; i < internal_name_length; i++) { if (internal_name[i] == '^') { prefix_length = i + 1; } else { break; } } if (i == internal_name_length) { prefix_length = i; } break; default: break; } /* * Check for object names. Note that there could be 0-255 of these * 4-byte elements. */ if (prefix_length < internal_name_length) { switch (internal_name[prefix_length]) { case AML_MULTI_NAME_PREFIX_OP: /* <count> 4-byte names */ names_index = prefix_length + 2; num_segments = (acpi_native_uint) (u8) internal_name[(acpi_native_uint) (prefix_length + 1)]; break; case AML_DUAL_NAME_PREFIX: /* Two 4-byte names */ names_index = prefix_length + 1; num_segments = 2; break; case 0: /* null_name */ names_index = 0; num_segments = 0; break; default: /* one 4-byte name */ names_index = prefix_length; num_segments = 1; break; } } /* * Calculate the length of converted_name, which equals the length * of the prefix, length of all object names, length of any required * punctuation ('.') between object names, plus the NULL terminator. */ required_length = prefix_length + (4 * num_segments) + ((num_segments > 0) ? (num_segments - 1) : 0) + 1; /* * Check to see if we're still in bounds. If not, there's a problem * with internal_name (invalid format). */ if (required_length > internal_name_length) { ACPI_REPORT_ERROR (("ns_externalize_name: Invalid internal name\n")); return_ACPI_STATUS (AE_BAD_PATHNAME); } /* * Build converted_name */ *converted_name = ACPI_MEM_CALLOCATE (required_length); if (!(*converted_name)) { return_ACPI_STATUS (AE_NO_MEMORY); } j = 0; for (i = 0; i < prefix_length; i++) { (*converted_name)[j++] = internal_name[i]; } if (num_segments > 0) { for (i = 0; i < num_segments; i++) { if (i > 0) { (*converted_name)[j++] = '.'; } (*converted_name)[j++] = internal_name[names_index++]; (*converted_name)[j++] = internal_name[names_index++]; (*converted_name)[j++] = internal_name[names_index++]; (*converted_name)[j++] = internal_name[names_index++]; } } if (converted_name_length) { *converted_name_length = (u32) required_length; } return_ACPI_STATUS (AE_OK); }
acpi_status acpi_ex_do_concatenate ( union acpi_operand_object *obj_desc1, union acpi_operand_object *obj_desc2, union acpi_operand_object **actual_return_desc, struct acpi_walk_state *walk_state) { acpi_status status; u32 i; acpi_integer this_integer; union acpi_operand_object *return_desc; char *new_buf; ACPI_FUNCTION_ENTRY (); /* * There are three cases to handle: * * 1) Two Integers concatenated to produce a new Buffer * 2) Two Strings concatenated to produce a new String * 3) Two Buffers concatenated to produce a new Buffer */ switch (ACPI_GET_OBJECT_TYPE (obj_desc1)) { case ACPI_TYPE_INTEGER: /* Result of two Integers is a Buffer */ /* Need enough buffer space for two integers */ return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width * 2); if (!return_desc) { return (AE_NO_MEMORY); } new_buf = (char *) return_desc->buffer.pointer; /* Convert the first integer */ this_integer = obj_desc1->integer.value; for (i = 0; i < acpi_gbl_integer_byte_width; i++) { new_buf[i] = (char) this_integer; this_integer >>= 8; } /* Convert the second integer */ this_integer = obj_desc2->integer.value; for (; i < (ACPI_MUL_2 (acpi_gbl_integer_byte_width)); i++) { new_buf[i] = (char) this_integer; this_integer >>= 8; } break; case ACPI_TYPE_STRING: /* Result of two Strings is a String */ return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); if (!return_desc) { return (AE_NO_MEMORY); } /* Operand0 is string */ new_buf = ACPI_MEM_CALLOCATE ((acpi_size) obj_desc1->string.length + (acpi_size) obj_desc2->string.length + 1); if (!new_buf) { ACPI_REPORT_ERROR (("ex_do_concatenate: String allocation failure\n")); status = AE_NO_MEMORY; goto cleanup; } /* Concatenate the strings */ ACPI_STRCPY (new_buf, obj_desc1->string.pointer); ACPI_STRCPY (new_buf + obj_desc1->string.length, obj_desc2->string.pointer); /* Complete the String object initialization */ return_desc->string.pointer = new_buf; return_desc->string.length = obj_desc1->string.length + obj_desc2->string.length; break; case ACPI_TYPE_BUFFER: /* Result of two Buffers is a Buffer */ return_desc = acpi_ut_create_buffer_object ( (acpi_size) obj_desc1->buffer.length + (acpi_size) obj_desc2->buffer.length); if (!return_desc) { return (AE_NO_MEMORY); } new_buf = (char *) return_desc->buffer.pointer; /* Concatenate the buffers */ ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer, obj_desc1->buffer.length); ACPI_MEMCPY (new_buf + obj_desc1->buffer.length, obj_desc2->buffer.pointer, obj_desc2->buffer.length); break; default: /* Invalid object type, should not happen here */ ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n", ACPI_GET_OBJECT_TYPE (obj_desc1))); status = AE_AML_INTERNAL; return_desc = NULL; } *actual_return_desc = return_desc; return (AE_OK); cleanup: acpi_ut_remove_reference (return_desc); return (status); }
static acpi_status acpi_ev_create_gpe_info_blocks ( struct acpi_gpe_block_info *gpe_block) { struct acpi_gpe_register_info *gpe_register_info = NULL; struct acpi_gpe_event_info *gpe_event_info = NULL; struct acpi_gpe_event_info *this_event; struct acpi_gpe_register_info *this_register; acpi_native_uint i; acpi_native_uint j; acpi_status status; ACPI_FUNCTION_TRACE ("ev_create_gpe_info_blocks"); /* Allocate the GPE register information block */ gpe_register_info = ACPI_MEM_CALLOCATE ( (acpi_size) gpe_block->register_count * sizeof (struct acpi_gpe_register_info)); if (!gpe_register_info) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_register_info table\n")); return_ACPI_STATUS (AE_NO_MEMORY); } /* * Allocate the GPE event_info block. There are eight distinct GPEs * per register. Initialization to zeros is sufficient. */ gpe_event_info = ACPI_MEM_CALLOCATE ( ((acpi_size) gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) * sizeof (struct acpi_gpe_event_info)); if (!gpe_event_info) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_event_info table\n")); status = AE_NO_MEMORY; goto error_exit; } /* Save the new Info arrays in the GPE block */ gpe_block->register_info = gpe_register_info; gpe_block->event_info = gpe_event_info; /* * Initialize the GPE Register and Event structures. A goal of these * tables is to hide the fact that there are two separate GPE register sets * in a given gpe hardware block, the status registers occupy the first half, * and the enable registers occupy the second half. */ this_register = gpe_register_info; this_event = gpe_event_info; for (i = 0; i < gpe_block->register_count; i++) { /* Init the register_info for this GPE register (8 GPEs) */ this_register->base_gpe_number = (u8) (gpe_block->block_base_number + (i * ACPI_GPE_REGISTER_WIDTH)); ACPI_STORE_ADDRESS (this_register->status_address.address, (gpe_block->block_address.address + i)); ACPI_STORE_ADDRESS (this_register->enable_address.address, (gpe_block->block_address.address + i + gpe_block->register_count)); this_register->status_address.address_space_id = gpe_block->block_address.address_space_id; this_register->enable_address.address_space_id = gpe_block->block_address.address_space_id; this_register->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH; this_register->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH; this_register->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH; this_register->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH; /* Init the event_info for each GPE within this register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { this_event->bit_mask = acpi_gbl_decode_to8bit[j]; this_event->register_info = this_register; this_event++; } /* * Clear the status/enable registers. Note that status registers * are cleared by writing a '1', while enable registers are cleared * by writing a '0'. */ status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00, &this_register->enable_address); if (ACPI_FAILURE (status)) { goto error_exit; } status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF, &this_register->status_address); if (ACPI_FAILURE (status)) { goto error_exit; } this_register++; } return_ACPI_STATUS (AE_OK); error_exit: if (gpe_register_info) { ACPI_MEM_FREE (gpe_register_info); } if (gpe_event_info) { ACPI_MEM_FREE (gpe_event_info); } return_ACPI_STATUS (status); }