Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

525 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. amlisupp.h
  5. Abstract:
  6. This contains some of the routines to read
  7. and understand the AMLI library
  8. Author:
  9. Stephane Plante (splante)
  10. Environment:
  11. NT Kernel Model Driver only
  12. --*/
  13. #include "pch.h"
  14. PSZ gpszOSName = "Microsoft Windows NT";
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGE,ACPIAmliFindObject)
  17. #endif
  18. VOID
  19. ACPIAmliDoubleToName(
  20. IN OUT PUCHAR ACPIName,
  21. IN ULONG DwordID,
  22. IN BOOLEAN ConvertToID
  23. )
  24. /*++
  25. Routine Description:
  26. Convert the DWORD ID into a 9 character name
  27. Arguments:
  28. ACPIName - Pointer to a memory location to fill
  29. DwordID - The ID to verify with IsID()?
  30. Return Value:
  31. None
  32. --*/
  33. {
  34. USHORT value;
  35. //
  36. // Leading Star
  37. //
  38. // Note: This has been left in since this is what Query ID should return:
  39. // DeviceID = ACPI\PNPxxxx
  40. // InstanceID = yyyy
  41. // HardwareID = DeviceID,*PNPxxxx
  42. //
  43. if (ConvertToID) {
  44. *ACPIName = '*';
  45. ACPIName++;
  46. }
  47. //
  48. // First character of DwordID[2..6]
  49. //
  50. *ACPIName = (UCHAR) ( ( (DwordID & 0x007C) >> 2 ) + 'A' - 1);
  51. ACPIName++;
  52. //
  53. // Second Character from DwordID[13..15,0..1]
  54. //
  55. *ACPIName = (UCHAR) ( ( (DwordID & 0x3 )<< 3 ) +
  56. ( (DwordID & 0xE000) >> 13 ) + 'A' - 1);
  57. ACPIName++;
  58. //
  59. // Third Character from dwID[8..12]
  60. //
  61. *ACPIName = (UCHAR) ( ( (DwordID >> 8 ) & 0x1F) + 'A' - 1);
  62. ACPIName++;
  63. //
  64. // The rest is made up of the Product ID, which is the HIWORD of the
  65. // DwordID
  66. //
  67. value = (USHORT) (DwordID >> 16);
  68. //
  69. // Add to the reset of the string
  70. //
  71. sprintf(ACPIName, "%02X%02X",(value & 0xFF ) ,( value >> 8 ));
  72. }
  73. VOID
  74. ACPIAmliDoubleToNameWide(
  75. IN OUT PWCHAR ACPIName,
  76. IN ULONG DwordID,
  77. IN BOOLEAN ConvertToID
  78. )
  79. /*++
  80. Routine Description:
  81. Convert the DWORD ID into a 9 character name
  82. Arguments:
  83. ACPIName - Pointer to a memory location to fill
  84. DwordID - The ID to verify with IsID()?
  85. Return Value:
  86. None
  87. --*/
  88. {
  89. USHORT value;
  90. //
  91. // Leading Star
  92. //
  93. // Note: This has been left in since this is what Query ID should return:
  94. // DeviceID = ACPI\PNPxxxx
  95. // InstanceID = yyyy
  96. // HardwareID = DeviceID,*PNPxxxx
  97. //
  98. if (ConvertToID) {
  99. *ACPIName = L'*';
  100. ACPIName++;
  101. }
  102. //
  103. // First character of DwordID[2..6]
  104. //
  105. *ACPIName = (WCHAR) ( ( (DwordID & 0x007C) >> 2 ) + L'A' - 1);
  106. ACPIName++;
  107. //
  108. // Second Character from DwordID[13..15,0..1]
  109. //
  110. *ACPIName = (WCHAR) ( ( (DwordID & 0x3 )<< 3 ) +
  111. ( (DwordID & 0xE000) >> 13 ) + L'A' - 1);
  112. ACPIName++;
  113. //
  114. // Third Character from dwID[8..12]
  115. //
  116. *ACPIName = (WCHAR) ( ( (DwordID >> 8 ) & 0x1F) + L'A' - 1);
  117. ACPIName++;
  118. //
  119. // The rest is made up of the Product ID, which is the HIWORD of the
  120. // DwordID
  121. //
  122. value = (USHORT) (DwordID >> 16);
  123. //
  124. // Add to the reset of the string
  125. //
  126. swprintf(ACPIName, L"%02X%02X",(value & 0xFF ) ,( value >> 8 ));
  127. }
  128. VOID
  129. EXPORT
  130. AmlisuppCompletePassive(
  131. IN PNSOBJ AcpiObject,
  132. IN NTSTATUS Status,
  133. IN POBJDATA Result,
  134. IN PVOID Context
  135. )
  136. /*++
  137. Routine Description:
  138. This is used as the completion routine for several
  139. functions in this file that run at passive level.
  140. Arguments:
  141. AcpiObject - unused
  142. Status - status to be returned to caller
  143. Result - unused
  144. Context - contains the event to be set
  145. Return Value:
  146. none
  147. --*/
  148. {
  149. PRKEVENT event = &((PAMLISUPP_CONTEXT_PASSIVE)Context)->Event;
  150. ASSERT(Context);
  151. ((PAMLISUPP_CONTEXT_PASSIVE)Context)->Status = Status;
  152. KeSetEvent(event, IO_NO_INCREMENT, FALSE);
  153. }
  154. PNSOBJ
  155. ACPIAmliGetNamedChild(
  156. IN PNSOBJ AcpiObject,
  157. IN ULONG ObjectId
  158. )
  159. /*++
  160. Routine Description:
  161. Looks at all the children of AcpiObject and returns
  162. the one named 'ObjectId'.
  163. Arguments:
  164. AcpiObject - Object to search in
  165. ObjectId - What we are looking for
  166. Return Value:
  167. A PNSOBJ, NULL if none
  168. --*/
  169. {
  170. PNSOBJ tempObject;
  171. //
  172. // Lets try to find a child object
  173. //
  174. for (tempObject = NSGETFIRSTCHILD(AcpiObject);
  175. tempObject != NULL;
  176. tempObject = NSGETNEXTSIBLING(tempObject)) {
  177. if (ObjectId == tempObject->dwNameSeg) {
  178. break;
  179. }
  180. }
  181. return tempObject;
  182. }
  183. PUCHAR
  184. ACPIAmliNameObject(
  185. IN PNSOBJ AcpiObject
  186. )
  187. /*++
  188. Routine Description:
  189. Returns a String that describes the objects
  190. Debug Only
  191. Arguments:
  192. AcpiOBject - The object to name
  193. Returns:
  194. String
  195. --*/
  196. {
  197. static UCHAR buffer[5];
  198. RtlCopyMemory( &buffer[0], &(AcpiObject->dwNameSeg), 4 );
  199. buffer[4] = '\0';
  200. return &(buffer[0]);
  201. }
  202. NTSTATUS
  203. ACPIAmliFindObject(
  204. IN PUCHAR ObjectName,
  205. IN PNSOBJ Scope,
  206. OUT PNSOBJ *Object
  207. )
  208. /*++
  209. Routine Description:
  210. Finds the first occurrence of an object within a given scope.
  211. Arguments:
  212. ObjectName - Name of the object. (null terminated)
  213. Scope - Node to search under
  214. Object - Pointer to return value
  215. Returns:
  216. status
  217. --*/
  218. {
  219. NTSTATUS status;
  220. PNSOBJ child;
  221. PNSOBJ sibling;
  222. PAGED_CODE();
  223. status = AMLIGetNameSpaceObject(ObjectName,
  224. Scope,
  225. Object,
  226. NSF_LOCAL_SCOPE);
  227. if (NT_SUCCESS(status)) {
  228. return status;
  229. }
  230. child = NSGETFIRSTCHILD(Scope);
  231. if (child) {
  232. status = ACPIAmliFindObject(ObjectName,
  233. child,
  234. Object);
  235. if (NT_SUCCESS(status)) {
  236. return status;
  237. }
  238. }
  239. sibling = NSGETNEXTSIBLING(Scope);
  240. if (sibling) {
  241. status = ACPIAmliFindObject(ObjectName,
  242. sibling,
  243. Object);
  244. }
  245. return status;
  246. }
  247. NTSTATUS
  248. ACPIAmliGetFirstChild(
  249. IN PUCHAR ObjectName,
  250. OUT PNSOBJ *Object)
  251. /*++
  252. Routine Description:
  253. This routine is called to get the first nsobject which is of type 'Device'
  254. that lives under ObjectName
  255. Arguments:
  256. ObjectName - The parent of the child we are looking for
  257. Object - Where to save a pointer to the PNSOBJ
  258. Return Value:
  259. NTSTATUS
  260. --*/
  261. {
  262. NTSTATUS status;
  263. PNSOBJ parentObj;
  264. status = AMLIGetNameSpaceObject(
  265. ObjectName,
  266. NULL,
  267. &parentObj,
  268. 0
  269. );
  270. if (!NT_SUCCESS(status)) {
  271. return status;
  272. }
  273. *Object = parentObj->pnsFirstChild;
  274. if (*Object == NULL ) {
  275. return STATUS_OBJECT_NAME_NOT_FOUND;
  276. }
  277. if ( NSGETOBJTYPE(*Object) == OBJTYPE_DEVICE) {
  278. return STATUS_SUCCESS;
  279. }
  280. *Object = (PNSOBJ) (*Object)->list.plistNext;
  281. parentObj = parentObj->pnsFirstChild;
  282. while (*Object != parentObj) {
  283. if ( NSGETOBJTYPE( *Object ) == OBJTYPE_DEVICE) {
  284. return STATUS_SUCCESS;
  285. }
  286. *Object = (PNSOBJ) (*Object)->list.plistNext;
  287. }
  288. *Object = NULL;
  289. return STATUS_OBJECT_NAME_NOT_FOUND;
  290. }
  291. NTSTATUS
  292. ACPIAmliBuildObjectPathname(
  293. IN PNSOBJ ACPIObject,
  294. OUT PUCHAR *ConstructedPathName
  295. )
  296. /*++
  297. Routine Description:
  298. This function takes an ACPI node and constructs the full path name with
  299. the parent/children seperated by '.'s, spaces with '*'s. e.g. (we smack
  300. off the initial '\___'.
  301. _SB*.PCI0.DOCK
  302. Arguments:
  303. ACPIObject - Object to start the enumeration at.
  304. ConstructedPathName - Allocated from the paged pool.
  305. Return Value:
  306. NTSTATUS
  307. --*/
  308. {
  309. PNSOBJ currentAcpiObject, nextAcpiObject ;
  310. ULONG nDepth, i, j ;
  311. PUCHAR objectPathname ;
  312. ASSERT(ACPIObject) ;
  313. //
  314. // First, calculate the size of data we must allocate
  315. //
  316. nDepth=0 ;
  317. currentAcpiObject=ACPIObject ;
  318. while(1) {
  319. nextAcpiObject = NSGETPARENT(currentAcpiObject);
  320. if (!nextAcpiObject) {
  321. break;
  322. }
  323. nDepth++;
  324. currentAcpiObject = nextAcpiObject;
  325. }
  326. objectPathname = (PUCHAR) ExAllocatePoolWithTag(
  327. NonPagedPool,
  328. (nDepth * 5) + 1,
  329. ACPI_STRING_POOLTAG
  330. );
  331. if (!objectPathname) {
  332. return STATUS_INSUFFICIENT_RESOURCES ;
  333. }
  334. objectPathname[ nDepth * 5 ] = '\0';
  335. j = nDepth;
  336. currentAcpiObject = ACPIObject;
  337. while(1) {
  338. nextAcpiObject = NSGETPARENT(currentAcpiObject);
  339. if (!nextAcpiObject) {
  340. break;
  341. }
  342. j--;
  343. RtlCopyMemory(
  344. &objectPathname[ (j * 5) ],
  345. &(currentAcpiObject->dwNameSeg),
  346. sizeof(NAMESEG)
  347. );
  348. for(i = 0; i < 4; i++) {
  349. if (objectPathname[ (j * 5) + i ] == '\0' ) {
  350. objectPathname[ (j * 5) + i ] = '*';
  351. }
  352. }
  353. objectPathname[ (j * 5) + 4 ] = '.';
  354. currentAcpiObject = nextAcpiObject;
  355. }
  356. //
  357. // Smack of trailing '.'
  358. //
  359. if (nDepth) {
  360. objectPathname[ (nDepth * 5) - 1 ] = '\0';
  361. }
  362. *ConstructedPathName = objectPathname;
  363. return STATUS_SUCCESS;
  364. }