ReactOS  0.4.14-dev-390-g34947ad
utids.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: utids - support for device IDs - HID, UID, CID, SUB, CLS
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2019, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
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.
25  *
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.
29  *
30  * NO WARRANTY
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.
42  */
43 
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acinterp.h"
47 
48 
49 #define _COMPONENT ACPI_UTILITIES
50  ACPI_MODULE_NAME ("utids")
51 
52 
53 /*******************************************************************************
54  *
55  * FUNCTION: AcpiUtExecute_HID
56  *
57  * PARAMETERS: DeviceNode - Node for the device
58  * ReturnId - Where the string HID is returned
59  *
60  * RETURN: Status
61  *
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.
66  *
67  * NOTE: Internal function, no parameter validation
68  *
69  ******************************************************************************/
70 
74  ACPI_PNP_DEVICE_ID **ReturnId)
75 {
76  ACPI_OPERAND_OBJECT *ObjDesc;
77  ACPI_PNP_DEVICE_ID *Hid;
78  UINT32 Length;
80 
81 
82  ACPI_FUNCTION_TRACE (UtExecute_HID);
83 
84 
87  if (ACPI_FAILURE (Status))
88  {
90  }
91 
92  /* Get the size of the String to be returned, includes null terminator */
93 
94  if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
95  {
97  }
98  else
99  {
100  Length = ObjDesc->String.Length + 1;
101  }
102 
103  /* Allocate a buffer for the HID */
104 
105  Hid = ACPI_ALLOCATE_ZEROED (
106  sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
107  if (!Hid)
108  {
110  goto Cleanup;
111  }
112 
113  /* Area for the string starts after PNP_DEVICE_ID struct */
114 
115  Hid->String = ACPI_ADD_PTR (char, Hid, sizeof (ACPI_PNP_DEVICE_ID));
116 
117  /* Convert EISAID to a string or simply copy existing string */
118 
119  if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
120  {
121  AcpiExEisaIdToString (Hid->String, ObjDesc->Integer.Value);
122  }
123  else
124  {
125  strcpy (Hid->String, ObjDesc->String.Pointer);
126  }
127 
128  Hid->Length = Length;
129  *ReturnId = Hid;
130 
131 
132 Cleanup:
133 
134  /* On exit, we must delete the return object */
135 
136  AcpiUtRemoveReference (ObjDesc);
138 }
139 
140 
141 /*******************************************************************************
142  *
143  * FUNCTION: AcpiUtExecute_UID
144  *
145  * PARAMETERS: DeviceNode - Node for the device
146  * ReturnId - Where the string UID is returned
147  *
148  * RETURN: Status
149  *
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.
154  *
155  * NOTE: Internal function, no parameter validation
156  *
157  ******************************************************************************/
158 
162  ACPI_PNP_DEVICE_ID **ReturnId)
163 {
164  ACPI_OPERAND_OBJECT *ObjDesc;
165  ACPI_PNP_DEVICE_ID *Uid;
166  UINT32 Length;
168 
169 
170  ACPI_FUNCTION_TRACE (UtExecute_UID);
171 
172 
175  if (ACPI_FAILURE (Status))
176  {
178  }
179 
180  /* Get the size of the String to be returned, includes null terminator */
181 
182  if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
183  {
185  }
186  else
187  {
188  Length = ObjDesc->String.Length + 1;
189  }
190 
191  /* Allocate a buffer for the UID */
192 
193  Uid = ACPI_ALLOCATE_ZEROED (
194  sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
195  if (!Uid)
196  {
198  goto Cleanup;
199  }
200 
201  /* Area for the string starts after PNP_DEVICE_ID struct */
202 
203  Uid->String = ACPI_ADD_PTR (char, Uid, sizeof (ACPI_PNP_DEVICE_ID));
204 
205  /* Convert an Integer to string, or just copy an existing string */
206 
207  if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
208  {
209  AcpiExIntegerToString (Uid->String, ObjDesc->Integer.Value);
210  }
211  else
212  {
213  strcpy (Uid->String, ObjDesc->String.Pointer);
214  }
215 
216  Uid->Length = Length;
217  *ReturnId = Uid;
218 
219 
220 Cleanup:
221 
222  /* On exit, we must delete the return object */
223 
224  AcpiUtRemoveReference (ObjDesc);
226 }
227 
228 
229 /*******************************************************************************
230  *
231  * FUNCTION: AcpiUtExecute_CID
232  *
233  * PARAMETERS: DeviceNode - Node for the device
234  * ReturnCidList - Where the CID list is returned
235  *
236  * RETURN: Status, list of CID strings
237  *
238  * DESCRIPTION: Executes the _CID control method that returns one or more
239  * compatible hardware IDs for the device.
240  *
241  * NOTE: Internal function, no parameter validation
242  *
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")
247  *
248  * The Integer CIDs are converted to string format by this function.
249  *
250  ******************************************************************************/
251 
255  ACPI_PNP_DEVICE_ID_LIST **ReturnCidList)
256 {
257  ACPI_OPERAND_OBJECT **CidObjects;
258  ACPI_OPERAND_OBJECT *ObjDesc;
259  ACPI_PNP_DEVICE_ID_LIST *CidList;
260  char *NextIdString;
261  UINT32 StringAreaSize;
262  UINT32 Length;
263  UINT32 CidListSize;
265  UINT32 Count;
266  UINT32 i;
267 
268 
269  ACPI_FUNCTION_TRACE (UtExecute_CID);
270 
271 
272  /* Evaluate the _CID method for this device */
273 
276  &ObjDesc);
277  if (ACPI_FAILURE (Status))
278  {
280  }
281 
282  /*
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).
287  */
288  if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
289  {
290  Count = ObjDesc->Package.Count;
291  CidObjects = ObjDesc->Package.Elements;
292  }
293  else /* Single Integer or String CID */
294  {
295  Count = 1;
296  CidObjects = &ObjDesc;
297  }
298 
299  StringAreaSize = 0;
300  for (i = 0; i < Count; i++)
301  {
302  /* String lengths include null terminator */
303 
304  switch (CidObjects[i]->Common.Type)
305  {
306  case ACPI_TYPE_INTEGER:
307 
308  StringAreaSize += ACPI_EISAID_STRING_SIZE;
309  break;
310 
311  case ACPI_TYPE_STRING:
312 
313  StringAreaSize += CidObjects[i]->String.Length + 1;
314  break;
315 
316  default:
317 
318  Status = AE_TYPE;
319  goto Cleanup;
320  }
321  }
322 
323  /*
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
328  */
329  CidListSize = sizeof (ACPI_PNP_DEVICE_ID_LIST) +
330  ((Count - 1) * sizeof (ACPI_PNP_DEVICE_ID)) +
331  StringAreaSize;
332 
333  CidList = ACPI_ALLOCATE_ZEROED (CidListSize);
334  if (!CidList)
335  {
337  goto Cleanup;
338  }
339 
340  /* Area for CID strings starts after the CID PNP_DEVICE_ID array */
341 
342  NextIdString = ACPI_CAST_PTR (char, CidList->Ids) +
343  ((ACPI_SIZE) Count * sizeof (ACPI_PNP_DEVICE_ID));
344 
345  /* Copy/convert the CIDs to the return buffer */
346 
347  for (i = 0; i < Count; i++)
348  {
349  if (CidObjects[i]->Common.Type == ACPI_TYPE_INTEGER)
350  {
351  /* Convert the Integer (EISAID) CID to a string */
352 
354  NextIdString, CidObjects[i]->Integer.Value);
356  }
357  else /* ACPI_TYPE_STRING */
358  {
359  /* Copy the String CID from the returned object */
360 
361  strcpy (NextIdString, CidObjects[i]->String.Pointer);
362  Length = CidObjects[i]->String.Length + 1;
363  }
364 
365  CidList->Ids[i].String = NextIdString;
366  CidList->Ids[i].Length = Length;
367  NextIdString += Length;
368  }
369 
370  /* Finish the CID list */
371 
372  CidList->Count = Count;
373  CidList->ListSize = CidListSize;
374  *ReturnCidList = CidList;
375 
376 
377 Cleanup:
378 
379  /* On exit, we must delete the _CID return object */
380 
381  AcpiUtRemoveReference (ObjDesc);
383 }
384 
385 
386 /*******************************************************************************
387  *
388  * FUNCTION: AcpiUtExecute_CLS
389  *
390  * PARAMETERS: DeviceNode - Node for the device
391  * ReturnId - Where the _CLS is returned
392  *
393  * RETURN: Status
394  *
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
402  *
403  ******************************************************************************/
404 
408  ACPI_PNP_DEVICE_ID **ReturnId)
409 {
410  ACPI_OPERAND_OBJECT *ObjDesc;
411  ACPI_OPERAND_OBJECT **ClsObjects;
412  UINT32 Count;
413  ACPI_PNP_DEVICE_ID *Cls;
414  UINT32 Length;
416  UINT8 ClassCode[3] = {0, 0, 0};
417 
418 
419  ACPI_FUNCTION_TRACE (UtExecute_CLS);
420 
421 
423  ACPI_BTYPE_PACKAGE, &ObjDesc);
424  if (ACPI_FAILURE (Status))
425  {
427  }
428 
429  /* Get the size of the String to be returned, includes null terminator */
430 
432  ClsObjects = ObjDesc->Package.Elements;
433  Count = ObjDesc->Package.Count;
434 
435  if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
436  {
437  if (Count > 0 && ClsObjects[0]->Common.Type == ACPI_TYPE_INTEGER)
438  {
439  ClassCode[0] = (UINT8) ClsObjects[0]->Integer.Value;
440  }
441  if (Count > 1 && ClsObjects[1]->Common.Type == ACPI_TYPE_INTEGER)
442  {
443  ClassCode[1] = (UINT8) ClsObjects[1]->Integer.Value;
444  }
445  if (Count > 2 && ClsObjects[2]->Common.Type == ACPI_TYPE_INTEGER)
446  {
447  ClassCode[2] = (UINT8) ClsObjects[2]->Integer.Value;
448  }
449  }
450 
451  /* Allocate a buffer for the CLS */
452 
453  Cls = ACPI_ALLOCATE_ZEROED (
454  sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
455  if (!Cls)
456  {
458  goto Cleanup;
459  }
460 
461  /* Area for the string starts after PNP_DEVICE_ID struct */
462 
463  Cls->String = ACPI_ADD_PTR (char, Cls, sizeof (ACPI_PNP_DEVICE_ID));
464 
465  /* Simply copy existing string */
466 
467  AcpiExPciClsToString (Cls->String, ClassCode);
468  Cls->Length = Length;
469  *ReturnId = Cls;
470 
471 
472 Cleanup:
473 
474  /* On exit, we must delete the return object */
475 
476  AcpiUtRemoveReference (ObjDesc);
478 }
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
ACPI_STATUS AcpiUtExecute_CID(ACPI_NAMESPACE_NODE *DeviceNode, ACPI_PNP_DEVICE_ID_LIST **ReturnCidList)
Definition: utids.c:253
#define AE_NO_MEMORY
Definition: acexcep.h:112
struct acpi_pnp_device_id_list ACPI_PNP_DEVICE_ID_LIST
#define ACPI_PCICLS_STRING_SIZE
Definition: actypes.h:1256
ACPI_OBJECT_PACKAGE Package
Definition: acobject.h:520
#define ACPI_TYPE_INTEGER
Definition: actypes.h:679
ACPI_PNP_DEVICE_ID Ids[1]
Definition: actypes.h:1272
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
static WCHAR String[]
Definition: stringtable.c:55
UINT32 ACPI_STATUS
Definition: actypes.h:460
void AcpiExIntegerToString(char *OutString, UINT64 Value)
Definition: exutils.c:421
void AcpiExPciClsToString(char *OutString, UINT8 ClassCode[3])
Definition: exutils.c:461
ACPI_STATUS AcpiUtExecute_HID(ACPI_NAMESPACE_NODE *DeviceNode, ACPI_PNP_DEVICE_ID **ReturnId)
Definition: utids.c:72
struct acpi_pnp_device_id ACPI_PNP_DEVICE_ID
#define ACPI_TYPE_PACKAGE
Definition: actypes.h:682
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT32
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define ACPI_EISAID_STRING_SIZE
Definition: actypes.h:1248
#define METHOD_NAME__CLS
Definition: acnames.h:54
#define ACPI_MAX64_DECIMAL_DIGITS
Definition: actypes.h:492
#define ACPI_BTYPE_INTEGER
Definition: aclocal.h:332
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Definition: Node.h:9
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:517
#define METHOD_NAME__CID
Definition: acnames.h:53
#define AE_TYPE
Definition: acexcep.h:116
static const WCHAR Cleanup[]
Definition: register.c:80
#define ACPI_BTYPE_PACKAGE
Definition: aclocal.h:335
#define ACPI_BTYPE_STRING
Definition: aclocal.h:333
ACPI_OBJECT_STRING String
Definition: acobject.h:518
Status
Definition: gdiplustypes.h:24
ACPI_STATUS AcpiUtExecute_UID(ACPI_NAMESPACE_NODE *DeviceNode, ACPI_PNP_DEVICE_ID **ReturnId)
Definition: utids.c:160
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
ACPI_OBJECT_COMMON Common
Definition: acobject.h:516
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:784
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define ACPI_ADD_PTR(t, a, b)
Definition: actypes.h:546
#define ACPI_TYPE_STRING
Definition: actypes.h:680
#define METHOD_NAME__UID
Definition: acnames.h:75
void AcpiExEisaIdToString(char *OutString, UINT64 CompressedId)
Definition: exutils.c:366
ACPI_STATUS AcpiUtEvaluateObject(ACPI_NAMESPACE_NODE *PrefixNode, const char *Path, UINT32 ExpectedReturnBtypes, ACPI_OPERAND_OBJECT **ReturnDesc)
Definition: uteval.c:73
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
unsigned char UINT8
#define METHOD_NAME__HID
Definition: acnames.h:58
union acpi_operand_object ** Elements
Definition: acobject.h:161
ACPI_STATUS AcpiUtExecute_CLS(ACPI_NAMESPACE_NODE *DeviceNode, ACPI_PNP_DEVICE_ID **ReturnId)
Definition: utids.c:406