windows-nt/Source/XPSP1/NT/base/busdrv/acpi/driver/nt/amlisupp.c
2020-09-26 16:20:57 +08:00

526 lines
9.2 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
amlisupp.h
Abstract:
This contains some of the routines to read
and understand the AMLI library
Author:
Stephane Plante (splante)
Environment:
NT Kernel Model Driver only
--*/
#include "pch.h"
PSZ gpszOSName = "Microsoft Windows NT";
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,ACPIAmliFindObject)
#endif
VOID
ACPIAmliDoubleToName(
IN OUT PUCHAR ACPIName,
IN ULONG DwordID,
IN BOOLEAN ConvertToID
)
/*++
Routine Description:
Convert the DWORD ID into a 9 character name
Arguments:
ACPIName - Pointer to a memory location to fill
DwordID - The ID to verify with IsID()?
Return Value:
None
--*/
{
USHORT value;
//
// Leading Star
//
// Note: This has been left in since this is what Query ID should return:
// DeviceID = ACPI\PNPxxxx
// InstanceID = yyyy
// HardwareID = DeviceID,*PNPxxxx
//
if (ConvertToID) {
*ACPIName = '*';
ACPIName++;
}
//
// First character of DwordID[2..6]
//
*ACPIName = (UCHAR) ( ( (DwordID & 0x007C) >> 2 ) + 'A' - 1);
ACPIName++;
//
// Second Character from DwordID[13..15,0..1]
//
*ACPIName = (UCHAR) ( ( (DwordID & 0x3 )<< 3 ) +
( (DwordID & 0xE000) >> 13 ) + 'A' - 1);
ACPIName++;
//
// Third Character from dwID[8..12]
//
*ACPIName = (UCHAR) ( ( (DwordID >> 8 ) & 0x1F) + 'A' - 1);
ACPIName++;
//
// The rest is made up of the Product ID, which is the HIWORD of the
// DwordID
//
value = (USHORT) (DwordID >> 16);
//
// Add to the reset of the string
//
sprintf(ACPIName, "%02X%02X",(value & 0xFF ) ,( value >> 8 ));
}
VOID
ACPIAmliDoubleToNameWide(
IN OUT PWCHAR ACPIName,
IN ULONG DwordID,
IN BOOLEAN ConvertToID
)
/*++
Routine Description:
Convert the DWORD ID into a 9 character name
Arguments:
ACPIName - Pointer to a memory location to fill
DwordID - The ID to verify with IsID()?
Return Value:
None
--*/
{
USHORT value;
//
// Leading Star
//
// Note: This has been left in since this is what Query ID should return:
// DeviceID = ACPI\PNPxxxx
// InstanceID = yyyy
// HardwareID = DeviceID,*PNPxxxx
//
if (ConvertToID) {
*ACPIName = L'*';
ACPIName++;
}
//
// First character of DwordID[2..6]
//
*ACPIName = (WCHAR) ( ( (DwordID & 0x007C) >> 2 ) + L'A' - 1);
ACPIName++;
//
// Second Character from DwordID[13..15,0..1]
//
*ACPIName = (WCHAR) ( ( (DwordID & 0x3 )<< 3 ) +
( (DwordID & 0xE000) >> 13 ) + L'A' - 1);
ACPIName++;
//
// Third Character from dwID[8..12]
//
*ACPIName = (WCHAR) ( ( (DwordID >> 8 ) & 0x1F) + L'A' - 1);
ACPIName++;
//
// The rest is made up of the Product ID, which is the HIWORD of the
// DwordID
//
value = (USHORT) (DwordID >> 16);
//
// Add to the reset of the string
//
swprintf(ACPIName, L"%02X%02X",(value & 0xFF ) ,( value >> 8 ));
}
VOID
EXPORT
AmlisuppCompletePassive(
IN PNSOBJ AcpiObject,
IN NTSTATUS Status,
IN POBJDATA Result,
IN PVOID Context
)
/*++
Routine Description:
This is used as the completion routine for several
functions in this file that run at passive level.
Arguments:
AcpiObject - unused
Status - status to be returned to caller
Result - unused
Context - contains the event to be set
Return Value:
none
--*/
{
PRKEVENT event = &((PAMLISUPP_CONTEXT_PASSIVE)Context)->Event;
ASSERT(Context);
((PAMLISUPP_CONTEXT_PASSIVE)Context)->Status = Status;
KeSetEvent(event, IO_NO_INCREMENT, FALSE);
}
PNSOBJ
ACPIAmliGetNamedChild(
IN PNSOBJ AcpiObject,
IN ULONG ObjectId
)
/*++
Routine Description:
Looks at all the children of AcpiObject and returns
the one named 'ObjectId'.
Arguments:
AcpiObject - Object to search in
ObjectId - What we are looking for
Return Value:
A PNSOBJ, NULL if none
--*/
{
PNSOBJ tempObject;
//
// Lets try to find a child object
//
for (tempObject = NSGETFIRSTCHILD(AcpiObject);
tempObject != NULL;
tempObject = NSGETNEXTSIBLING(tempObject)) {
if (ObjectId == tempObject->dwNameSeg) {
break;
}
}
return tempObject;
}
PUCHAR
ACPIAmliNameObject(
IN PNSOBJ AcpiObject
)
/*++
Routine Description:
Returns a String that describes the objects
Debug Only
Arguments:
AcpiOBject - The object to name
Returns:
String
--*/
{
static UCHAR buffer[5];
RtlCopyMemory( &buffer[0], &(AcpiObject->dwNameSeg), 4 );
buffer[4] = '\0';
return &(buffer[0]);
}
NTSTATUS
ACPIAmliFindObject(
IN PUCHAR ObjectName,
IN PNSOBJ Scope,
OUT PNSOBJ *Object
)
/*++
Routine Description:
Finds the first occurrence of an object within a given scope.
Arguments:
ObjectName - Name of the object. (null terminated)
Scope - Node to search under
Object - Pointer to return value
Returns:
status
--*/
{
NTSTATUS status;
PNSOBJ child;
PNSOBJ sibling;
PAGED_CODE();
status = AMLIGetNameSpaceObject(ObjectName,
Scope,
Object,
NSF_LOCAL_SCOPE);
if (NT_SUCCESS(status)) {
return status;
}
child = NSGETFIRSTCHILD(Scope);
if (child) {
status = ACPIAmliFindObject(ObjectName,
child,
Object);
if (NT_SUCCESS(status)) {
return status;
}
}
sibling = NSGETNEXTSIBLING(Scope);
if (sibling) {
status = ACPIAmliFindObject(ObjectName,
sibling,
Object);
}
return status;
}
NTSTATUS
ACPIAmliGetFirstChild(
IN PUCHAR ObjectName,
OUT PNSOBJ *Object)
/*++
Routine Description:
This routine is called to get the first nsobject which is of type 'Device'
that lives under ObjectName
Arguments:
ObjectName - The parent of the child we are looking for
Object - Where to save a pointer to the PNSOBJ
Return Value:
NTSTATUS
--*/
{
NTSTATUS status;
PNSOBJ parentObj;
status = AMLIGetNameSpaceObject(
ObjectName,
NULL,
&parentObj,
0
);
if (!NT_SUCCESS(status)) {
return status;
}
*Object = parentObj->pnsFirstChild;
if (*Object == NULL ) {
return STATUS_OBJECT_NAME_NOT_FOUND;
}
if ( NSGETOBJTYPE(*Object) == OBJTYPE_DEVICE) {
return STATUS_SUCCESS;
}
*Object = (PNSOBJ) (*Object)->list.plistNext;
parentObj = parentObj->pnsFirstChild;
while (*Object != parentObj) {
if ( NSGETOBJTYPE( *Object ) == OBJTYPE_DEVICE) {
return STATUS_SUCCESS;
}
*Object = (PNSOBJ) (*Object)->list.plistNext;
}
*Object = NULL;
return STATUS_OBJECT_NAME_NOT_FOUND;
}
NTSTATUS
ACPIAmliBuildObjectPathname(
IN PNSOBJ ACPIObject,
OUT PUCHAR *ConstructedPathName
)
/*++
Routine Description:
This function takes an ACPI node and constructs the full path name with
the parent/children seperated by '.'s, spaces with '*'s. e.g. (we smack
off the initial '\___'.
_SB*.PCI0.DOCK
Arguments:
ACPIObject - Object to start the enumeration at.
ConstructedPathName - Allocated from the paged pool.
Return Value:
NTSTATUS
--*/
{
PNSOBJ currentAcpiObject, nextAcpiObject ;
ULONG nDepth, i, j ;
PUCHAR objectPathname ;
ASSERT(ACPIObject) ;
//
// First, calculate the size of data we must allocate
//
nDepth=0 ;
currentAcpiObject=ACPIObject ;
while(1) {
nextAcpiObject = NSGETPARENT(currentAcpiObject);
if (!nextAcpiObject) {
break;
}
nDepth++;
currentAcpiObject = nextAcpiObject;
}
objectPathname = (PUCHAR) ExAllocatePoolWithTag(
NonPagedPool,
(nDepth * 5) + 1,
ACPI_STRING_POOLTAG
);
if (!objectPathname) {
return STATUS_INSUFFICIENT_RESOURCES ;
}
objectPathname[ nDepth * 5 ] = '\0';
j = nDepth;
currentAcpiObject = ACPIObject;
while(1) {
nextAcpiObject = NSGETPARENT(currentAcpiObject);
if (!nextAcpiObject) {
break;
}
j--;
RtlCopyMemory(
&objectPathname[ (j * 5) ],
&(currentAcpiObject->dwNameSeg),
sizeof(NAMESEG)
);
for(i = 0; i < 4; i++) {
if (objectPathname[ (j * 5) + i ] == '\0' ) {
objectPathname[ (j * 5) + i ] = '*';
}
}
objectPathname[ (j * 5) + 4 ] = '.';
currentAcpiObject = nextAcpiObject;
}
//
// Smack of trailing '.'
//
if (nDepth) {
objectPathname[ (nDepth * 5) - 1 ] = '\0';
}
*ConstructedPathName = objectPathname;
return STATUS_SUCCESS;
}