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

1142 lines
25 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:
debug.c
Abstract:
This module contains the enumerated for the ACPI driver, NT version
Author:
Stephane Plante (splante)
Environment:
NT Kernel Model Driver only
--*/
#include "pch.h"
#if DBG
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, ACPIDebugResourceDescriptor)
#pragma alloc_text(PAGE, ACPIDebugResourceList)
#pragma alloc_text(PAGE, ACPIDebugResourceRequirementsList)
#pragma alloc_text(PAGE, ACPIDebugCmResourceList)
#endif
#define ACPI_DEBUG_BUFFER_SIZE 256
PCCHAR ACPIDispatchPnpTableNames[ACPIDispatchPnpTableSize] = {
"IRP_MN_START_DEVICE",
"IRP_MN_QUERY_REMOVE_DEVICE",
"IRP_MN_REMOVE_DEVICE",
"IRP_MN_CANCEL_REMOVE_DEVICE",
"IRP_MN_STOP_DEVICE",
"IRP_MN_QUERY_STOP_DEVICE",
"IRP_MN_CANCEL_STOP_DEVICE",
"IRP_MN_QUERY_DEVICE_RELATIONS",
"IRP_MN_QUERY_INTERFACE",
"IRP_MN_QUERY_CAPABILITIES",
"IRP_MN_QUERY_RESOURCES",
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
"IRP_MN_QUERY_DEVICE_TEXT",
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
"INVALID MINOR IRP CODE",
"IRP_MN_READ_CONFIG",
"IRP_MN_WRITE_CONFIG",
"IRP_MN_EJECT",
"IRP_MN_SET_LOCK",
"IRP_MN_QUERY_ID",
"IRP_MN_QUERY_PNP_DEVICE_STATE",
"IRP_MN_QUERY_BUS_INFORMATION",
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
"IRP_MN_SURPRISE_REMOVAL",
"UNKNOWN PNP MINOR CODE"
};
PCCHAR ACPIDispatchPowerTableNames[ACPIDispatchPowerTableSize] = {
"IRP_MN_WAIT_WAKE",
"IRP_MN_POWER_SEQUENCE",
"IRP_MN_SET_POWER",
"IRP_MN_QUERY_POWER",
"UNKNOWN POWER MINOR CODE"
};
PCCHAR ACPIDispatchUnknownTableName[1] = {
"IRP_MN_????"
};
#endif
VOID
_ACPIInternalError(
IN ULONG Bugcode
)
{
KeBugCheckEx (ACPI_DRIVER_INTERNAL, 0x1, Bugcode, 0, 0);
}
#if DBG
VOID
ACPIDebugPrint(
ULONG DebugPrintLevel,
PCCHAR DebugMessage,
...
)
/*++
Routine Description:
This is the debug print routine for the NT side of things. This is
here because we don't want to use the 'shared' ACPIPrint() function
since we can't control it.
Arguments:
DebugPrintLevel - The bit mask that when anded with the debuglevel, must
equal itself
DebugMessage - The string to feed through vsprintf
Return Value:
None
--*/
{
va_list ap;
//
// Get the variable arguments
//
va_start( ap, DebugMessage );
//
// Call the kernel function to print the message
//
vDbgPrintEx( DPFLTR_ACPI_ID, DebugPrintLevel, DebugMessage, ap );
//
// We are done with the varargs
//
va_end( ap );
}
VOID
ACPIDebugDevicePrint(
ULONG DebugPrintLevel,
PVOID DebugExtension,
PCCHAR DebugMessage,
...
)
/*++
Routine Description:
This is the debug print routine for the NT side of things. This routine
is here to handle the case where we are printing information that is
associated with a device extension.
Arguments:
DebugPrintLevel - The big mask that when and'ed with the debug level, must
equal itself
DeviceExtension - The device associated with the message
DebugMessage - The string to feed through vsprintf
Return Value:
NTSTATUS
---*/
{
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DebugExtension;
va_list ap;
//
// Get the variable arguments
//
va_start( ap, DebugMessage );
//
// What kind of device extension are we looking at?
//
if (deviceExtension->Flags & DEV_PROP_HID) {
//
// Now that we have a _HID, do we also have a _UID?
//
if (deviceExtension->Flags & DEV_PROP_UID) {
DbgPrintEx(
DPFLTR_ACPI_ID,
DebugPrintLevel,
"%p %s-%s ",
deviceExtension,
deviceExtension->DeviceID,
deviceExtension->InstanceID
);
} else {
DbgPrintEx(
DPFLTR_ACPI_ID,
DebugPrintLevel,
"%p %s ",
deviceExtension,
deviceExtension->DeviceID
);
}
} else if (deviceExtension->Flags & DEV_PROP_ADDRESS) {
DbgPrintEx(
DPFLTR_ACPI_ID,
DebugPrintLevel,
"%p %x ",
deviceExtension,
deviceExtension->Address
);
} else {
DbgPrintEx(
DPFLTR_ACPI_ID,
DebugPrintLevel,
"%p ",
deviceExtension
);
}
//
// Call the kernel function to print the message
//
vDbgPrintEx( DPFLTR_ACPI_ID, DebugPrintLevel, DebugMessage, ap );
//
// We are done with the varargs
//
va_end( ap );
}
PCCHAR
ACPIDebugGetIrpText(
UCHAR MajorFunction,
UCHAR MinorFunction
)
/*++
Routine Description:
This function returns a const pointer to the text string appropriate for
the passed in major and minor IRP.
Arguments:
MajorFunction
MinorFunction
Return Value:
const pointer to descriptive IRP text.
--*/
{
ULONG index ;
PCCHAR *minorTable ;
switch(MajorFunction) {
case IRP_MJ_PNP:
index = ACPIDispatchPnpTableSize - 1;
minorTable = ACPIDispatchPnpTableNames ;
break;
case IRP_MJ_POWER:
index = ACPIDispatchPowerTableSize - 1;
minorTable = ACPIDispatchPowerTableNames ;
break;
default:
index = 0 ;
minorTable = ACPIDispatchUnknownTableName ;
break;
}
if (MinorFunction < index) {
index = MinorFunction;
}
return minorTable[index];
}
VOID
ACPIDebugResourceDescriptor(
IN PIO_RESOURCE_DESCRIPTOR Descriptor,
IN ULONG ListCount,
IN ULONG DescCount
)
/*++
Routine Description:
This function dumps the contents of a single resource descriptor.
Arguments:
Descriptor - What to dump
ListCount - The number of the current list
DescCount - The number of the current descriptor
--*/
{
PAGED_CODE();
ASSERT( Descriptor != NULL );
//
// Dump the appropriate info
//
switch (Descriptor->Type) {
case CmResourceTypePort:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] %-9s MininumAddress = %#08lx MaximumAddress = %#08lx\n"
" Length = %#08lx Alignment = %#08lx\n",
ListCount,
DescCount,
"Port",
Descriptor->u.Port.MinimumAddress.LowPart,
Descriptor->u.Port.MaximumAddress.LowPart,
Descriptor->u.Port.Length,
Descriptor->u.Port.Alignment
) );
break;
case CmResourceTypeMemory:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] %-9s MinimumAddress = %#08lx MaximumAddress = %#08lx\n"
" Length = %#08lx Alignment = %#08lx\n",
ListCount,
DescCount,
"Memory",
Descriptor->u.Memory.MinimumAddress.LowPart,
Descriptor->u.Memory.MaximumAddress.LowPart,
Descriptor->u.Memory.Length,
Descriptor->u.Memory.Alignment
) );
break;
case CmResourceTypeInterrupt:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] %-9s MinimumVector = %#08lx MaximumVector = %#08lx\n",
ListCount,
DescCount,
"Interrupt",
Descriptor->u.Interrupt.MinimumVector,
Descriptor->u.Interrupt.MaximumVector
) );
break;
case CmResourceTypeDma:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] %-9s MinimumChannel = %#08lx MaximumChannel = %#08lx\n",
ListCount,
DescCount,
"Dma",
Descriptor->u.Dma.MinimumChannel,
Descriptor->u.Dma.MaximumChannel
) );
break;
default:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] Type = (%d)\n",
ListCount,
DescCount,
Descriptor->Type
) );
} // switch
//
// Dump the common info
//
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
" Option,Share = %#04lx%#04lx Flags = %#08lx\n",
ListCount,
DescCount,
Descriptor->Option,
Descriptor->ShareDisposition
) );
} // for
VOID
ACPIDebugResourceList(
IN PIO_RESOURCE_LIST List,
IN ULONG Count
)
/*++
Routine Description:
This functions displays the contents of a single resource list, so that it
can be checked by a human
Arguments:
List - List to dump
Count - The List number (for visual reference)
Return Value:
None
--*/
{
ULONG i;
PAGED_CODE();
ASSERT( List != NULL );
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] %#04x Version = %#08lx Revision = %#08lx\n",
Count,
List->Count,
List->Version,
List->Revision
) );
for (i = 0; i < List->Count; i++ ) {
//
// Print the info on the current element
//
ACPIDebugResourceDescriptor( &(List->Descriptors[i]), Count, i );
}
}
VOID
ACPIDebugResourceRequirementsList(
IN PIO_RESOURCE_REQUIREMENTS_LIST List,
IN PDEVICE_EXTENSION DeviceExtension
)
/*++
Routine Description:
This function displays a resource list in a method that can be checked
for accuracy when the driver is loading up
Arguments:
List - The list to dump
Object - NameSpace object associated with this list
Return Value:
None
--*/
{
PUCHAR buffer;
PIO_RESOURCE_LIST list;
ULONG i;
ULONG size;
PAGED_CODE();
ACPIDevPrint( (
ACPI_PRINT_RESOURCES_1,
DeviceExtension,
"IoResourceRequirementsList @ %x\n",
List
) );
if (List == NULL) {
return;
}
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"%x size: %xb alternatives: %x bus type: %x bus number %x\n",
List,
List->ListSize,
List->AlternativeLists,
List->InterfaceType,
List->BusNumber
) );
//
// Point to the first list
//
list = &(List->List[0]);
buffer = (PUCHAR) list;
for (i = 0; i < List->AlternativeLists && buffer < ( (PUCHAR)List + List->ListSize ); i++) {
//
// Dump the current list
//
ACPIDebugResourceList( list, i );
//
// Determine the size of the list, and find the next one
//
size = sizeof(IO_RESOURCE_LIST) + (list->Count - 1) * sizeof(IO_RESOURCE_DESCRIPTOR);
buffer += size;
//
// This should be pointing at a list
//
list = (PIO_RESOURCE_LIST) buffer;
}
}
VOID
ACPIDebugCmResourceList(
IN PCM_RESOURCE_LIST List,
IN PDEVICE_EXTENSION DeviceExtension
)
/*++
Routine Description:
This function displays a resource list in a method that can be checked
for accuracy when the driver is loading up
Arguments:
List - The list to dump
Device - The associated device extension
Return Value:
None
--*/
{
PCM_FULL_RESOURCE_DESCRIPTOR fullDesc;
PCM_PARTIAL_RESOURCE_DESCRIPTOR partDesc;
PUCHAR buffer;
ULONG i;
ULONG j;
ULONG size;
PAGED_CODE();
ACPIDevPrint( (
ACPI_PRINT_RESOURCES_1,
DeviceExtension,
"CmResourceList @ %x\n",
List
) );
if (List == NULL) {
return;
}
if (List->Count == 0) {
ACPIDevPrint( (
ACPI_PRINT_RESOURCES_1,
DeviceExtension,
"There are no full resource descriptors in the list\n"
) );
return;
}
//
// Start to walk this data structure
//
fullDesc = &(List->List[0]);
buffer = (PUCHAR) fullDesc;
for (i = 0; i < List->Count; i++) {
//
// How long is the current list
//
size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
(fullDesc->PartialResourceList.Count - 1) *
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
//
// Point the buffer there
//
buffer += size;
//
// Dump the information about the current list
//
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] BusNumber = %#04x Interface = %#04x\n"
"[%2d] Count = %#04x Version = %#04x Revision = %#04x\n",
i,
fullDesc->BusNumber,
fullDesc->InterfaceType,
i,
fullDesc->PartialResourceList.Count,
fullDesc->PartialResourceList.Version,
fullDesc->PartialResourceList.Revision
) );
//
// Walk this list
//
for (j = 0; j < fullDesc->PartialResourceList.Count; j++) {
//
// Current item
//
partDesc = &(fullDesc->PartialResourceList.PartialDescriptors[j]);
//
// Dump Principal Information...
//
switch (partDesc->Type) {
case CmResourceTypePort:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] %12s Start: %#08lx Length: %#08lx\n",
i,
j,
"Port",
partDesc->u.Port.Start.LowPart,
partDesc->u.Port.Length
) );
break;
case CmResourceTypeInterrupt:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] %12s Level: %#02x Vector: %#02x Affinity: %#08lx\n",
i,
j,
"Interrupt",
partDesc->u.Interrupt.Level,
partDesc->u.Interrupt.Vector,
partDesc->u.Interrupt.Affinity
) );
break;
case CmResourceTypeMemory:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] %12s Start: %#08lx Length: %#08lx\n",
i,
j,
"Memory",
partDesc->u.Memory.Start.LowPart,
partDesc->u.Memory.Length
) );
break;
case CmResourceTypeDma:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] %12s Channel: %#02x Port: %#02x Reserved: %#02x\n",
i,
j,
"Dma",
partDesc->u.Dma.Channel,
partDesc->u.Dma.Port,
partDesc->u.Dma.Reserved1
) );
break;
default:
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
"[%2d] [%2d] Type: %2d 1: %#08lx 2: %#08lx 3: %#08lx\n",
i,
j,
partDesc->Type,
partDesc->u.DeviceSpecificData.DataSize,
partDesc->u.DeviceSpecificData.Reserved1,
partDesc->u.DeviceSpecificData.Reserved2
) );
break;
}
//
// Dump ancillary info
//
ACPIPrint( (
ACPI_PRINT_RESOURCES_1,
" Flags: %#08lx Share: %#08lx\n",
partDesc->Flags,
partDesc->ShareDisposition
) );
}
//
// Grab new list
//
fullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) buffer;
}
}
VOID
ACPIDebugDeviceCapabilities(
IN PDEVICE_EXTENSION DeviceExtension,
IN PDEVICE_CAPABILITIES DeviceCapabilities,
IN PUCHAR Message
)
/*++
Routine Description:
This will display the device capabilities in an interesting format
Arguments:
DeviceExtension The device whose' capabilities we are dumping
DeviceCapabilites The capabilities that we are interested in
Message Message to print
Return Value:
None
--*/
{
SYSTEM_POWER_STATE index;
ACPIDevPrint( (
ACPI_PRINT_SXD,
DeviceExtension,
" - %s - Capabilities @ %08lx\n",
Message,
DeviceCapabilities
) );
ACPIDevPrint( (
ACPI_PRINT_SXD,
DeviceExtension,
" -"
) );
for (index = PowerSystemWorking; index < PowerSystemMaximum; index++) {
if (DeviceCapabilities->DeviceState[index] == PowerSystemUnspecified) {
ACPIPrint( (
ACPI_PRINT_SXD,
" S%d -> None",
(index - 1)
) );
} else {
ACPIPrint( (
ACPI_PRINT_SXD,
" S%d -> D%x",
(index - 1),
(DeviceCapabilities->DeviceState[index] - 1)
) );
}
}
ACPIPrint( (
ACPI_PRINT_SXD,
"\n"
) );
ACPIDevPrint( (
ACPI_PRINT_SXD,
DeviceExtension,
" -"
) );
if (DeviceCapabilities->SystemWake == PowerSystemUnspecified) {
ACPIPrint( (
ACPI_PRINT_SXD,
" SystemWake = None"
) );
} else {
ACPIPrint( (
ACPI_PRINT_SXD,
" SystemWake = S%d",
(DeviceCapabilities->SystemWake - 1)
) );
}
if (DeviceCapabilities->DeviceWake == PowerDeviceUnspecified) {
ACPIPrint( (
ACPI_PRINT_SXD,
" DeviceWake = None"
) );
} else {
ACPIPrint( (
ACPI_PRINT_SXD,
" DeviceWake = D%d",
(DeviceCapabilities->DeviceWake - 1)
) );
}
if (DeviceCapabilities->DeviceD1) {
ACPIPrint( (
ACPI_PRINT_SXD,
" DeviceD1"
) );
}
if (DeviceCapabilities->DeviceD2) {
ACPIPrint( (
ACPI_PRINT_SXD,
" DeviceD2"
) );
}
if (DeviceCapabilities->WakeFromD0) {
ACPIPrint( (
ACPI_PRINT_SXD,
" WakeD0"
) );
}
if (DeviceCapabilities->WakeFromD1) {
ACPIPrint( (
ACPI_PRINT_SXD,
" WakeD1"
) );
}
if (DeviceCapabilities->WakeFromD2) {
ACPIPrint( (
ACPI_PRINT_SXD,
" WakeD2"
) );
}
if (DeviceCapabilities->WakeFromD3) {
ACPIPrint( (
ACPI_PRINT_SXD,
" WakeD3"
) );
}
ACPIPrint( (
ACPI_PRINT_SXD,
"\n"
) );
}
VOID
ACPIDebugPowerCapabilities(
IN PDEVICE_EXTENSION DeviceExtension,
IN PUCHAR Message
)
/*++
Routine Description:
This will display the device capabilities in an interesting format
Arguments:
DeviceExtension The device whose' capabilities we are dumping
Message Identify where capabilities are fron
Return Value:
--*/
{
PACPI_POWER_INFO powerInfo = &(DeviceExtension->PowerInfo);
SYSTEM_POWER_STATE index;
ACPIDevPrint( (
ACPI_PRINT_SXD,
DeviceExtension,
" - %s - Internal Capabilities\n",
Message
) );
ACPIDevPrint( (
ACPI_PRINT_SXD,
DeviceExtension,
" -"
) );
for (index = PowerSystemWorking; index < PowerSystemMaximum; index++) {
if (powerInfo->DevicePowerMatrix[index] == PowerSystemUnspecified) {
ACPIPrint( (
ACPI_PRINT_SXD,
" S%d -> None",
(index - 1)
) );
} else {
ACPIPrint( (
ACPI_PRINT_SXD,
" S%d -> D%x",
(index - 1),
(powerInfo->DevicePowerMatrix[index] - 1)
) );
}
}
ACPIPrint( (
ACPI_PRINT_SXD,
"\n"
) );
ACPIDevPrint( (
ACPI_PRINT_SXD,
DeviceExtension,
" -"
) );
if (powerInfo->SystemWakeLevel == PowerSystemUnspecified) {
ACPIPrint( (
ACPI_PRINT_SXD,
" SystemWake = None"
) );
} else {
ACPIPrint( (
ACPI_PRINT_SXD,
" SystemWake = S%d",
(powerInfo->SystemWakeLevel - 1)
) );
}
if (powerInfo->DeviceWakeLevel == PowerDeviceUnspecified) {
ACPIPrint( (
ACPI_PRINT_SXD,
" DeviceWake = None"
) );
} else {
ACPIPrint( (
ACPI_PRINT_SXD,
" DeviceWake = D%d",
(powerInfo->DeviceWakeLevel - 1)
) );
}
if (powerInfo->SupportDeviceD1) {
ACPIPrint( (
ACPI_PRINT_SXD,
" DeviceD1"
) );
}
if (powerInfo->SupportDeviceD2) {
ACPIPrint( (
ACPI_PRINT_SXD,
" DeviceD2"
) );
}
if (powerInfo->SupportWakeFromD0) {
ACPIPrint( (
ACPI_PRINT_SXD,
" WakeD0"
) );
}
if (powerInfo->SupportWakeFromD1) {
ACPIPrint( (
ACPI_PRINT_SXD,
" WakeD1"
) );
}
if (powerInfo->SupportWakeFromD2) {
ACPIPrint( (
ACPI_PRINT_SXD,
" WakeD2"
) );
}
if (powerInfo->SupportWakeFromD3) {
ACPIPrint( (
ACPI_PRINT_SXD,
" WakeD3"
) );
}
ACPIPrint( (
ACPI_PRINT_SXD,
"\n"
) );
}
VOID
ACPIDebugThermalPrint(
ULONG DebugPrintLevel,
PVOID DebugExtension,
ULONGLONG DebugTime,
PCCHAR DebugMessage,
...
)
/*++
Routine Description:
This is the debug print routine for the NT side of things. This routine
is here to handle the case where we are printing information that is
associated with a device extension.
Arguments:
DebugPrintLevel - The big mask that when and'ed with the debug level, must
equal itself
DeviceExtension - The device associated with the message
DebugTime - The time that event occured
DebugMessage - The string to feed through vsprintf
Return Value:
NTSTATUS
---*/
{
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DebugExtension;
LARGE_INTEGER curTime;
TIME_FIELDS exCurTime;
va_list ap;
va_start( ap, DebugMessage );
//
// What kind of device extension are we looking at?
//
if (deviceExtension->Flags & DEV_PROP_HID) {
//
// Now that we have a _HID, do we also have a _UID?
//
if (deviceExtension->Flags & DEV_PROP_UID) {
DbgPrintEx(
DPFLTR_ACPI_ID,
DebugPrintLevel,
"%p %s-%s ",
deviceExtension,
deviceExtension->DeviceID,
deviceExtension->InstanceID
);
} else {
DbgPrintEx(
DPFLTR_ACPI_ID,
DebugPrintLevel,
"%p %s ",
deviceExtension,
deviceExtension->DeviceID
);
}
} else if (deviceExtension->Flags & DEV_PROP_ADDRESS) {
DbgPrintEx(
DPFLTR_ACPI_ID,
DebugPrintLevel,
"%p %x ",
deviceExtension,
deviceExtension->Address
);
} else {
DbgPrintEx(
DPFLTR_ACPI_ID,
DebugPrintLevel,
"%p ",
deviceExtension
);
}
//
// Print the time string
//
curTime.QuadPart = DebugTime;
RtlTimeToTimeFields( &curTime, &exCurTime );
DbgPrintEx(
DPFLTR_ACPI_ID,
DebugPrintLevel,
"%d:%02d:%02d.%03d ",
exCurTime.Hour,
exCurTime.Minute,
exCurTime.Second,
exCurTime.Milliseconds
);
//
// Call the kernel function to print the message
//
vDbgPrintEx( DPFLTR_ACPI_ID, DebugPrintLevel, DebugMessage, ap );
//
// We are done with the varargs
//
va_end( ap );
}
#endif