1 /******************************************************************************
3 * Module Name: utids - support for device IDs - HID, UID, CID
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
51 #define _COMPONENT ACPI_UTILITIES
52 ACPI_MODULE_NAME ("utids")
55 /*******************************************************************************
57 * FUNCTION: AcpiUtExecute_HID
59 * PARAMETERS: DeviceNode - Node for the device
60 * ReturnId - Where the string HID is returned
64 * DESCRIPTION: Executes the _HID control method that returns the hardware
65 * ID of the device. The HID is either an 32-bit encoded EISAID
66 * Integer or a String. A string is always returned. An EISAID
67 * is converted to a string.
69 * NOTE: Internal function, no parameter validation
71 ******************************************************************************/
75 ACPI_NAMESPACE_NODE
*DeviceNode
,
76 ACPI_PNP_DEVICE_ID
**ReturnId
)
78 ACPI_OPERAND_OBJECT
*ObjDesc
;
79 ACPI_PNP_DEVICE_ID
*Hid
;
84 ACPI_FUNCTION_TRACE (UtExecute_HID
);
87 Status
= AcpiUtEvaluateObject (DeviceNode
, METHOD_NAME__HID
,
88 ACPI_BTYPE_INTEGER
| ACPI_BTYPE_STRING
, &ObjDesc
);
89 if (ACPI_FAILURE (Status
))
91 return_ACPI_STATUS (Status
);
94 /* Get the size of the String to be returned, includes null terminator */
96 if (ObjDesc
->Common
.Type
== ACPI_TYPE_INTEGER
)
98 Length
= ACPI_EISAID_STRING_SIZE
;
102 Length
= ObjDesc
->String
.Length
+ 1;
105 /* Allocate a buffer for the HID */
107 Hid
= ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID
) + (ACPI_SIZE
) Length
);
110 Status
= AE_NO_MEMORY
;
114 /* Area for the string starts after PNP_DEVICE_ID struct */
116 Hid
->String
= ACPI_ADD_PTR (char, Hid
, sizeof (ACPI_PNP_DEVICE_ID
));
118 /* Convert EISAID to a string or simply copy existing string */
120 if (ObjDesc
->Common
.Type
== ACPI_TYPE_INTEGER
)
122 AcpiExEisaIdToString (Hid
->String
, ObjDesc
->Integer
.Value
);
126 ACPI_STRCPY (Hid
->String
, ObjDesc
->String
.Pointer
);
129 Hid
->Length
= Length
;
135 /* On exit, we must delete the return object */
137 AcpiUtRemoveReference (ObjDesc
);
138 return_ACPI_STATUS (Status
);
142 /*******************************************************************************
144 * FUNCTION: AcpiUtExecute_SUB
146 * PARAMETERS: DeviceNode - Node for the device
147 * ReturnId - Where the _SUB is returned
151 * DESCRIPTION: Executes the _SUB control method that returns the subsystem
152 * ID of the device. The _SUB value is always a string containing
153 * either a valid PNP or ACPI ID.
155 * NOTE: Internal function, no parameter validation
157 ******************************************************************************/
161 ACPI_NAMESPACE_NODE
*DeviceNode
,
162 ACPI_PNP_DEVICE_ID
**ReturnId
)
164 ACPI_OPERAND_OBJECT
*ObjDesc
;
165 ACPI_PNP_DEVICE_ID
*Sub
;
170 ACPI_FUNCTION_TRACE (UtExecute_SUB
);
173 Status
= AcpiUtEvaluateObject (DeviceNode
, METHOD_NAME__SUB
,
174 ACPI_BTYPE_STRING
, &ObjDesc
);
175 if (ACPI_FAILURE (Status
))
177 return_ACPI_STATUS (Status
);
180 /* Get the size of the String to be returned, includes null terminator */
182 Length
= ObjDesc
->String
.Length
+ 1;
184 /* Allocate a buffer for the SUB */
186 Sub
= ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID
) + (ACPI_SIZE
) Length
);
189 Status
= AE_NO_MEMORY
;
193 /* Area for the string starts after PNP_DEVICE_ID struct */
195 Sub
->String
= ACPI_ADD_PTR (char, Sub
, sizeof (ACPI_PNP_DEVICE_ID
));
197 /* Simply copy existing string */
199 ACPI_STRCPY (Sub
->String
, ObjDesc
->String
.Pointer
);
200 Sub
->Length
= Length
;
206 /* On exit, we must delete the return object */
208 AcpiUtRemoveReference (ObjDesc
);
209 return_ACPI_STATUS (Status
);
213 /*******************************************************************************
215 * FUNCTION: AcpiUtExecute_UID
217 * PARAMETERS: DeviceNode - Node for the device
218 * ReturnId - Where the string UID is returned
222 * DESCRIPTION: Executes the _UID control method that returns the unique
223 * ID of the device. The UID is either a 64-bit Integer (NOT an
224 * EISAID) or a string. Always returns a string. A 64-bit integer
225 * is converted to a decimal string.
227 * NOTE: Internal function, no parameter validation
229 ******************************************************************************/
233 ACPI_NAMESPACE_NODE
*DeviceNode
,
234 ACPI_PNP_DEVICE_ID
**ReturnId
)
236 ACPI_OPERAND_OBJECT
*ObjDesc
;
237 ACPI_PNP_DEVICE_ID
*Uid
;
242 ACPI_FUNCTION_TRACE (UtExecute_UID
);
245 Status
= AcpiUtEvaluateObject (DeviceNode
, METHOD_NAME__UID
,
246 ACPI_BTYPE_INTEGER
| ACPI_BTYPE_STRING
, &ObjDesc
);
247 if (ACPI_FAILURE (Status
))
249 return_ACPI_STATUS (Status
);
252 /* Get the size of the String to be returned, includes null terminator */
254 if (ObjDesc
->Common
.Type
== ACPI_TYPE_INTEGER
)
256 Length
= ACPI_MAX64_DECIMAL_DIGITS
+ 1;
260 Length
= ObjDesc
->String
.Length
+ 1;
263 /* Allocate a buffer for the UID */
265 Uid
= ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID
) + (ACPI_SIZE
) Length
);
268 Status
= AE_NO_MEMORY
;
272 /* Area for the string starts after PNP_DEVICE_ID struct */
274 Uid
->String
= ACPI_ADD_PTR (char, Uid
, sizeof (ACPI_PNP_DEVICE_ID
));
276 /* Convert an Integer to string, or just copy an existing string */
278 if (ObjDesc
->Common
.Type
== ACPI_TYPE_INTEGER
)
280 AcpiExIntegerToString (Uid
->String
, ObjDesc
->Integer
.Value
);
284 ACPI_STRCPY (Uid
->String
, ObjDesc
->String
.Pointer
);
287 Uid
->Length
= Length
;
293 /* On exit, we must delete the return object */
295 AcpiUtRemoveReference (ObjDesc
);
296 return_ACPI_STATUS (Status
);
300 /*******************************************************************************
302 * FUNCTION: AcpiUtExecute_CID
304 * PARAMETERS: DeviceNode - Node for the device
305 * ReturnCidList - Where the CID list is returned
307 * RETURN: Status, list of CID strings
309 * DESCRIPTION: Executes the _CID control method that returns one or more
310 * compatible hardware IDs for the device.
312 * NOTE: Internal function, no parameter validation
314 * A _CID method can return either a single compatible ID or a package of
315 * compatible IDs. Each compatible ID can be one of the following:
316 * 1) Integer (32 bit compressed EISA ID) or
317 * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
319 * The Integer CIDs are converted to string format by this function.
321 ******************************************************************************/
325 ACPI_NAMESPACE_NODE
*DeviceNode
,
326 ACPI_PNP_DEVICE_ID_LIST
**ReturnCidList
)
328 ACPI_OPERAND_OBJECT
**CidObjects
;
329 ACPI_OPERAND_OBJECT
*ObjDesc
;
330 ACPI_PNP_DEVICE_ID_LIST
*CidList
;
332 UINT32 StringAreaSize
;
340 ACPI_FUNCTION_TRACE (UtExecute_CID
);
343 /* Evaluate the _CID method for this device */
345 Status
= AcpiUtEvaluateObject (DeviceNode
, METHOD_NAME__CID
,
346 ACPI_BTYPE_INTEGER
| ACPI_BTYPE_STRING
| ACPI_BTYPE_PACKAGE
,
348 if (ACPI_FAILURE (Status
))
350 return_ACPI_STATUS (Status
);
354 * Get the count and size of the returned _CIDs. _CID can return either
355 * a Package of Integers/Strings or a single Integer or String.
356 * Note: This section also validates that all CID elements are of the
357 * correct type (Integer or String).
359 if (ObjDesc
->Common
.Type
== ACPI_TYPE_PACKAGE
)
361 Count
= ObjDesc
->Package
.Count
;
362 CidObjects
= ObjDesc
->Package
.Elements
;
364 else /* Single Integer or String CID */
367 CidObjects
= &ObjDesc
;
371 for (i
= 0; i
< Count
; i
++)
373 /* String lengths include null terminator */
375 switch (CidObjects
[i
]->Common
.Type
)
377 case ACPI_TYPE_INTEGER
:
379 StringAreaSize
+= ACPI_EISAID_STRING_SIZE
;
382 case ACPI_TYPE_STRING
:
384 StringAreaSize
+= CidObjects
[i
]->String
.Length
+ 1;
395 * Now that we know the length of the CIDs, allocate return buffer:
396 * 1) Size of the base structure +
397 * 2) Size of the CID PNP_DEVICE_ID array +
398 * 3) Size of the actual CID strings
400 CidListSize
= sizeof (ACPI_PNP_DEVICE_ID_LIST
) +
401 ((Count
- 1) * sizeof (ACPI_PNP_DEVICE_ID
)) +
404 CidList
= ACPI_ALLOCATE_ZEROED (CidListSize
);
407 Status
= AE_NO_MEMORY
;
411 /* Area for CID strings starts after the CID PNP_DEVICE_ID array */
413 NextIdString
= ACPI_CAST_PTR (char, CidList
->Ids
) +
414 ((ACPI_SIZE
) Count
* sizeof (ACPI_PNP_DEVICE_ID
));
416 /* Copy/convert the CIDs to the return buffer */
418 for (i
= 0; i
< Count
; i
++)
420 if (CidObjects
[i
]->Common
.Type
== ACPI_TYPE_INTEGER
)
422 /* Convert the Integer (EISAID) CID to a string */
424 AcpiExEisaIdToString (NextIdString
, CidObjects
[i
]->Integer
.Value
);
425 Length
= ACPI_EISAID_STRING_SIZE
;
427 else /* ACPI_TYPE_STRING */
429 /* Copy the String CID from the returned object */
431 ACPI_STRCPY (NextIdString
, CidObjects
[i
]->String
.Pointer
);
432 Length
= CidObjects
[i
]->String
.Length
+ 1;
435 CidList
->Ids
[i
].String
= NextIdString
;
436 CidList
->Ids
[i
].Length
= Length
;
437 NextIdString
+= Length
;
440 /* Finish the CID list */
442 CidList
->Count
= Count
;
443 CidList
->ListSize
= CidListSize
;
444 *ReturnCidList
= CidList
;
449 /* On exit, we must delete the _CID return object */
451 AcpiUtRemoveReference (ObjDesc
);
452 return_ACPI_STATUS (Status
);