^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: utids - support for device Ids - HID, UID, CID, SUB, CLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^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) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "acinterp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define _COMPONENT ACPI_UTILITIES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) ACPI_MODULE_NAME("utids")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * FUNCTION: acpi_ut_execute_HID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * PARAMETERS: device_node - Node for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * return_id - Where the string HID is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * DESCRIPTION: Executes the _HID control method that returns the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * ID of the device. The HID is either an 32-bit encoded EISAID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Integer or a String. A string is always returned. An EISAID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * is converted to a string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * NOTE: Internal function, no parameter validation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct acpi_pnp_device_id **return_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) union acpi_operand_object *obj_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct acpi_pnp_device_id *hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u32 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ACPI_FUNCTION_TRACE(ut_execute_HID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) &obj_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* Get the size of the String to be returned, includes null terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) length = ACPI_EISAID_STRING_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) length = obj_desc->string.length + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Allocate a buffer for the HID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) hid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) (acpi_size)length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (!hid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) goto cleanup;
^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) /* Area for the string starts after PNP_DEVICE_ID struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) hid->string =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ACPI_ADD_PTR(char, hid, sizeof(struct acpi_pnp_device_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Convert EISAID to a string or simply copy existing string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) strcpy(hid->string, obj_desc->string.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) hid->length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *return_id = hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* On exit, we must delete the return object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) acpi_ut_remove_reference(obj_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^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) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * FUNCTION: acpi_ut_execute_UID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * PARAMETERS: device_node - Node for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * return_id - Where the string UID is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * DESCRIPTION: Executes the _UID control method that returns the unique
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * ID of the device. The UID is either a 64-bit Integer (NOT an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * EISAID) or a string. Always returns a string. A 64-bit integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * is converted to a decimal string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * NOTE: Internal function, no parameter validation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct acpi_pnp_device_id **return_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) union acpi_operand_object *obj_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct acpi_pnp_device_id *uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u32 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ACPI_FUNCTION_TRACE(ut_execute_UID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) &obj_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Get the size of the String to be returned, includes null terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) length = ACPI_MAX64_DECIMAL_DIGITS + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) length = obj_desc->string.length + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* Allocate a buffer for the UID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) uid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) (acpi_size)length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (!uid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) goto cleanup;
^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) /* Area for the string starts after PNP_DEVICE_ID struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) uid->string =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ACPI_ADD_PTR(char, uid, sizeof(struct acpi_pnp_device_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Convert an Integer to string, or just copy an existing string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) acpi_ex_integer_to_string(uid->string, obj_desc->integer.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) strcpy(uid->string, obj_desc->string.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) uid->length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *return_id = uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* On exit, we must delete the return object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) acpi_ut_remove_reference(obj_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * FUNCTION: acpi_ut_execute_CID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * PARAMETERS: device_node - Node for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * return_cid_list - Where the CID list is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * RETURN: Status, list of CID strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * DESCRIPTION: Executes the _CID control method that returns one or more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * compatible hardware IDs for the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * NOTE: Internal function, no parameter validation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * A _CID method can return either a single compatible ID or a package of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * compatible IDs. Each compatible ID can be one of the following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * 1) Integer (32 bit compressed EISA ID) or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * The Integer CIDs are converted to string format by this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct acpi_pnp_device_id_list **return_cid_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) union acpi_operand_object **cid_objects;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) union acpi_operand_object *obj_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct acpi_pnp_device_id_list *cid_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) char *next_id_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u32 string_area_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u32 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u32 cid_list_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u32 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ACPI_FUNCTION_TRACE(ut_execute_CID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Evaluate the _CID method for this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) | ACPI_BTYPE_PACKAGE, &obj_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * Get the count and size of the returned _CIDs. _CID can return either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * a Package of Integers/Strings or a single Integer or String.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * Note: This section also validates that all CID elements are of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * correct type (Integer or String).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) count = obj_desc->package.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) cid_objects = obj_desc->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) } else { /* Single Integer or String CID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) cid_objects = &obj_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) string_area_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* String lengths include null terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) switch (cid_objects[i]->common.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) case ACPI_TYPE_INTEGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) string_area_size += ACPI_EISAID_STRING_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case ACPI_TYPE_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) string_area_size += cid_objects[i]->string.length + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) status = AE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * Now that we know the length of the CIDs, allocate return buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * 1) Size of the base structure +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * 2) Size of the CID PNP_DEVICE_ID array +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * 3) Size of the actual CID strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) cid_list_size = sizeof(struct acpi_pnp_device_id_list) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) (count * sizeof(struct acpi_pnp_device_id)) + string_area_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (!cid_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Area for CID strings starts after the CID PNP_DEVICE_ID array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) next_id_string = ACPI_CAST_PTR(char, cid_list->ids) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ((acpi_size)count * sizeof(struct acpi_pnp_device_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Copy/convert the CIDs to the return buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (cid_objects[i]->common.type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* Convert the Integer (EISAID) CID to a string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) acpi_ex_eisa_id_to_string(next_id_string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) cid_objects[i]->integer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) length = ACPI_EISAID_STRING_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) } else { /* ACPI_TYPE_STRING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* Copy the String CID from the returned object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) strcpy(next_id_string, cid_objects[i]->string.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) length = cid_objects[i]->string.length + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) cid_list->ids[i].string = next_id_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) cid_list->ids[i].length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) next_id_string += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* Finish the CID list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) cid_list->count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) cid_list->list_size = cid_list_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) *return_cid_list = cid_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* On exit, we must delete the _CID return object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) acpi_ut_remove_reference(obj_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return_ACPI_STATUS(status);
^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) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * FUNCTION: acpi_ut_execute_CLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * PARAMETERS: device_node - Node for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * return_id - Where the _CLS is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * DESCRIPTION: Executes the _CLS control method that returns PCI-defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * class code of the device. The _CLS value is always a package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * containing PCI class information as a list of integers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * The returned string has format "BBSSPP", where:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * BB = Base-class code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * SS = Sub-class code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * PP = Programming Interface code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) *
^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) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) acpi_ut_execute_CLS(struct acpi_namespace_node *device_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct acpi_pnp_device_id **return_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) union acpi_operand_object *obj_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) union acpi_operand_object **cls_objects;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) u32 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct acpi_pnp_device_id *cls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u32 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) u8 class_code[3] = { 0, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ACPI_FUNCTION_TRACE(ut_execute_CLS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CLS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) ACPI_BTYPE_PACKAGE, &obj_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return_ACPI_STATUS(status);
^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) /* Get the size of the String to be returned, includes null terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) length = ACPI_PCICLS_STRING_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) cls_objects = obj_desc->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) count = obj_desc->package.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (count > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) && cls_objects[0]->common.type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) class_code[0] = (u8)cls_objects[0]->integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (count > 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) && cls_objects[1]->common.type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) class_code[1] = (u8)cls_objects[1]->integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (count > 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) && cls_objects[2]->common.type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) class_code[2] = (u8)cls_objects[2]->integer.value;
^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) /* Allocate a buffer for the CLS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) cls =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) (acpi_size)length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (!cls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* Area for the string starts after PNP_DEVICE_ID struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) cls->string =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ACPI_ADD_PTR(char, cls, sizeof(struct acpi_pnp_device_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* Simply copy existing string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) acpi_ex_pci_cls_to_string(cls->string, class_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) cls->length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) *return_id = cls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* On exit, we must delete the return object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) acpi_ut_remove_reference(obj_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }