/*++ Copyright (c) 1997-2000 Microsoft Corporation Module Name: debug.c Abstract: This module contains debug functions for PCI.SYS. Author: Peter Johnston (peterj) 12-Feb-1997 Revision History: --*/ #include "pcip.h" PUCHAR PciDebugInterfaceTypeToText( ULONG InterfaceType ); PUCHAR PciDebugCmResourceTypeToText( UCHAR Type ); #if DBG #define PCI_DEBUG_BUFFER_SIZE 256 PCI_DEBUG_LEVEL PciDebug = PciDbgAlways; ULONG PciDebugStop = 0; UCHAR PciDebugBuffer[PCI_DEBUG_BUFFER_SIZE]; #endif VOID PciDebugPrintIfLevel( PCI_DEBUG_LEVEL DebugPrintLevel, PCCHAR DebugMessage, ... ) /*++ Routine Description: Debug print for the PCI Bus Driver. Arguments: Debug print level between 0 and 3, with 3 being the most verbose. A bit mask corresponding to various debug items. Note: This used to be a level, for backward compatibility, 0 is treated as print always. Return Value: None --*/ { #if DBG va_list ap; va_start(ap, DebugMessage); if (PCI_DEBUGGING_OKAY() && (DebugPrintLevel & PciDebug)) { if (FAILED(StringCbVPrintfA(PciDebugBuffer, sizeof(PciDebugBuffer), DebugMessage, ap))) { DbgPrint("Pci Debug Print Failed! Format string was %s", DebugMessage); } else { DbgPrint(PciDebugBuffer); } } va_end(ap); #endif } // end PciDebugPrint() VOID PciDebugPrintf( PCCHAR DebugMessage, ... ) /*++ Routine Description: Debug print for the PCI Bus Driver. Arguments: The message to print Return Value: None --*/ { #if DBG va_list ap; va_start(ap, DebugMessage); if (PCI_DEBUGGING_OKAY()) { if (FAILED(StringCbVPrintfA(PciDebugBuffer, sizeof(PciDebugBuffer), DebugMessage, ap))) { DbgPrint("Pci Debug Print Failed! Format string was %s", DebugMessage); } else { DbgPrint(PciDebugBuffer); } } va_end(ap); #endif } VOID PciDebugHit( ULONG StopOnBit ) /*++ Routine Description: Called from various places with various bits for arguments. If the bit(s) are a subset of the bits in the global PciDebugStop, call PciDebugBreak. Arguments: Stop bit(s). Return Value: None --*/ { #if DBG if (PCI_DEBUGGING_OKAY() && (StopOnBit & PciDebugStop)) { DbgBreakPoint(); } #endif } //++ // // Miscellaneous Debug printing routines. // //-- #if DBG static UCHAR PnpIrpUnknownText[] = "** UNKNOWN PNP IRP Minor Code **"; static UCHAR PoIrpUnknownText[] = "** UNKNOWN PO IRP Minor Code **"; // // The following really begin with "IRP_MN_" // static PUCHAR PnpIrpTypeStrings[] = { "START_DEVICE", // 0x00 "QUERY_REMOVE_DEVICE", // 0x01 "REMOVE_DEVICE", // 0x02 "CANCEL_REMOVE_DEVICE", // 0x03 "STOP_DEVICE", // 0x04 "QUERY_STOP_DEVICE", // 0x05 "CANCEL_STOP_DEVICE", // 0x06 "QUERY_DEVICE_RELATIONS", // 0x07 "QUERY_INTERFACE", // 0x08 "QUERY_CAPABILITIES", // 0x09 "QUERY_RESOURCES", // 0x0A "QUERY_RESOURCE_REQUIREMENTS", // 0x0B "QUERY_DEVICE_TEXT", // 0x0C "FILTER_RESOURCE_REQUIREMENTS",// 0x0D PnpIrpUnknownText, // 0x0E "READ_CONFIG", // 0x0F "WRITE_CONFIG", // 0x10 "EJECT", // 0x11 "SET_LOCK", // 0x12 "QUERY_ID", // 0x13 "QUERY_PNP_DEVICE_STATE", // 0x14 "QUERY_BUS_INFORMATION", // 0x15 "DEVICE_USAGE_NOTIFICATION" // 0x16 }; static PUCHAR PoIrpTypeStrings[] = { "WAIT_WAKE", // 0x00 "POWER_SEQUENCE", // 0x01 "SET_POWER", // 0x02 "QUERY_POWER" // 0x03 }; static PUCHAR SystemPowerStateStrings[] = { "Unspecified", "Working", "Sleeping1", "Sleeping2", "Sleeping3", "Hibernate", "Shutdown" }; static PUCHAR DevicePowerStateStrings[] = { "Unspecified", "D0", "D1", "D2", "D3" }; PUCHAR PciDebugCmResourceTypeToText( UCHAR Type ) { switch (Type) { case CmResourceTypePort: return "CmResourceTypePort"; case CmResourceTypeInterrupt: return "CmResourceTypeInterrupt"; case CmResourceTypeMemory: return "CmResourceTypeMemory"; case CmResourceTypeDma: return "CmResourceTypeDma"; case CmResourceTypeDeviceSpecific: return "CmResourceTypeDeviceSpecific"; case CmResourceTypeBusNumber: return "CmResourceTypeBusNumber"; case CmResourceTypeConfigData: return "CmResourceTypeConfigData"; case CmResourceTypeDevicePrivate: return "CmResourceTypeDevicePrivate"; case CmResourceTypePcCardConfig: return "CmResourceTypePcCardConfig"; default: return "*** INVALID RESOURCE TYPE ***"; } } PUCHAR PciDebugPnpIrpTypeToText( ULONG IrpMinorCode ) { if (IrpMinorCode < (sizeof(PnpIrpTypeStrings)/sizeof(PUCHAR))) { return PnpIrpTypeStrings[IrpMinorCode]; } return PnpIrpUnknownText; } PUCHAR PciDebugPoIrpTypeToText( ULONG IrpMinorCode ) { if (IrpMinorCode < (sizeof(PoIrpTypeStrings)/sizeof(PUCHAR))) { return PoIrpTypeStrings[IrpMinorCode]; } return PoIrpUnknownText; } VOID PciDebugDumpCommonConfig( IN PPCI_COMMON_CONFIG CommonConfig ) { PULONG dw; ULONG i; if (PciDebug < PciDbgPrattling) { return; } dw = (PULONG)CommonConfig; for (i = 0; i < PCI_COMMON_HDR_LENGTH; i += sizeof(ULONG)) { PciDebugPrintf(" %02x - %08x\n", i, *dw); dw++; } } VOID PciDebugDumpQueryCapabilities( IN PDEVICE_CAPABILITIES C ) { // // Dump the DEVICE_CAPABILITIES structure pointed to by C. // SYSTEM_POWER_STATE sw = C->SystemWake; DEVICE_POWER_STATE dw = C->DeviceWake; ULONG i; PciDebugPrintf( "Capabilities\n Lock:%d, Eject:%d, Remove:%d, Dock:%d, UniqueId:%d\n", C->LockSupported, C->EjectSupported, C->Removable, C->DockDevice, C->UniqueID ); PciDebugPrintf( " SilentInstall:%d, RawOk:%d, SurpriseOk:%d\n", C->SilentInstall, C->RawDeviceOK, C->SurpriseRemovalOK ); PciDebugPrintf( " Address %08x, UINumber %08x, Latencies D1 %d, D2 %d, D3 %d\n", C->Address, C->UINumber, C->D1Latency, C->D2Latency, C->D3Latency ); if (sw > PowerSystemMaximum) { sw = PowerSystemMaximum; } if (dw > PowerDeviceMaximum) { dw = PowerDeviceMaximum; } PciDebugPrintf( " System Wake: %s, Device Wake: %s\n DeviceState[PowerState] [", SystemPowerStateStrings[sw], DevicePowerStateStrings[dw] ); for (i = PowerSystemWorking; i < (sizeof(C->DeviceState) / sizeof(C->DeviceState[0])); i++) { dw = C->DeviceState[i]; if (dw > PowerDeviceMaximum) { dw = PowerDeviceMaximum; } PciDebugPrintf(" %s", DevicePowerStateStrings[dw]); } PciDebugPrintf(" ]\n"); } VOID PciDebugPrintIoResource( IN PIO_RESOURCE_DESCRIPTOR D ) { ULONG i; PUCHAR t; t = PciDebugCmResourceTypeToText(D->Type); PciDebugPrintf(" IoResource Descriptor dump: Descriptor @0x%x\n", D); PciDebugPrintf(" Option = 0x%x\n", D->Option); PciDebugPrintf(" Type = %d (%s)\n", D->Type, t); PciDebugPrintf(" ShareDisposition = %d\n", D->ShareDisposition); PciDebugPrintf(" Flags = 0x%04X\n", D->Flags); for ( i = 0; i < 6; i+=3 ) { PciDebugPrintf(" Data[%d] = %08x %08x %08x\n", i, D->u.DevicePrivate.Data[i], D->u.DevicePrivate.Data[i+1], D->u.DevicePrivate.Data[i+2]); } } VOID PciDebugPrintIoResReqList( IN PIO_RESOURCE_REQUIREMENTS_LIST IoResReqList ) { ULONG numlists; PIO_RESOURCE_LIST list; if ((PciDebug < PciDbgPrattling) || (IoResReqList == NULL)) { return; } numlists = IoResReqList->AlternativeLists; list = IoResReqList->List; PciDebugPrintf(" IO_RESOURCE_REQUIREMENTS_LIST (PCI Bus Driver)\n"); PciDebugPrintf(" InterfaceType %d\n", IoResReqList->InterfaceType); PciDebugPrintf(" BusNumber 0x%x\n", IoResReqList->BusNumber ); PciDebugPrintf(" SlotNumber %d (0x%x), (d/f = 0x%x/0x%x)\n", IoResReqList->SlotNumber, // in decimal IoResReqList->SlotNumber, // in hex IoResReqList->SlotNumber & 0x1f, // device number (IoResReqList->SlotNumber >> 5) & 0x7 // function ); PciDebugPrintf(" AlternativeLists %d\n", numlists ); while (numlists--) { PIO_RESOURCE_DESCRIPTOR resource = list->Descriptors; ULONG count = list->Count; PciDebugPrintf("\n List[%d].Count = %d\n", numlists, count); while (count--) { PciDebugPrintIoResource(resource++); } list = (PIO_RESOURCE_LIST)resource; } PciDebugPrintf("\n"); } VOID PciDebugPrintPartialResource( PCI_DEBUG_LEVEL DebugPrintLevel, IN PCM_PARTIAL_RESOURCE_DESCRIPTOR D ) { ULONG i; PUCHAR t; if (!(PciDebug & DebugPrintLevel)) { return; } t = PciDebugCmResourceTypeToText(D->Type); PciDebugPrintf(" Partial Resource Descriptor @0x%x\n", D); PciDebugPrintf(" Type = %d (%s)\n", D->Type, t); PciDebugPrintf(" ShareDisposition = %d\n", D->ShareDisposition); PciDebugPrintf(" Flags = 0x%04X\n", D->Flags); for ( i = 0; i < 3; i+=3 ) { PciDebugPrintf(" Data[%d] = %08x %08x %08x\n", i, D->u.DevicePrivate.Data[i], D->u.DevicePrivate.Data[i+1], D->u.DevicePrivate.Data[i+2]); } } VOID PciDebugPrintCmResList( PCI_DEBUG_LEVEL DebugPrintLevel, IN PCM_RESOURCE_LIST ResourceList ) { ULONG numlists; PCM_FULL_RESOURCE_DESCRIPTOR full; PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor; if (!ResourceList || !(PciDebug & DebugPrintLevel)) { return; } numlists = ResourceList->Count; full = ResourceList->List; PciDebugPrintf(" CM_RESOURCE_LIST (PCI Bus Driver) (List Count = %d)\n", numlists); while (numlists--) { PCM_PARTIAL_RESOURCE_LIST partial = &full->PartialResourceList; ULONG count = partial->Count; PciDebugPrintf(" InterfaceType %d\n", full->InterfaceType); PciDebugPrintf(" BusNumber 0x%x\n", full->BusNumber ); descriptor = partial->PartialDescriptors; while (count--) { PciDebugPrintPartialResource(DebugPrintLevel, descriptor); descriptor = PciNextPartialDescriptor(descriptor); } full = (PCM_FULL_RESOURCE_DESCRIPTOR)descriptor; } PciDebugPrintf("\n"); } static UCHAR InterfaceTypeUnknownText[] = "** Unknown interface type **"; static PUCHAR InterfaceTypeText[] = { "InterfaceTypeUndefined", // -1 "Internal", // 0 "Isa", // 1 "Eisa", // 2 "MicroChannel", // 3 "TurboChannel", // 4 "PCIBus", // 5 "VMEBus", // 6 "NuBus", // 7 "PCMCIABus", // 8 "CBus", // 9 "MPIBus", // 10 "MPSABus", // 11 "ProcessorInternal", // 12 "InternalPowerBus", // 13 "PNPISABus", // 14 "PNPBus" // 15 }; PUCHAR PciDebugInterfaceTypeToText( ULONG InterfaceType ) { if (InterfaceType < MaximumInterfaceType) { PCI_ASSERT(InterfaceType + 1 < sizeof(InterfaceTypeText) / sizeof(PUCHAR)); return InterfaceTypeText[InterfaceType + 1]; } return InterfaceTypeUnknownText; } #endif