^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: nsxfname - Public interfaces to the ACPI subsystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * ACPI Namespace oriented interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define EXPORT_ACPI_INTERFACES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "acnamesp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "acparser.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "amlcode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define _COMPONENT ACPI_NAMESPACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) ACPI_MODULE_NAME("nsxfname")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* Local prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct acpi_pnp_device_id *source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) char *string_area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * FUNCTION: acpi_get_handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * PARAMETERS: parent - Object to search under (search scope).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * pathname - Pointer to an asciiz string containing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * ret_handle - Where the return handle is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * DESCRIPTION: This routine will search for a caller specified name in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * name space. The caller can restrict the search region by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * specifying a non NULL parent. The parent value is itself a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * namespace handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) acpi_get_handle(acpi_handle parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) acpi_string pathname, acpi_handle *ret_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct acpi_namespace_node *node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct acpi_namespace_node *prefix_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ACPI_FUNCTION_ENTRY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Parameter Validation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (!ret_handle || !pathname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Convert a parent handle to a prefix node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) prefix_node = acpi_ns_validate_handle(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (!prefix_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * Valid cases are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * 1) Fully qualified pathname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * 2) Parent + Relative pathname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Error for <null Parent + relative path>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (ACPI_IS_ROOT_PREFIX(pathname[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Pathname is fully qualified (starts with '\') */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Special case for root-only, since we can't search for it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (!strcmp(pathname, ACPI_NS_ROOT_PATH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *ret_handle =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ACPI_CAST_PTR(acpi_handle, acpi_gbl_root_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) } else if (!prefix_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Relative path with null prefix is disallowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* Find the Node and convert to a handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *ret_handle = ACPI_CAST_PTR(acpi_handle, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ACPI_EXPORT_SYMBOL(acpi_get_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * FUNCTION: acpi_get_name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * PARAMETERS: handle - Handle to be converted to a pathname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * name_type - Full pathname or single segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * buffer - Buffer for returned path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * RETURN: Pointer to a string containing the fully qualified Name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * DESCRIPTION: This routine returns the fully qualified name associated with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * the Handle parameter. This and the acpi_pathname_to_handle are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * complementary functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Parameter validation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (name_type > ACPI_NAME_TYPE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) status = acpi_ut_validate_buffer(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Wants the single segment ACPI name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Validate handle and convert to a namespace Node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (name_type == ACPI_FULL_PATHNAME ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) name_type == ACPI_FULL_PATHNAME_NO_TRAILING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Get the full pathname (From the namespace root) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) status = acpi_ns_handle_to_pathname(handle, buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) name_type ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ACPI_FULL_PATHNAME ? FALSE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Get the single name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) status = acpi_ns_handle_to_name(handle, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ACPI_EXPORT_SYMBOL(acpi_get_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * FUNCTION: acpi_ns_copy_device_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * PARAMETERS: dest - Pointer to the destination PNP_DEVICE_ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * source - Pointer to the source PNP_DEVICE_ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * string_area - Pointer to where to copy the dest string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * RETURN: Pointer to the next string area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * DESCRIPTION: Copy a single PNP_DEVICE_ID, including the string data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct acpi_pnp_device_id *source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) char *string_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* Create the destination PNP_DEVICE_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dest->string = string_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dest->length = source->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /* Copy actual string and return a pointer to the next string area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) memcpy(string_area, source->string, source->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return (string_area + source->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * FUNCTION: acpi_get_object_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * PARAMETERS: handle - Object Handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * return_buffer - Where the info is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * DESCRIPTION: Returns information about an object as gleaned from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * namespace node and possibly by running several standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * control methods (Such as in the case of a device.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * For Device and Processor objects, run the Device _HID, _UID, _CID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * _CLS, _ADR, _sx_w, and _sx_d methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Note: Allocates the return buffer, must be freed by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Note: This interface is intended to be used during the initial device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * discovery namespace traversal. Therefore, no complex methods can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * executed, especially those that access operation regions. Therefore, do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * not add any additional methods that could cause problems in this area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * Because of this reason support for the following methods has been removed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * 1) _SUB method was removed (11/2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * 2) _STA method was removed (02/2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) acpi_get_object_info(acpi_handle handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct acpi_device_info **return_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct acpi_namespace_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct acpi_device_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct acpi_pnp_device_id_list *cid_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct acpi_pnp_device_id *hid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct acpi_pnp_device_id *uid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct acpi_pnp_device_id *cls = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) char *next_id_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) acpi_object_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) acpi_name name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) u8 param_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) u16 valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u32 info_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* Parameter validation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!handle || !return_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) node = acpi_ns_validate_handle(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* Get the namespace node data while the namespace is locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) info_size = sizeof(struct acpi_device_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) type = node->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) name = node->name.integer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (node->type == ACPI_TYPE_METHOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) param_count = node->object->method.param_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * Get extra info for ACPI Device/Processor objects only:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * Run the Device _HID, _UID, _CLS, and _CID methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * Note: none of these methods are required, so they may or may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * not be present for this device. The Info->Valid bitfield is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * to indicate which methods were found and run successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Execute the Device._HID method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) status = acpi_ut_execute_HID(node, &hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) info_size += hid->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) valid |= ACPI_VALID_HID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* Execute the Device._UID method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) status = acpi_ut_execute_UID(node, &uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) info_size += uid->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) valid |= ACPI_VALID_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Execute the Device._CID method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) status = acpi_ut_execute_CID(node, &cid_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Add size of CID strings and CID pointer array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) info_size +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) (cid_list->list_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) sizeof(struct acpi_pnp_device_id_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) valid |= ACPI_VALID_CID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* Execute the Device._CLS method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) status = acpi_ut_execute_CLS(node, &cls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) info_size += cls->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) valid |= ACPI_VALID_CLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Now that we have the variable-length data, we can allocate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * return buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) info = ACPI_ALLOCATE_ZEROED(info_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* Get the fixed-length data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * Get extra info for ACPI Device/Processor objects only:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * Run the _ADR and, sx_w, and _sx_d methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * Notes: none of these methods are required, so they may or may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * not be present for this device. The Info->Valid bitfield is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * to indicate which methods were found and run successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* Execute the Device._ADR method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) &info->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) valid |= ACPI_VALID_ADR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* Execute the Device._sx_w methods */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) status = acpi_ut_execute_power_methods(node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) acpi_gbl_lowest_dstate_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ACPI_NUM_sx_w_METHODS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) info->lowest_dstates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) valid |= ACPI_VALID_SXWS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* Execute the Device._sx_d methods */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) status = acpi_ut_execute_power_methods(node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) acpi_gbl_highest_dstate_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ACPI_NUM_sx_d_METHODS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) info->highest_dstates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) valid |= ACPI_VALID_SXDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * Create a pointer to the string area of the return buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Point to the end of the base struct acpi_device_info structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) next_id_string = ACPI_CAST_PTR(char, info->compatible_id_list.ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (cid_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* Point past the CID PNP_DEVICE_ID array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) next_id_string +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ((acpi_size)cid_list->count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) sizeof(struct acpi_pnp_device_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * Copy the HID, UID, and CIDs to the return buffer. The variable-length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * strings are copied to the reserved area at the end of the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * For HID and CID, check if the ID is a PCI Root Bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (hid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) next_id_string = acpi_ns_copy_device_id(&info->hardware_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) hid, next_id_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (acpi_ut_is_pci_root_bridge(hid->string)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) info->flags |= ACPI_PCI_ROOT_BRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (uid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) next_id_string = acpi_ns_copy_device_id(&info->unique_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) uid, next_id_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (cid_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) info->compatible_id_list.count = cid_list->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) info->compatible_id_list.list_size = cid_list->list_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* Copy each CID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) for (i = 0; i < cid_list->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) next_id_string =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) acpi_ns_copy_device_id(&info->compatible_id_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ids[i], &cid_list->ids[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) next_id_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (acpi_ut_is_pci_root_bridge(cid_list->ids[i].string)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) info->flags |= ACPI_PCI_ROOT_BRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (cls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) (void)acpi_ns_copy_device_id(&info->class_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) cls, next_id_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Copy the fixed-length data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) info->info_size = info_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) info->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) info->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) info->param_count = param_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) info->valid = valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) *return_buffer = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (hid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ACPI_FREE(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (uid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ACPI_FREE(uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (cid_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ACPI_FREE(cid_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (cls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ACPI_FREE(cls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ACPI_EXPORT_SYMBOL(acpi_get_object_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * FUNCTION: acpi_install_method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * PARAMETERS: buffer - An ACPI table containing one control method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * DESCRIPTION: Install a control method into the namespace. If the method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * name already exists in the namespace, it is overwritten. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * input buffer must contain a valid DSDT or SSDT containing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * single control method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) acpi_status acpi_install_method(u8 *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct acpi_table_header *table =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ACPI_CAST_PTR(struct acpi_table_header, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) u8 *aml_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) u8 *aml_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) char *path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct acpi_namespace_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) union acpi_operand_object *method_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct acpi_parse_state parser_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) u32 aml_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) u16 opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u8 method_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Parameter validation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* Table must be a DSDT or SSDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (!ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) !ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_SSDT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return (AE_BAD_HEADER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* First AML opcode in the table must be a control method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) parser_state.aml = buffer + sizeof(struct acpi_table_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) opcode = acpi_ps_peek_opcode(&parser_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (opcode != AML_METHOD_OP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /* Extract method information from the raw AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) parser_state.aml += acpi_ps_get_opcode_size(opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) parser_state.pkg_end = acpi_ps_get_next_package_end(&parser_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) path = acpi_ps_get_next_namestring(&parser_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) method_flags = *parser_state.aml++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) aml_start = parser_state.aml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) aml_length = (u32)ACPI_PTR_DIFF(parser_state.pkg_end, aml_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * Allocate resources up-front. We don't want to have to delete a new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * node from the namespace if we cannot allocate memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) aml_buffer = ACPI_ALLOCATE(aml_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (!aml_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return (AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (!method_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ACPI_FREE(aml_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return (AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* Lock namespace for acpi_ns_lookup, we may be creating a new node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) goto error_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* The lookup either returns an existing node or creates a new one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) acpi_ns_lookup(NULL, path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) NULL, &node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (ACPI_FAILURE(status)) { /* ns_lookup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (status != AE_ALREADY_EXISTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) goto error_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* Node existed previously, make sure it is a method node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (node->type != ACPI_TYPE_METHOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) status = AE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) goto error_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Copy the method AML to the local buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) memcpy(aml_buffer, aml_start, aml_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* Initialize the method object with the new method's information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) method_obj->method.aml_start = aml_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) method_obj->method.aml_length = aml_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) method_obj->method.param_count = (u8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) (method_flags & AML_METHOD_ARG_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (method_flags & AML_METHOD_SERIALIZED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) method_obj->method.info_flags = ACPI_METHOD_SERIALIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) method_obj->method.sync_level = (u8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * Now that it is complete, we can attach the new method object to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * the method Node (detaches/deletes any existing object)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) status = acpi_ns_attach_object(node, method_obj, ACPI_TYPE_METHOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * Flag indicates AML buffer is dynamic, must be deleted later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * Must be set only after attach above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) node->flags |= ANOBJ_ALLOCATED_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Remove local reference to the method object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) acpi_ut_remove_reference(method_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) error_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ACPI_FREE(aml_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ACPI_FREE(method_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ACPI_EXPORT_SYMBOL(acpi_install_method)