[go: nahoru, domu]

115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore/******************************************************************************
215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
3ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * Module Name: utids - support for device Ids - HID, UID, CID
415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *****************************************************************************/
615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore/*
8fbb7a2dc2be493c87399550bdc2ddaa510cdf450Bob Moore * Copyright (C) 2000 - 2014, Intel Corp.
915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * All rights reserved.
1015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
1115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * Redistribution and use in source and binary forms, with or without
1215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * modification, are permitted provided that the following conditions
1315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * are met:
1415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * 1. Redistributions of source code must retain the above copyright
1515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *    notice, this list of conditions, and the following disclaimer,
1615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *    without modification.
1715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *    substantially similar to the "NO WARRANTY" disclaimer below
1915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *    ("Disclaimer") and any redistribution must be conditioned upon
2015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *    including a substantially similar Disclaimer requirement for further
2115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *    binary redistribution.
2215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * 3. Neither the names of the above-listed copyright holders nor the names
2315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *    of any contributors may be used to endorse or promote products derived
2415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *    from this software without specific prior written permission.
2515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
2615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * Alternatively, this software may be distributed under the terms of the
2715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * GNU General Public License ("GPL") version 2 as published by the Free
2815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * Software Foundation.
2915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
3015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * NO WARRANTY
3115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * POSSIBILITY OF SUCH DAMAGES.
4215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore */
4315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
4415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore#include <acpi/acpi.h>
4515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore#include "accommon.h"
4615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore#include "acinterp.h"
4715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
4815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore#define _COMPONENT          ACPI_UTILITIES
4915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob MooreACPI_MODULE_NAME("utids")
5015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
5115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore/*******************************************************************************
5215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
5315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * FUNCTION:    acpi_ut_execute_HID
5415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
5515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * PARAMETERS:  device_node         - Node for the device
5615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              return_id           - Where the string HID is returned
5715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
5815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * RETURN:      Status
5915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
6015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * DESCRIPTION: Executes the _HID control method that returns the hardware
6115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              ID of the device. The HID is either an 32-bit encoded EISAID
6215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              Integer or a String. A string is always returned. An EISAID
6315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              is converted to a string.
6415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
6515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              NOTE: Internal function, no parameter validation
6615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
6715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore ******************************************************************************/
6815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Mooreacpi_status
6915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Mooreacpi_ut_execute_HID(struct acpi_namespace_node *device_node,
7078e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng		    struct acpi_pnp_device_id **return_id)
7115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore{
7215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	union acpi_operand_object *obj_desc;
7378e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	struct acpi_pnp_device_id *hid;
7415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	u32 length;
7515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	acpi_status status;
7615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
7715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	ACPI_FUNCTION_TRACE(ut_execute_HID);
7815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
7915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
8015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore					 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
8115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore					 &obj_desc);
8215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (ACPI_FAILURE(status)) {
8315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		return_ACPI_STATUS(status);
8415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
8515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
8615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* Get the size of the String to be returned, includes null terminator */
8715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
8815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
8915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		length = ACPI_EISAID_STRING_SIZE;
9015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	} else {
9115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		length = obj_desc->string.length + 1;
9215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
9315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
9415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* Allocate a buffer for the HID */
9515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
9615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	hid =
9778e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
9815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore				 (acpi_size) length);
9915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (!hid) {
10015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		status = AE_NO_MEMORY;
10115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		goto cleanup;
10215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
10315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
10478e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	/* Area for the string starts after PNP_DEVICE_ID struct */
10515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
10678e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	hid->string =
10778e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	    ACPI_ADD_PTR(char, hid, sizeof(struct acpi_pnp_device_id));
10815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
10915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* Convert EISAID to a string or simply copy existing string */
11015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
11115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
11215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value);
11315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	} else {
11434cf66e724a2bf0a406d59b18f5bfeed746d7979Bob Moore		ACPI_STRCPY(hid->string, obj_desc->string.pointer);
11515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
11615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
11715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	hid->length = length;
11815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	*return_id = hid;
11915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
12015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moorecleanup:
12115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
12215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* On exit, we must delete the return object */
12315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
12415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	acpi_ut_remove_reference(obj_desc);
12515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	return_ACPI_STATUS(status);
12615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore}
12715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
12815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore/*******************************************************************************
129413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *
130413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore * FUNCTION:    acpi_ut_execute_SUB
131413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *
132413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore * PARAMETERS:  device_node         - Node for the device
133413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *              return_id           - Where the _SUB is returned
134413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *
135413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore * RETURN:      Status
136413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *
137413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore * DESCRIPTION: Executes the _SUB control method that returns the subsystem
138413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *              ID of the device. The _SUB value is always a string containing
139413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *              either a valid PNP or ACPI ID.
140413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *
141413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *              NOTE: Internal function, no parameter validation
142413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore *
143413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore ******************************************************************************/
144413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
145413fc3f592c65977858f8adce2e7af0e82aa1191Bob Mooreacpi_status
146413fc3f592c65977858f8adce2e7af0e82aa1191Bob Mooreacpi_ut_execute_SUB(struct acpi_namespace_node *device_node,
147413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore		    struct acpi_pnp_device_id **return_id)
148413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore{
149413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	union acpi_operand_object *obj_desc;
150413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	struct acpi_pnp_device_id *sub;
151413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	u32 length;
152413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	acpi_status status;
153413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
154413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	ACPI_FUNCTION_TRACE(ut_execute_SUB);
155413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
156413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__SUB,
157413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore					 ACPI_BTYPE_STRING, &obj_desc);
158413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	if (ACPI_FAILURE(status)) {
159413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore		return_ACPI_STATUS(status);
160413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	}
161413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
162413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	/* Get the size of the String to be returned, includes null terminator */
163413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
164413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	length = obj_desc->string.length + 1;
165413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
166413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	/* Allocate a buffer for the SUB */
167413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
168413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	sub =
169413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
170413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore				 (acpi_size) length);
171413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	if (!sub) {
172413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore		status = AE_NO_MEMORY;
173413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore		goto cleanup;
174413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	}
175413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
176413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	/* Area for the string starts after PNP_DEVICE_ID struct */
177413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
178413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	sub->string =
179413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	    ACPI_ADD_PTR(char, sub, sizeof(struct acpi_pnp_device_id));
180413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
181413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	/* Simply copy existing string */
182413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
183413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	ACPI_STRCPY(sub->string, obj_desc->string.pointer);
184413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	sub->length = length;
185413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	*return_id = sub;
186413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
18710622bf8ce432e6a53fd3c37163e99e99c9e43eeLv Zhengcleanup:
188413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
189413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	/* On exit, we must delete the return object */
190413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
191413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	acpi_ut_remove_reference(obj_desc);
192413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore	return_ACPI_STATUS(status);
193413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore}
194413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore
195413fc3f592c65977858f8adce2e7af0e82aa1191Bob Moore/*******************************************************************************
19615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
19715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * FUNCTION:    acpi_ut_execute_UID
19815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
19915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * PARAMETERS:  device_node         - Node for the device
20015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              return_id           - Where the string UID is returned
20115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
20215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * RETURN:      Status
20315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
20415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * DESCRIPTION: Executes the _UID control method that returns the unique
20515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              ID of the device. The UID is either a 64-bit Integer (NOT an
20615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              EISAID) or a string. Always returns a string. A 64-bit integer
20715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              is converted to a decimal string.
20815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
20915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              NOTE: Internal function, no parameter validation
21015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
21115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore ******************************************************************************/
21215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
21315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Mooreacpi_status
21415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Mooreacpi_ut_execute_UID(struct acpi_namespace_node *device_node,
21578e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng		    struct acpi_pnp_device_id **return_id)
21615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore{
21715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	union acpi_operand_object *obj_desc;
21878e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	struct acpi_pnp_device_id *uid;
21915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	u32 length;
22015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	acpi_status status;
22115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
22215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	ACPI_FUNCTION_TRACE(ut_execute_UID);
22315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
22415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
22515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore					 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
22615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore					 &obj_desc);
22715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (ACPI_FAILURE(status)) {
22815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		return_ACPI_STATUS(status);
22915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
23015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
23115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* Get the size of the String to be returned, includes null terminator */
23215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
23315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
23415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		length = ACPI_MAX64_DECIMAL_DIGITS + 1;
23515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	} else {
23615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		length = obj_desc->string.length + 1;
23715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
23815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
23915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* Allocate a buffer for the UID */
24015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
24115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	uid =
24278e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
24315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore				 (acpi_size) length);
24415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (!uid) {
24515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		status = AE_NO_MEMORY;
24615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		goto cleanup;
24715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
24815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
24978e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	/* Area for the string starts after PNP_DEVICE_ID struct */
25015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
25178e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	uid->string =
25278e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	    ACPI_ADD_PTR(char, uid, sizeof(struct acpi_pnp_device_id));
25315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
25415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* Convert an Integer to string, or just copy an existing string */
25515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
25615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
25715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		acpi_ex_integer_to_string(uid->string, obj_desc->integer.value);
25815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	} else {
25934cf66e724a2bf0a406d59b18f5bfeed746d7979Bob Moore		ACPI_STRCPY(uid->string, obj_desc->string.pointer);
26015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
26115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
26215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	uid->length = length;
26315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	*return_id = uid;
26415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
26515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moorecleanup:
26615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
26715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* On exit, we must delete the return object */
26815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
26915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	acpi_ut_remove_reference(obj_desc);
27015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	return_ACPI_STATUS(status);
27115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore}
27215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
27315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore/*******************************************************************************
27415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
27515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * FUNCTION:    acpi_ut_execute_CID
27615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
27715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * PARAMETERS:  device_node         - Node for the device
27815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              return_cid_list     - Where the CID list is returned
27915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
28015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * RETURN:      Status, list of CID strings
28115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
28215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * DESCRIPTION: Executes the _CID control method that returns one or more
28315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              compatible hardware IDs for the device.
28415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
28515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *              NOTE: Internal function, no parameter validation
28615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
28715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * A _CID method can return either a single compatible ID or a package of
28815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * compatible IDs. Each compatible ID can be one of the following:
28915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * 1) Integer (32 bit compressed EISA ID) or
29015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
29115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
29215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore * The Integer CIDs are converted to string format by this function.
29315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore *
29415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore ******************************************************************************/
29515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
29615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Mooreacpi_status
29715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Mooreacpi_ut_execute_CID(struct acpi_namespace_node *device_node,
29878e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng		    struct acpi_pnp_device_id_list **return_cid_list)
29915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore{
30015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	union acpi_operand_object **cid_objects;
30115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	union acpi_operand_object *obj_desc;
30278e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	struct acpi_pnp_device_id_list *cid_list;
30315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	char *next_id_string;
30415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	u32 string_area_size;
30515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	u32 length;
30615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	u32 cid_list_size;
30715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	acpi_status status;
30815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	u32 count;
30915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	u32 i;
31015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
31115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	ACPI_FUNCTION_TRACE(ut_execute_CID);
31215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
31315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* Evaluate the _CID method for this device */
31415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
31515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
31615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore					 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
31715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore					 | ACPI_BTYPE_PACKAGE, &obj_desc);
31815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (ACPI_FAILURE(status)) {
31915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		return_ACPI_STATUS(status);
32015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
32115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
32215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/*
32315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	 * Get the count and size of the returned _CIDs. _CID can return either
32415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	 * a Package of Integers/Strings or a single Integer or String.
32515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	 * Note: This section also validates that all CID elements are of the
32615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	 * correct type (Integer or String).
32715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	 */
32815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
32915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		count = obj_desc->package.count;
33015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		cid_objects = obj_desc->package.elements;
33115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	} else {		/* Single Integer or String CID */
33215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
33315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		count = 1;
33415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		cid_objects = &obj_desc;
33515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
33615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
33715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	string_area_size = 0;
33815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	for (i = 0; i < count; i++) {
33915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
34015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		/* String lengths include null terminator */
34115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
34215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		switch (cid_objects[i]->common.type) {
34315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		case ACPI_TYPE_INTEGER:
3441d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
34515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			string_area_size += ACPI_EISAID_STRING_SIZE;
34615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			break;
34715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
34815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		case ACPI_TYPE_STRING:
3491d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
35015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			string_area_size += cid_objects[i]->string.length + 1;
35115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			break;
35215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
35315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		default:
3541d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
35515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			status = AE_TYPE;
35615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			goto cleanup;
35715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		}
35815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
35915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
36015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/*
36115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	 * Now that we know the length of the CIDs, allocate return buffer:
36215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	 * 1) Size of the base structure +
36378e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	 * 2) Size of the CID PNP_DEVICE_ID array +
36415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	 * 3) Size of the actual CID strings
36515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	 */
36678e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	cid_list_size = sizeof(struct acpi_pnp_device_id_list) +
36778e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	    ((count - 1) * sizeof(struct acpi_pnp_device_id)) +
36878e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	    string_area_size;
36915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
37015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size);
37115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	if (!cid_list) {
37215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		status = AE_NO_MEMORY;
37315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		goto cleanup;
37415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
37515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
37678e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	/* Area for CID strings starts after the CID PNP_DEVICE_ID array */
37715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
37815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	next_id_string = ACPI_CAST_PTR(char, cid_list->ids) +
37978e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	    ((acpi_size) count * sizeof(struct acpi_pnp_device_id));
38015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
38115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* Copy/convert the CIDs to the return buffer */
38215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
38315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	for (i = 0; i < count; i++) {
38415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		if (cid_objects[i]->common.type == ACPI_TYPE_INTEGER) {
38515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
38615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			/* Convert the Integer (EISAID) CID to a string */
38715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
38815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			acpi_ex_eisa_id_to_string(next_id_string,
38915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore						  cid_objects[i]->integer.
39015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore						  value);
39115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			length = ACPI_EISAID_STRING_SIZE;
39215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		} else {	/* ACPI_TYPE_STRING */
39315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
39415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			/* Copy the String CID from the returned object */
39515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
39634cf66e724a2bf0a406d59b18f5bfeed746d7979Bob Moore			ACPI_STRCPY(next_id_string,
39734cf66e724a2bf0a406d59b18f5bfeed746d7979Bob Moore				    cid_objects[i]->string.pointer);
39815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			length = cid_objects[i]->string.length + 1;
39915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		}
40015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
40115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		cid_list->ids[i].string = next_id_string;
40215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		cid_list->ids[i].length = length;
40315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		next_id_string += length;
40415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	}
40515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
40615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* Finish the CID list */
40715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
40815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	cid_list->count = count;
40915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	cid_list->list_size = cid_list_size;
41015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	*return_cid_list = cid_list;
41115b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
41215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moorecleanup:
41315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
41415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	/* On exit, we must delete the _CID return object */
41515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore
41615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	acpi_ut_remove_reference(obj_desc);
41715b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	return_ACPI_STATUS(status);
41815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore}
419