ACPI_STATUS acpi_cm_execute_UID ( ACPI_NAMESPACE_NODE *device_node, DEVICE_ID *uid) { ACPI_OPERAND_OBJECT *obj_desc; ACPI_STATUS status; /* Execute the method */ status = acpi_ns_evaluate_relative (device_node, METHOD_NAME__UID, NULL, &obj_desc); if (ACPI_FAILURE (status)) { return (status); } /* Did we get a return object? */ if (!obj_desc) { return (AE_TYPE); } /* * A _UID can return either a Number (32 bit compressed EISA ID) or * a string */ if ((obj_desc->common.type != ACPI_TYPE_NUMBER) && (obj_desc->common.type != ACPI_TYPE_STRING)) { status = AE_TYPE; } else { if (obj_desc->common.type == ACPI_TYPE_NUMBER) { /* Convert the Numeric UID to string */ acpi_aml_unsigned_integer_to_string (obj_desc->number.value, uid->buffer); } else { /* Copy the String UID from the returned object */ STRNCPY(uid->buffer, obj_desc->string.pointer, sizeof(uid->buffer)); } } /* On exit, we must delete the return object */ acpi_cm_remove_reference (obj_desc); return (status); }
ACPI_STATUS acpi_cm_execute_STA ( ACPI_NAMESPACE_NODE *device_node, u32 *flags) { ACPI_OPERAND_OBJECT *obj_desc; ACPI_STATUS status; /* Execute the method */ status = acpi_ns_evaluate_relative (device_node, METHOD_NAME__STA, NULL, &obj_desc); if (AE_NOT_FOUND == status) { *flags = 0x0F; status = AE_OK; } else /* success */ { /* Did we get a return object? */ if (!obj_desc) { return (AE_TYPE); } /* Is the return object of the correct type? */ if (obj_desc->common.type != ACPI_TYPE_NUMBER) { status = AE_TYPE; } else { /* Extract the status flags */ *flags = (u32) obj_desc->number.value; } /* On exit, we must delete the return object */ acpi_cm_remove_reference (obj_desc); } return (status); }
ACPI_STATUS acpi_cm_evaluate_numeric_object ( NATIVE_CHAR *object_name, ACPI_NAMESPACE_NODE *device_node, ACPI_INTEGER *address) { ACPI_OPERAND_OBJECT *obj_desc; ACPI_STATUS status; /* Execute the method */ status = acpi_ns_evaluate_relative (device_node, object_name, NULL, &obj_desc); if (ACPI_FAILURE (status)) { return (status); } /* Did we get a return object? */ if (!obj_desc) { return (AE_TYPE); } /* Is the return object of the correct type? */ if (obj_desc->common.type != ACPI_TYPE_NUMBER) { status = AE_TYPE; } else { /* * Since the structure is a union, setting any field will set all * of the variables in the union */ *address = obj_desc->number.value; } /* On exit, we must delete the return object */ acpi_cm_remove_reference (obj_desc); return (status); }
acpi_status acpi_ns_init_one_device ( acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { acpi_status status; acpi_namespace_node *node; u32 flags; acpi_device_walk_info *info = (acpi_device_walk_info *) context; FUNCTION_TRACE ("Ns_init_one_device"); if (!(acpi_dbg_level & ACPI_LV_INIT)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, ".")); } info->device_count++; acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); node = acpi_ns_map_handle_to_node (obj_handle); if (!node) { acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); /* * Run _STA to determine if we can run _INI on the device. */ DEBUG_EXEC (acpi_ut_display_init_pathname (node, "_STA [Method]")); status = acpi_ut_execute_STA (node, &flags); if (ACPI_FAILURE (status)) { /* Ignore error and move on to next device */ return_ACPI_STATUS (AE_OK); } info->num_STA++; if (!(flags & 0x01)) { /* don't look at children of a not present device */ return_ACPI_STATUS(AE_CTRL_DEPTH); } /* * The device is present. Run _INI. */ DEBUG_EXEC (acpi_ut_display_init_pathname (obj_handle, "_INI [Method]")); status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL); if (AE_NOT_FOUND == status) { /* No _INI means device requires no initialization */ status = AE_OK; } else if (ACPI_FAILURE (status)) { /* Ignore error and move on to next device */ #ifdef ACPI_DEBUG NATIVE_CHAR *scope_name = acpi_ns_get_table_pathname (obj_handle); ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n", scope_name, acpi_format_exception (status))); ACPI_MEM_FREE (scope_name); #endif } else { /* Count of successful INIs */ info->num_INI++; } return_ACPI_STATUS (AE_OK); }
acpi_status acpi_evaluate_object ( acpi_handle handle, acpi_string pathname, struct acpi_object_list *external_params, struct acpi_buffer *return_buffer) { acpi_status status; acpi_status status2; struct acpi_parameter_info info; acpi_size buffer_space_needed; u32 i; ACPI_FUNCTION_TRACE ("acpi_evaluate_object"); info.node = handle; info.parameters = NULL; info.return_object = NULL; info.parameter_type = ACPI_PARAM_ARGS; /* * If there are parameters to be passed to the object * (which must be a control method), the external objects * must be converted to internal objects */ if (external_params && external_params->count) { /* * Allocate a new parameter block for the internal objects * Add 1 to count to allow for null terminated internal list */ info.parameters = ACPI_MEM_CALLOCATE ( ((acpi_size) external_params->count + 1) * sizeof (void *)); if (!info.parameters) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * Convert each external object in the list to an * internal object */ for (i = 0; i < external_params->count; i++) { status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i], &info.parameters[i]); if (ACPI_FAILURE (status)) { acpi_ut_delete_internal_object_list (info.parameters); return_ACPI_STATUS (status); } } info.parameters[external_params->count] = NULL; } /* * Three major cases: * 1) Fully qualified pathname * 2) No handle, not fully qualified pathname (error) * 3) Valid handle */ if ((pathname) && (acpi_ns_valid_root_prefix (pathname[0]))) { /* * The path is fully qualified, just evaluate by name */ status = acpi_ns_evaluate_by_name (pathname, &info); } else if (!handle) { /* * A handle is optional iff a fully qualified pathname * is specified. Since we've already handled fully * qualified names above, this is an error */ if (!pathname) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Both Handle and Pathname are NULL\n")); } else { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Handle is NULL and Pathname is relative\n")); } status = AE_BAD_PARAMETER; } else { /* * We get here if we have a handle -- and if we have a * pathname it is relative. The handle will be validated * in the lower procedures */ if (!pathname) { /* * The null pathname case means the handle is for * the actual object to be evaluated */ status = acpi_ns_evaluate_by_handle (&info); } else { /* * Both a Handle and a relative Pathname */ status = acpi_ns_evaluate_relative (pathname, &info); } } /* * If we are expecting a return value, and all went well above, * copy the return value to an external object. */ if (return_buffer) { if (!info.return_object) { return_buffer->length = 0; } else { if (ACPI_GET_DESCRIPTOR_TYPE (info.return_object) == ACPI_DESC_TYPE_NAMED) { /* * If we received a NS Node as a return object, this means that * the object we are evaluating has nothing interesting to * return (such as a mutex, etc.) We return an error because * these types are essentially unsupported by this interface. * We don't check up front because this makes it easier to add * support for various types at a later date if necessary. */ status = AE_TYPE; info.return_object = NULL; /* No need to delete a NS Node */ return_buffer->length = 0; } if (ACPI_SUCCESS (status)) { /* * Find out how large a buffer is needed * to contain the returned object */ status = acpi_ut_get_object_size (info.return_object, &buffer_space_needed); if (ACPI_SUCCESS (status)) { /* Validate/Allocate/Clear caller buffer */ status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed); if (ACPI_FAILURE (status)) { /* * Caller's buffer is too small or a new one can't be allocated */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Needed buffer size %X, %s\n", (u32) buffer_space_needed, acpi_format_exception (status))); } else { /* * We have enough space for the object, build it */ status = acpi_ut_copy_iobject_to_eobject (info.return_object, return_buffer); } } } } } if (info.return_object) { /* * Delete the internal return object. NOTE: Interpreter * must be locked to avoid race condition. */ status2 = acpi_ex_enter_interpreter (); if (ACPI_SUCCESS (status2)) { /* * Delete the internal return object. (Or at least * decrement the reference count by one) */ acpi_ut_remove_reference (info.return_object); acpi_ex_exit_interpreter (); } } /* * Free the input parameter list (if we created one), */ if (info.parameters) { /* Free the allocated parameter block */ acpi_ut_delete_internal_object_list (info.parameters); } return_ACPI_STATUS (status); }
acpi_status acpi_ut_evaluate_object ( struct acpi_namespace_node *prefix_node, char *path, u32 expected_return_btypes, union acpi_operand_object **return_desc) { struct acpi_parameter_info info; acpi_status status; u32 return_btype; ACPI_FUNCTION_TRACE ("ut_evaluate_object"); info.node = prefix_node; info.parameters = NULL; info.parameter_type = ACPI_PARAM_ARGS; /* Evaluate the object/method */ status = acpi_ns_evaluate_relative (path, &info); if (ACPI_FAILURE (status)) { if (status == AE_NOT_FOUND) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n", acpi_ut_get_node_name (prefix_node), path)); } else { ACPI_REPORT_METHOD_ERROR ("Method execution failed", prefix_node, path, status); } return_ACPI_STATUS (status); } /* Did we get a return object? */ if (!info.return_object) { if (expected_return_btypes) { ACPI_REPORT_METHOD_ERROR ("No object was returned from", prefix_node, path, AE_NOT_EXIST); return_ACPI_STATUS (AE_NOT_EXIST); } return_ACPI_STATUS (AE_OK); } /* Map the return object type to the bitmapped type */ switch (ACPI_GET_OBJECT_TYPE (info.return_object)) { case ACPI_TYPE_INTEGER: return_btype = ACPI_BTYPE_INTEGER; break; case ACPI_TYPE_BUFFER: return_btype = ACPI_BTYPE_BUFFER; break; case ACPI_TYPE_STRING: return_btype = ACPI_BTYPE_STRING; break; case ACPI_TYPE_PACKAGE: return_btype = ACPI_BTYPE_PACKAGE; break; default: return_btype = 0; break; } /* Is the return object one of the expected types? */ if (!(expected_return_btypes & return_btype)) { ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect", prefix_node, path, AE_TYPE); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Type returned from %s was incorrect: %X\n", path, ACPI_GET_OBJECT_TYPE (info.return_object))); /* On error exit, we must delete the return object */ acpi_ut_remove_reference (info.return_object); return_ACPI_STATUS (AE_TYPE); } /* Object type is OK, return it */ *return_desc = info.return_object; return_ACPI_STATUS (AE_OK); }
acpi_status acpi_rs_get_prt_method_data ( acpi_handle handle, acpi_buffer *ret_buffer) { acpi_operand_object *ret_obj; acpi_status status; u32 buffer_space_needed; FUNCTION_TRACE ("Rs_get_prt_method_data"); /* already validated params, so we won't repeat here */ buffer_space_needed = ret_buffer->length; /* * Execute the method, no parameters */ status = acpi_ns_evaluate_relative (handle, "_PRT", NULL, &ret_obj); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } if (!ret_obj) { /* Return object is required */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRT\n")); return_ACPI_STATUS (AE_TYPE); } /* * The return object will be a package, so check the * parameters. If the return object is not a package, * then the underlying AML code is corrupt or improperly * written. */ if (ACPI_TYPE_PACKAGE != ret_obj->common.type) { status = AE_AML_OPERAND_TYPE; goto cleanup; } /* * Make the call to create a resource linked list from the * byte stream buffer that comes back from the _CRS method * execution. */ status = acpi_rs_create_pci_routing_table (ret_obj, ret_buffer->pointer, &buffer_space_needed); /* * Tell the user how much of the buffer we have used or is needed * and return the final status. */ ret_buffer->length = buffer_space_needed; /* On exit, we must delete the object returned by evaluate_object */ cleanup: acpi_ut_remove_reference (ret_obj); return_ACPI_STATUS (status); }
acpi_status acpi_rs_set_srs_method_data ( acpi_handle handle, acpi_buffer *in_buffer) { acpi_operand_object *params[2]; acpi_status status; u8 *byte_stream = NULL; u32 buffer_size_needed = 0; FUNCTION_TRACE ("Rs_set_srs_method_data"); /* already validated params, so we won't repeat here */ /* * The In_buffer 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. */ buffer_size_needed = 0; /* * First call is to get the buffer size needed */ status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream, &buffer_size_needed); /* * 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 */ byte_stream = ACPI_MEM_CALLOCATE (buffer_size_needed); if (NULL == byte_stream) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * Now call to convert the linked list into a byte stream */ status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream, &buffer_size_needed); if (ACPI_FAILURE (status)) { goto cleanup; } /* * Init the param object */ params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); if (!params[0]) { status = AE_NO_MEMORY; goto cleanup; } params [1] = NULL; /* * Set up the parameter object */ params[0]->buffer.length = buffer_size_needed; params[0]->buffer.pointer = byte_stream; /* * Execute the method, no return value */ status = acpi_ns_evaluate_relative (handle, "_SRS", params, NULL); acpi_ut_remove_reference (params[0]); /* * Clean up and return the status from Acpi_ns_evaluate_relative */ cleanup: return_ACPI_STATUS (status); }
static acpi_status acpi_ns_init_one_device(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { struct acpi_device_walk_info *info = (struct acpi_device_walk_info *)context; struct acpi_parameter_info pinfo; u32 flags; acpi_status status; ACPI_FUNCTION_TRACE("ns_init_one_device"); pinfo.parameters = NULL; pinfo.parameter_type = ACPI_PARAM_ARGS; pinfo.node = acpi_ns_map_handle_to_node(obj_handle); if (!pinfo.node) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* * We will run _STA/_INI on Devices, Processors and thermal_zones only */ if ((pinfo.node->type != ACPI_TYPE_DEVICE) && (pinfo.node->type != ACPI_TYPE_PROCESSOR) && (pinfo.node->type != ACPI_TYPE_THERMAL)) { return_ACPI_STATUS(AE_OK); } if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) { ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); } info->device_count++; /* * Run _STA to determine if we can run _INI on the device. */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD, pinfo.node, METHOD_NAME__STA)); status = acpi_ut_execute_STA(pinfo.node, &flags); if (ACPI_FAILURE(status)) { if (pinfo.node->type == ACPI_TYPE_DEVICE) { /* Ignore error and move on to next device */ return_ACPI_STATUS(AE_OK); } /* _STA is not required for Processor or thermal_zone objects */ } else { info->num_STA++; if (!(flags & 0x01)) { /* Don't look at children of a not present device */ return_ACPI_STATUS(AE_CTRL_DEPTH); } } /* * The device is present. Run _INI. */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD, pinfo.node, METHOD_NAME__INI)); status = acpi_ns_evaluate_relative(METHOD_NAME__INI, &pinfo); if (ACPI_FAILURE(status)) { /* No _INI (AE_NOT_FOUND) means device requires no initialization */ if (status != AE_NOT_FOUND) { /* Ignore error and move on to next device */ #ifdef ACPI_DEBUG_OUTPUT char *scope_name = acpi_ns_get_external_pathname(pinfo.node); ACPI_DEBUG_PRINT((ACPI_DB_WARN, "%s._INI failed: %s\n", scope_name, acpi_format_exception(status))); ACPI_MEM_FREE(scope_name); #endif } status = AE_OK; } else { /* Delete any return object (especially if implicit_return is enabled) */ if (pinfo.return_object) { acpi_ut_remove_reference(pinfo.return_object); } /* Count of successful INIs */ info->num_INI++; } if (acpi_gbl_init_handler) { /* External initialization handler is present, call it */ status = acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI); } return_ACPI_STATUS(status); }
ACPI_STATUS acpi_evaluate_object ( ACPI_HANDLE handle, ACPI_STRING pathname, ACPI_OBJECT_LIST *param_objects, ACPI_BUFFER *return_buffer) { ACPI_STATUS status; ACPI_OPERAND_OBJECT **param_ptr = NULL; ACPI_OPERAND_OBJECT *return_obj = NULL; ACPI_OPERAND_OBJECT *object_ptr = NULL; u32 buffer_space_needed; u32 user_buffer_length; u32 count; u32 i; u32 param_length; u32 object_length; /* * If there are parameters to be passed to the object * (which must be a control method), the external objects * must be converted to internal objects */ if (param_objects && param_objects->count) { /* * Allocate a new parameter block for the internal objects * Add 1 to count to allow for null terminated internal list */ count = param_objects->count; param_length = (count + 1) * sizeof (void *); object_length = count * sizeof (ACPI_OPERAND_OBJECT); param_ptr = acpi_cm_callocate (param_length + /* Parameter List part */ object_length); /* Actual objects */ if (!param_ptr) { return (AE_NO_MEMORY); } object_ptr = (ACPI_OPERAND_OBJECT *) ((u8 *) param_ptr + param_length); /* * Init the param array of pointers and NULL terminate * the list */ for (i = 0; i < count; i++) { param_ptr[i] = &object_ptr[i]; acpi_cm_init_static_object (&object_ptr[i]); } param_ptr[count] = NULL; /* * Convert each external object in the list to an * internal object */ for (i = 0; i < count; i++) { status = acpi_cm_build_internal_object (¶m_objects->pointer[i], param_ptr[i]); if (ACPI_FAILURE (status)) { acpi_cm_delete_internal_object_list (param_ptr); return (status); } } } /* * Three major cases: * 1) Fully qualified pathname * 2) No handle, not fully qualified pathname (error) * 3) Valid handle */ if ((pathname) && (acpi_ns_valid_root_prefix (pathname[0]))) { /* * The path is fully qualified, just evaluate by name */ status = acpi_ns_evaluate_by_name (pathname, param_ptr, &return_obj); } else if (!handle) { /* * A handle is optional iff a fully qualified pathname * is specified. Since we've already handled fully * qualified names above, this is an error */ status = AE_BAD_PARAMETER; } else { /* * We get here if we have a handle -- and if we have a * pathname it is relative. The handle will be validated * in the lower procedures */ if (!pathname) { /* * The null pathname case means the handle is for * the actual object to be evaluated */ status = acpi_ns_evaluate_by_handle (handle, param_ptr, &return_obj); } else { /* * Both a Handle and a relative Pathname */ status = acpi_ns_evaluate_relative (handle, pathname, param_ptr, &return_obj); } } /* * If we are expecting a return value, and all went well above, * copy the return value to an external object. */ if (return_buffer) { user_buffer_length = return_buffer->length; return_buffer->length = 0; if (return_obj) { if (VALID_DESCRIPTOR_TYPE (return_obj, ACPI_DESC_TYPE_NAMED)) { /* * If we got an Node as a return object, * this means the object we are evaluating * has nothing interesting to return (such * as a mutex, etc.) We return an error * because these types are essentially * unsupported by this interface. We * don't check up front because this makes * it easier to add support for various * types at a later date if necessary. */ status = AE_TYPE; return_obj = NULL; /* No need to delete an Node */ } if (ACPI_SUCCESS (status)) { /* * Find out how large a buffer is needed * to contain the returned object */ status = acpi_cm_get_object_size (return_obj, &buffer_space_needed); if (ACPI_SUCCESS (status)) { /* * Check if there is enough room in the * caller's buffer */ if (user_buffer_length < buffer_space_needed) { /* * Caller's buffer is too small, can't * give him partial results fail the call * but return the buffer size needed */ return_buffer->length = buffer_space_needed; status = AE_BUFFER_OVERFLOW; } else { /* * We have enough space for the object, build it */ status = acpi_cm_build_external_object (return_obj, return_buffer); return_buffer->length = buffer_space_needed; } } } } } /* Delete the return and parameter objects */ if (return_obj) { /* * Delete the internal return object. (Or at least * decrement the reference count by one) */ acpi_cm_remove_reference (return_obj); } /* * Free the input parameter list (if we created one), */ if (param_ptr) { /* Free the allocated parameter block */ acpi_cm_delete_internal_object_list (param_ptr); } return (status); }
ACPI_STATUS acpi_ns_init_one_device ( ACPI_HANDLE obj_handle, u32 nesting_level, void *context, void **return_value) { ACPI_STATUS status; ACPI_NAMESPACE_NODE *node; u32 flags; ACPI_DEVICE_WALK_INFO *info = (ACPI_DEVICE_WALK_INFO *) context; info->device_count++; acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); node = acpi_ns_convert_handle_to_entry (obj_handle); if (!node) { acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); /* * Run _STA to determine if we can run _INI on the device. */ status = acpi_cm_execute_STA (node, &flags); if (ACPI_FAILURE (status)) { return (status); } info->num_STA++; if (!(flags & 0x01)) { /* don't look at children of a not present device */ return(AE_CTRL_DEPTH); } /* * The device is present. Run _INI. */ status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL); if (AE_NOT_FOUND == status) { /* No _INI means device requires no initialization */ status = AE_OK; } else if (ACPI_FAILURE (status)) { return (status); } else { info->num_INI++; } return (status); }