1 /******************************************************************************
3 * Module Name: utids - support for device IDs - HID, UID, CID, SUB, CLS
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2016, 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.
49 #define _COMPONENT ACPI_UTILITIES
50 ACPI_MODULE_NAME ("utids")
53 /*******************************************************************************
55 * FUNCTION: AcpiUtExecute_HID
57 * PARAMETERS: DeviceNode - Node for the device
58 * ReturnId - Where the string HID is returned
62 * DESCRIPTION: Executes the _HID control method that returns the hardware
63 * ID of the device. The HID is either an 32-bit encoded EISAID
64 * Integer or a String. A string is always returned. An EISAID
65 * is converted to a string.
67 * NOTE: Internal function, no parameter validation
69 ******************************************************************************/
73 ACPI_NAMESPACE_NODE
*DeviceNode
,
74 ACPI_PNP_DEVICE_ID
**ReturnId
)
76 ACPI_OPERAND_OBJECT
*ObjDesc
;
77 ACPI_PNP_DEVICE_ID
*Hid
;
82 ACPI_FUNCTION_TRACE (UtExecute_HID
);
85 Status
= AcpiUtEvaluateObject (DeviceNode
, METHOD_NAME__HID
,
86 ACPI_BTYPE_INTEGER
| ACPI_BTYPE_STRING
, &ObjDesc
);
87 if (ACPI_FAILURE (Status
))
89 return_ACPI_STATUS (Status
);
92 /* Get the size of the String to be returned, includes null terminator */
94 if (ObjDesc
->Common
.Type
== ACPI_TYPE_INTEGER
)
96 Length
= ACPI_EISAID_STRING_SIZE
;
100 Length
= ObjDesc
->String
.Length
+ 1;
103 /* Allocate a buffer for the HID */
105 Hid
= ACPI_ALLOCATE_ZEROED (
106 sizeof (ACPI_PNP_DEVICE_ID
) + (ACPI_SIZE
) Length
);
109 Status
= AE_NO_MEMORY
;
113 /* Area for the string starts after PNP_DEVICE_ID struct */
115 Hid
->String
= ACPI_ADD_PTR (char, Hid
, sizeof (ACPI_PNP_DEVICE_ID
));
117 /* Convert EISAID to a string or simply copy existing string */
119 if (ObjDesc
->Common
.Type
== ACPI_TYPE_INTEGER
)
121 AcpiExEisaIdToString (Hid
->String
, ObjDesc
->Integer
.Value
);
125 strcpy (Hid
->String
, ObjDesc
->String
.Pointer
);
128 Hid
->Length
= Length
;
134 /* On exit, we must delete the return object */
136 AcpiUtRemoveReference (ObjDesc
);
137 return_ACPI_STATUS (Status
);
141 /*******************************************************************************
143 * FUNCTION: AcpiUtExecute_UID
145 * PARAMETERS: DeviceNode - Node for the device
146 * ReturnId - Where the string UID is returned
150 * DESCRIPTION: Executes the _UID control method that returns the unique
151 * ID of the device. The UID is either a 64-bit Integer (NOT an
152 * EISAID) or a string. Always returns a string. A 64-bit integer
153 * is converted to a decimal string.
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
*Uid
;
170 ACPI_FUNCTION_TRACE (UtExecute_UID
);
173 Status
= AcpiUtEvaluateObject (DeviceNode
, METHOD_NAME__UID
,
174 ACPI_BTYPE_INTEGER
| 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 if (ObjDesc
->Common
.Type
== ACPI_TYPE_INTEGER
)
184 Length
= ACPI_MAX64_DECIMAL_DIGITS
+ 1;
188 Length
= ObjDesc
->String
.Length
+ 1;
191 /* Allocate a buffer for the UID */
193 Uid
= ACPI_ALLOCATE_ZEROED (
194 sizeof (ACPI_PNP_DEVICE_ID
) + (ACPI_SIZE
) Length
);
197 Status
= AE_NO_MEMORY
;
201 /* Area for the string starts after PNP_DEVICE_ID struct */
203 Uid
->String
= ACPI_ADD_PTR (char, Uid
, sizeof (ACPI_PNP_DEVICE_ID
));
205 /* Convert an Integer to string, or just copy an existing string */
207 if (ObjDesc
->Common
.Type
== ACPI_TYPE_INTEGER
)
209 AcpiExIntegerToString (Uid
->String
, ObjDesc
->Integer
.Value
);
213 strcpy (Uid
->String
, ObjDesc
->String
.Pointer
);
216 Uid
->Length
= Length
;
222 /* On exit, we must delete the return object */
224 AcpiUtRemoveReference (ObjDesc
);
225 return_ACPI_STATUS (Status
);
229 /*******************************************************************************
231 * FUNCTION: AcpiUtExecute_CID
233 * PARAMETERS: DeviceNode - Node for the device
234 * ReturnCidList - Where the CID list is returned
236 * RETURN: Status, list of CID strings
238 * DESCRIPTION: Executes the _CID control method that returns one or more
239 * compatible hardware IDs for the device.
241 * NOTE: Internal function, no parameter validation
243 * A _CID method can return either a single compatible ID or a package of
244 * compatible IDs. Each compatible ID can be one of the following:
245 * 1) Integer (32 bit compressed EISA ID) or
246 * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
248 * The Integer CIDs are converted to string format by this function.
250 ******************************************************************************/
254 ACPI_NAMESPACE_NODE
*DeviceNode
,
255 ACPI_PNP_DEVICE_ID_LIST
**ReturnCidList
)
257 ACPI_OPERAND_OBJECT
**CidObjects
;
258 ACPI_OPERAND_OBJECT
*ObjDesc
;
259 ACPI_PNP_DEVICE_ID_LIST
*CidList
;
261 UINT32 StringAreaSize
;
269 ACPI_FUNCTION_TRACE (UtExecute_CID
);
272 /* Evaluate the _CID method for this device */
274 Status
= AcpiUtEvaluateObject (DeviceNode
, METHOD_NAME__CID
,
275 ACPI_BTYPE_INTEGER
| ACPI_BTYPE_STRING
| ACPI_BTYPE_PACKAGE
,
277 if (ACPI_FAILURE (Status
))
279 return_ACPI_STATUS (Status
);
283 * Get the count and size of the returned _CIDs. _CID can return either
284 * a Package of Integers/Strings or a single Integer or String.
285 * Note: This section also validates that all CID elements are of the
286 * correct type (Integer or String).
288 if (ObjDesc
->Common
.Type
== ACPI_TYPE_PACKAGE
)
290 Count
= ObjDesc
->Package
.Count
;
291 CidObjects
= ObjDesc
->Package
.Elements
;
293 else /* Single Integer or String CID */
296 CidObjects
= &ObjDesc
;
300 for (i
= 0; i
< Count
; i
++)
302 /* String lengths include null terminator */
304 switch (CidObjects
[i
]->Common
.Type
)
306 case ACPI_TYPE_INTEGER
:
308 StringAreaSize
+= ACPI_EISAID_STRING_SIZE
;
311 case ACPI_TYPE_STRING
:
313 StringAreaSize
+= CidObjects
[i
]->String
.Length
+ 1;
324 * Now that we know the length of the CIDs, allocate return buffer:
325 * 1) Size of the base structure +
326 * 2) Size of the CID PNP_DEVICE_ID array +
327 * 3) Size of the actual CID strings
329 CidListSize
= sizeof (ACPI_PNP_DEVICE_ID_LIST
) +
330 ((Count
- 1) * sizeof (ACPI_PNP_DEVICE_ID
)) +
333 CidList
= ACPI_ALLOCATE_ZEROED (CidListSize
);
336 Status
= AE_NO_MEMORY
;
340 /* Area for CID strings starts after the CID PNP_DEVICE_ID array */
342 NextIdString
= ACPI_CAST_PTR (char, CidList
->Ids
) +
343 ((ACPI_SIZE
) Count
* sizeof (ACPI_PNP_DEVICE_ID
));
345 /* Copy/convert the CIDs to the return buffer */
347 for (i
= 0; i
< Count
; i
++)
349 if (CidObjects
[i
]->Common
.Type
== ACPI_TYPE_INTEGER
)
351 /* Convert the Integer (EISAID) CID to a string */
353 AcpiExEisaIdToString (
354 NextIdString
, CidObjects
[i
]->Integer
.Value
);
355 Length
= ACPI_EISAID_STRING_SIZE
;
357 else /* ACPI_TYPE_STRING */
359 /* Copy the String CID from the returned object */
361 strcpy (NextIdString
, CidObjects
[i
]->String
.Pointer
);
362 Length
= CidObjects
[i
]->String
.Length
+ 1;
365 CidList
->Ids
[i
].String
= NextIdString
;
366 CidList
->Ids
[i
].Length
= Length
;
367 NextIdString
+= Length
;
370 /* Finish the CID list */
372 CidList
->Count
= Count
;
373 CidList
->ListSize
= CidListSize
;
374 *ReturnCidList
= CidList
;
379 /* On exit, we must delete the _CID return object */
381 AcpiUtRemoveReference (ObjDesc
);
382 return_ACPI_STATUS (Status
);
386 /*******************************************************************************
388 * FUNCTION: AcpiUtExecute_CLS
390 * PARAMETERS: DeviceNode - Node for the device
391 * ReturnId - Where the _CLS is returned
395 * DESCRIPTION: Executes the _CLS control method that returns PCI-defined
396 * class code of the device. The _CLS value is always a package
397 * containing PCI class information as a list of integers.
398 * The returned string has format "BBSSPP", where:
399 * BB = Base-class code
400 * SS = Sub-class code
401 * PP = Programming Interface code
403 ******************************************************************************/
407 ACPI_NAMESPACE_NODE
*DeviceNode
,
408 ACPI_PNP_DEVICE_ID
**ReturnId
)
410 ACPI_OPERAND_OBJECT
*ObjDesc
;
411 ACPI_OPERAND_OBJECT
**ClsObjects
;
413 ACPI_PNP_DEVICE_ID
*Cls
;
416 UINT8 ClassCode
[3] = {0, 0, 0};
419 ACPI_FUNCTION_TRACE (UtExecute_CLS
);
422 Status
= AcpiUtEvaluateObject (DeviceNode
, METHOD_NAME__CLS
,
423 ACPI_BTYPE_PACKAGE
, &ObjDesc
);
424 if (ACPI_FAILURE (Status
))
426 return_ACPI_STATUS (Status
);
429 /* Get the size of the String to be returned, includes null terminator */
431 Length
= ACPI_PCICLS_STRING_SIZE
;
432 ClsObjects
= ObjDesc
->Package
.Elements
;
433 Count
= ObjDesc
->Package
.Count
;
435 if (ObjDesc
->Common
.Type
== ACPI_TYPE_PACKAGE
)
437 if (Count
> 0 && ClsObjects
[0]->Common
.Type
== ACPI_TYPE_INTEGER
)
439 ClassCode
[0] = (UINT8
) ClsObjects
[0]->Integer
.Value
;
441 if (Count
> 1 && ClsObjects
[1]->Common
.Type
== ACPI_TYPE_INTEGER
)
443 ClassCode
[1] = (UINT8
) ClsObjects
[1]->Integer
.Value
;
445 if (Count
> 2 && ClsObjects
[2]->Common
.Type
== ACPI_TYPE_INTEGER
)
447 ClassCode
[2] = (UINT8
) ClsObjects
[2]->Integer
.Value
;
451 /* Allocate a buffer for the CLS */
453 Cls
= ACPI_ALLOCATE_ZEROED (
454 sizeof (ACPI_PNP_DEVICE_ID
) + (ACPI_SIZE
) Length
);
457 Status
= AE_NO_MEMORY
;
461 /* Area for the string starts after PNP_DEVICE_ID struct */
463 Cls
->String
= ACPI_ADD_PTR (char, Cls
, sizeof (ACPI_PNP_DEVICE_ID
));
465 /* Simply copy existing string */
467 AcpiExPciClsToString (Cls
->String
, ClassCode
);
468 Cls
->Length
= Length
;
474 /* On exit, we must delete the return object */
476 AcpiUtRemoveReference (ObjDesc
);
477 return_ACPI_STATUS (Status
);