/* GLOBALS ********************************************************************/
+PCHAR PnpCodes[] =
+{
+ "START_DEVICE",
+ "QUERY_REMOVE_DEVICE",
+ "REMOVE_DEVICE",
+ "CANCEL_REMOVE_DEVICE",
+ "STOP_DEVICE",
+ "QUERY_STOP_DEVICE",
+ "CANCEL_STOP_DEVICE",
+ "QUERY_DEVICE_RELATIONS",
+ "QUERY_INTERFACE",
+ "QUERY_CAPABILITIES",
+ "QUERY_RESOURCES",
+ "QUERY_RESOURCE_REQUIREMENTS",
+ "QUERY_DEVICE_TEXT",
+ "FILTER_RESOURCE_REQUIREMENTS",
+ "** UNKNOWN PNP IRP Minor Code **",
+ "READ_CONFIG",
+ "WRITE_CONFIG",
+ "EJECT",
+ "SET_LOCK",
+ "QUERY_ID",
+ "QUERY_PNP_DEVICE_STATE",
+ "QUERY_BUS_INFORMATION",
+ "DEVICE_USAGE_NOTIFICATION"
+};
+
+PCHAR PoCodes[] =
+{
+ "WAIT_WAKE",
+ "POWER_SEQUENCE",
+ "SET_POWER",
+ "QUERY_POWER",
+};
+
+PCHAR SystemPowerStates[] =
+{
+ "Unspecified",
+ "Working",
+ "Sleeping1",
+ "Sleeping2",
+ "Sleeping3",
+ "Hibernate",
+ "Shutdown"
+};
+
+PCHAR DevicePowerStates[] =
+{
+ "Unspecified",
+ "D0",
+ "D1",
+ "D2",
+ "D3"
+};
+
+ULONG PciBreakOnPdoPowerIrp, PciBreakOnFdoPowerIrp;
+ULONG PciBreakOnPdoPnpIrp, PciBreakOnFdoPnpIrp;
+
/* FUNCTIONS ******************************************************************/
+PCHAR
+NTAPI
+PciDebugPnpIrpTypeToText(IN USHORT MinorFunction)
+{
+ PCHAR Text;
+
+ /* Catch invalid code */
+ if (MinorFunction >= IRP_MN_SURPRISE_REMOVAL)
+ {
+ /* New version of Windows? Or driver bug */
+ Text = "** UNKNOWN PNP IRP Minor Code **";
+ }
+ else
+ {
+ /* Get the right text for it */
+ Text = PnpCodes[MinorFunction];
+ }
+
+ /* Return the symbolic name for the IRP */
+ return Text;
+}
+
+PCHAR
+NTAPI
+PciDebugPoIrpTypeToText(IN USHORT MinorFunction)
+{
+ PCHAR Text;
+
+ /* Catch invalid code */
+ if (MinorFunction >= IRP_MN_QUERY_POWER)
+ {
+ /* New version of Windows? Or driver bug */
+ Text = "** UNKNOWN PO IRP Minor Code **";
+ }
+ else
+ {
+ /* Get the right text for it */
+ Text = PoCodes[MinorFunction];
+ }
+
+ /* Return the symbolic name for the IRP */
+ return Text;
+}
+
+BOOLEAN
+NTAPI
+PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_FDO_EXTENSION DeviceExtension,
+ IN USHORT MaxMinor)
+{
+ PPCI_PDO_EXTENSION PdoDeviceExtension;
+ ULONG BreakMask;
+ //ULONG DebugLevel = 0;
+ PCHAR IrpString;
+
+ /* Only two functions are recognized */
+ switch (IoStackLocation->MajorFunction)
+ {
+ case IRP_MJ_POWER:
+
+ /* Get the string and the correct break mask for the extension */
+ BreakMask = (DeviceExtension->ExtensionType == PciPdoExtensionType) ?
+ PciBreakOnPdoPowerIrp : PciBreakOnFdoPowerIrp;
+ IrpString = PciDebugPoIrpTypeToText(IoStackLocation->MinorFunction);
+ break;
+
+ case IRP_MJ_PNP:
+
+ /* Get the string and the correct break mask for the extension */
+ BreakMask = (DeviceExtension->ExtensionType == PciFdoExtensionType) ?
+ PciBreakOnPdoPnpIrp : PciBreakOnFdoPnpIrp;
+ IrpString = PciDebugPnpIrpTypeToText(IoStackLocation->MinorFunction);
+ break;
+
+ default:
+
+ /* Other functions are not decoded */
+ BreakMask = FALSE;
+ IrpString = "";
+ break;
+ }
+
+ /* Check if this is a PDO */
+ if (DeviceExtension->ExtensionType == PciPdoExtensionType)
+ {
+ /* Choose the correct debug level based on which function this is */
+ if (IoStackLocation->MajorFunction == IRP_MJ_POWER)
+ {
+ //DebugLevel = 0x500;
+ }
+ else if (IoStackLocation->MajorFunction == IRP_MJ_PNP)
+ {
+ //DebugLevel = 0x200;
+ }
+
+ /* For a PDO, print out the bus, device, and function number */
+ PdoDeviceExtension = (PVOID)DeviceExtension;
+ DPRINT1("PDO(b=0x%x, d=0x%x, f=0x%x)<-%s\n",
+ PdoDeviceExtension->ParentFdoExtension->BaseBus,
+ PdoDeviceExtension->Slot.u.bits.DeviceNumber,
+ PdoDeviceExtension->Slot.u.bits.FunctionNumber,
+ IrpString);
+ }
+ else if (DeviceExtension->ExtensionType == PciFdoExtensionType)
+ {
+ /* Choose the correct debug level based on which function this is */
+ if (IoStackLocation->MajorFunction == IRP_MJ_POWER)
+ {
+ //DebugLevel = 0x400;
+ }
+ else if (IoStackLocation->MajorFunction == IRP_MJ_PNP)
+ {
+ //DebugLevel = 0x100;
+ }
+
+ /* For an FDO, just dump the extension pointer and IRP string */
+ DPRINT1("FDO(%p)<-%s\n", DeviceExtension, IrpString);
+ }
+
+ /* If the function is illegal for this extension, complain */
+ if (IoStackLocation->MinorFunction > MaxMinor)
+ DPRINT1("Unknown IRP, minor = 0x%x\n", IoStackLocation->MinorFunction);
+
+ /* Return whether or not the debugger should be broken into for this IRP */
+ return ((1 << IoStackLocation->MinorFunction) & BreakMask);
+}
+
+VOID
+NTAPI
+PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData)
+{
+ USHORT i;
+
+ /* Loop the PCI header */
+ for (i = 0; i < PCI_COMMON_HDR_LENGTH; i += 4)
+ {
+ /* Dump each DWORD and its offset */
+ DPRINT1(" %02x - %08x\n", i, *(PULONG)((ULONG_PTR)PciData + i));
+ }
+}
+
+VOID
+NTAPI
+PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps)
+{
+ ULONG i;
+
+ /* Dump the capabilities */
+ DPRINT1("Capabilities\n Lock:%u, Eject:%u, Remove:%u, Dock:%u, UniqueId:%u\n",
+ DeviceCaps->LockSupported,
+ DeviceCaps->EjectSupported,
+ DeviceCaps->Removable,
+ DeviceCaps->DockDevice,
+ DeviceCaps->UniqueID);
+ DbgPrint(" SilentInstall:%u, RawOk:%u, SurpriseOk:%u\n",
+ DeviceCaps->SilentInstall,
+ DeviceCaps->RawDeviceOK,
+ DeviceCaps->SurpriseRemovalOK);
+ DbgPrint(" Address %08x, UINumber %08x, Latencies D1 %u, D2 %u, D3 %u\n",
+ DeviceCaps->Address,
+ DeviceCaps->UINumber,
+ DeviceCaps->D1Latency,
+ DeviceCaps->D2Latency,
+ DeviceCaps->D3Latency);
+
+ /* Dump and convert the wake levels */
+ DbgPrint(" System Wake: %s, Device Wake: %s\n DeviceState[PowerState] [",
+ SystemPowerStates[min(DeviceCaps->SystemWake, PowerSystemMaximum)],
+ DevicePowerStates[min(DeviceCaps->DeviceWake, PowerDeviceMaximum)]);
+
+ /* Dump and convert the power state mappings */
+ for (i = PowerSystemWorking; i < PowerSystemMaximum; i++)
+ DbgPrint(" %s", DevicePowerStates[DeviceCaps->DeviceState[i]]);
+
+ /* Finish the dump */
+ DbgPrint(" ]\n");
+}
+
+PCHAR
+NTAPI
+PciDebugCmResourceTypeToText(IN UCHAR Type)
+{
+ /* What kind of resource it this? */
+ switch (Type)
+ {
+ /* Pick the correct identifier string based on the type */
+ case CmResourceTypeDeviceSpecific: return "CmResourceTypeDeviceSpecific";
+ case CmResourceTypePort: return "CmResourceTypePort";
+ case CmResourceTypeInterrupt: return "CmResourceTypeInterrupt";
+ case CmResourceTypeMemory: return "CmResourceTypeMemory";
+ case CmResourceTypeDma: return "CmResourceTypeDma";
+ case CmResourceTypeBusNumber: return "CmResourceTypeBusNumber";
+ case CmResourceTypeConfigData: return "CmResourceTypeConfigData";
+ case CmResourceTypeDevicePrivate: return "CmResourceTypeDevicePrivate";
+ case CmResourceTypePcCardConfig: return "CmResourceTypePcCardConfig";
+ default: return "*** INVALID RESOURCE TYPE ***";
+ }
+}
+
+VOID
+NTAPI
+PciDebugPrintIoResource(IN PIO_RESOURCE_DESCRIPTOR Descriptor)
+{
+ ULONG i;
+ PULONG Data;
+
+ /* Print out the header */
+ DPRINT1(" IoResource Descriptor dump: Descriptor @0x%p\n", Descriptor);
+ DPRINT1(" Option = 0x%x\n", Descriptor->Option);
+ DPRINT1(" Type = %u (%s)\n", Descriptor->Type, PciDebugCmResourceTypeToText(Descriptor->Type));
+ DPRINT1(" ShareDisposition = %u\n", Descriptor->ShareDisposition);
+ DPRINT1(" Flags = 0x%04X\n", Descriptor->Flags);
+
+ /* Loop private data */
+ Data = (PULONG)&Descriptor->u.DevicePrivate;
+ for (i = 0; i < 6; i += 3)
+ {
+ /* Dump it in 32-bit triplets */
+ DPRINT1(" Data[%u] = %08x %08x %08x\n", i, Data[0], Data[1], Data[2]);
+ }
+}
+
+VOID
+NTAPI
+PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements)
+{
+ ULONG AlternativeLists;
+ PIO_RESOURCE_LIST List;
+ ULONG Count;
+ PIO_RESOURCE_DESCRIPTOR Descriptor;
+
+ /* Make sure there's a list */
+ if (!Requirements) return;
+
+ /* Grab the main list and the alternates as well */
+ AlternativeLists = Requirements->AlternativeLists;
+ List = Requirements->List;
+
+ /* Print out the initial header*/
+ DPRINT1(" IO_RESOURCE_REQUIREMENTS_LIST (PCI Bus Driver)\n");
+ DPRINT1(" InterfaceType %d\n", Requirements->InterfaceType);
+ DPRINT1(" BusNumber 0x%x\n", Requirements->BusNumber);
+ DPRINT1(" SlotNumber %d (0x%x), (d/f = 0x%x/0x%x)\n",
+ Requirements->SlotNumber,
+ Requirements->SlotNumber,
+ ((PCI_SLOT_NUMBER*)&Requirements->SlotNumber)->u.bits.DeviceNumber,
+ ((PCI_SLOT_NUMBER*)&Requirements->SlotNumber)->u.bits.FunctionNumber);
+ DPRINT1(" AlternativeLists %u\n", AlternativeLists);
+
+ /* Scan alternative lists */
+ while (AlternativeLists--)
+ {
+ /* Get the descriptor array, and the count of descriptors */
+ Descriptor = List->Descriptors;
+ Count = List->Count;
+
+ /* Print out each descriptor */
+ DPRINT1("\n List[%u].Count = %u\n", AlternativeLists, Count);
+ while (Count--) PciDebugPrintIoResource(Descriptor++);
+
+ /* Should've reached a new list now */
+ List = (PIO_RESOURCE_LIST)Descriptor;
+ }
+
+ /* Terminate the dump */
+ DPRINT1("\n");
+}
+
+VOID
+NTAPI
+PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource)
+{
+ /* Dump all the data in the partial */
+ DPRINT1(" Partial Resource Descriptor @0x%p\n", PartialResource);
+ DPRINT1(" Type = %u (%s)\n", PartialResource->Type, PciDebugCmResourceTypeToText(PartialResource->Type));
+ DPRINT1(" ShareDisposition = %u\n", PartialResource->ShareDisposition);
+ DPRINT1(" Flags = 0x%04X\n", PartialResource->Flags);
+ DPRINT1(" Data[%d] = %08x %08x %08x\n",
+ 0,
+ PartialResource->u.Generic.Start.LowPart,
+ PartialResource->u.Generic.Start.HighPart,
+ PartialResource->u.Generic.Length);
+}
+
+VOID
+NTAPI
+PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList)
+{
+ PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ ULONG Count, i, ListCount;
+
+ /* Make sure there's something to dump */
+ if (!PartialList) return;
+
+ /* Get the full list count */
+ ListCount = PartialList->Count;
+ FullDescriptor = PartialList->List;
+ DPRINT1(" CM_RESOURCE_LIST (PCI Bus Driver) (List Count = %u)\n", PartialList->Count);
+
+ /* Loop full list */
+ for (i = 0; i < ListCount; i++)
+ {
+ /* Loop full descriptor */
+ DPRINT1(" InterfaceType %d\n", FullDescriptor->InterfaceType);
+ DPRINT1(" BusNumber 0x%x\n", FullDescriptor->BusNumber);
+
+ /* Get partial count and loop partials */
+ Count = FullDescriptor->PartialResourceList.Count;
+ for (PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
+ Count;
+ PartialDescriptor = PciNextPartialDescriptor(PartialDescriptor))
+ {
+ /* Print each partial */
+ PciDebugPrintPartialResource(PartialDescriptor);
+ Count--;
+ }
+ }
+
+ /* Done printing data */
+ DPRINT1("\n");
+}
+
+
/* EOF */