2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/debug.c
5 * PURPOSE: Debug Helpers
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
16 /* GLOBALS ********************************************************************/
21 "QUERY_REMOVE_DEVICE",
23 "CANCEL_REMOVE_DEVICE",
27 "QUERY_DEVICE_RELATIONS",
31 "QUERY_RESOURCE_REQUIREMENTS",
33 "FILTER_RESOURCE_REQUIREMENTS",
34 "** UNKNOWN PNP IRP Minor Code **",
40 "QUERY_PNP_DEVICE_STATE",
41 "QUERY_BUS_INFORMATION",
42 "DEVICE_USAGE_NOTIFICATION"
53 PCHAR SystemPowerStates
[] =
64 PCHAR DevicePowerStates
[] =
73 ULONG PciBreakOnPdoPowerIrp
, PciBreakOnFdoPowerIrp
;
74 ULONG PciBreakOnPdoPnpIrp
, PciBreakOnFdoPnpIrp
;
76 /* FUNCTIONS ******************************************************************/
80 PciDebugPnpIrpTypeToText(IN USHORT MinorFunction
)
84 /* Catch invalid code */
85 if (MinorFunction
>= IRP_MN_SURPRISE_REMOVAL
)
87 /* New version of Windows? Or driver bug */
88 Text
= "** UNKNOWN PNP IRP Minor Code **";
92 /* Get the right text for it */
93 Text
= PnpCodes
[MinorFunction
];
96 /* Return the symbolic name for the IRP */
102 PciDebugPoIrpTypeToText(IN USHORT MinorFunction
)
106 /* Catch invalid code */
107 if (MinorFunction
>= IRP_MN_QUERY_POWER
)
109 /* New version of Windows? Or driver bug */
110 Text
= "** UNKNOWN PO IRP Minor Code **";
114 /* Get the right text for it */
115 Text
= PoCodes
[MinorFunction
];
118 /* Return the symbolic name for the IRP */
124 PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation
,
125 IN PPCI_FDO_EXTENSION DeviceExtension
,
128 PPCI_PDO_EXTENSION PdoDeviceExtension
;
130 //ULONG DebugLevel = 0;
133 /* Only two functions are recognized */
134 switch (IoStackLocation
->MajorFunction
)
138 /* Get the string and the correct break mask for the extension */
139 BreakMask
= (DeviceExtension
->ExtensionType
== PciPdoExtensionType
) ?
140 PciBreakOnPdoPowerIrp
: PciBreakOnFdoPowerIrp
;
141 IrpString
= PciDebugPoIrpTypeToText(IoStackLocation
->MinorFunction
);
146 /* Get the string and the correct break mask for the extension */
147 BreakMask
= (DeviceExtension
->ExtensionType
== PciFdoExtensionType
) ?
148 PciBreakOnPdoPnpIrp
: PciBreakOnFdoPnpIrp
;
149 IrpString
= PciDebugPnpIrpTypeToText(IoStackLocation
->MinorFunction
);
154 /* Other functions are not decoded */
160 /* Check if this is a PDO */
161 if (DeviceExtension
->ExtensionType
== PciPdoExtensionType
)
163 /* Choose the correct debug level based on which function this is */
164 if (IoStackLocation
->MajorFunction
== IRP_MJ_POWER
)
166 //DebugLevel = 0x500;
168 else if (IoStackLocation
->MajorFunction
== IRP_MJ_PNP
)
170 //DebugLevel = 0x200;
173 /* For a PDO, print out the bus, device, and function number */
174 PdoDeviceExtension
= (PVOID
)DeviceExtension
;
175 DPRINT1("PDO(b=0x%x, d=0x%x, f=0x%x)<-%s\n",
176 PdoDeviceExtension
->ParentFdoExtension
->BaseBus
,
177 PdoDeviceExtension
->Slot
.u
.bits
.DeviceNumber
,
178 PdoDeviceExtension
->Slot
.u
.bits
.FunctionNumber
,
181 else if (DeviceExtension
->ExtensionType
== PciFdoExtensionType
)
183 /* Choose the correct debug level based on which function this is */
184 if (IoStackLocation
->MajorFunction
== IRP_MJ_POWER
)
186 //DebugLevel = 0x400;
188 else if (IoStackLocation
->MajorFunction
== IRP_MJ_PNP
)
190 //DebugLevel = 0x100;
193 /* For an FDO, just dump the extension pointer and IRP string */
194 DPRINT1("FDO(%p)<-%s\n", DeviceExtension
, IrpString
);
197 /* If the function is illegal for this extension, complain */
198 if (IoStackLocation
->MinorFunction
> MaxMinor
)
199 DPRINT1("Unknown IRP, minor = 0x%x\n", IoStackLocation
->MinorFunction
);
201 /* Return whether or not the debugger should be broken into for this IRP */
202 return ((1 << IoStackLocation
->MinorFunction
) & BreakMask
);
207 PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData
)
211 /* Loop the PCI header */
212 for (i
= 0; i
< PCI_COMMON_HDR_LENGTH
; i
+= 4)
214 /* Dump each DWORD and its offset */
215 DPRINT1(" %02x - %08x\n", i
, *(PULONG
)((ULONG_PTR
)PciData
+ i
));
221 PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps
)
225 /* Dump the capabilities */
226 DPRINT1("Capabilities\n Lock:%u, Eject:%u, Remove:%u, Dock:%u, UniqueId:%u\n",
227 DeviceCaps
->LockSupported
,
228 DeviceCaps
->EjectSupported
,
229 DeviceCaps
->Removable
,
230 DeviceCaps
->DockDevice
,
231 DeviceCaps
->UniqueID
);
232 DbgPrint(" SilentInstall:%u, RawOk:%u, SurpriseOk:%u\n",
233 DeviceCaps
->SilentInstall
,
234 DeviceCaps
->RawDeviceOK
,
235 DeviceCaps
->SurpriseRemovalOK
);
236 DbgPrint(" Address %08x, UINumber %08x, Latencies D1 %u, D2 %u, D3 %u\n",
238 DeviceCaps
->UINumber
,
239 DeviceCaps
->D1Latency
,
240 DeviceCaps
->D2Latency
,
241 DeviceCaps
->D3Latency
);
243 /* Dump and convert the wake levels */
244 DbgPrint(" System Wake: %s, Device Wake: %s\n DeviceState[PowerState] [",
245 SystemPowerStates
[min(DeviceCaps
->SystemWake
, PowerSystemMaximum
)],
246 DevicePowerStates
[min(DeviceCaps
->DeviceWake
, PowerDeviceMaximum
)]);
248 /* Dump and convert the power state mappings */
249 for (i
= PowerSystemWorking
; i
< PowerSystemMaximum
; i
++)
250 DbgPrint(" %s", DevicePowerStates
[DeviceCaps
->DeviceState
[i
]]);
252 /* Finish the dump */
258 PciDebugCmResourceTypeToText(IN UCHAR Type
)
260 /* What kind of resource it this? */
263 /* Pick the correct identifier string based on the type */
264 case CmResourceTypeDeviceSpecific
: return "CmResourceTypeDeviceSpecific";
265 case CmResourceTypePort
: return "CmResourceTypePort";
266 case CmResourceTypeInterrupt
: return "CmResourceTypeInterrupt";
267 case CmResourceTypeMemory
: return "CmResourceTypeMemory";
268 case CmResourceTypeDma
: return "CmResourceTypeDma";
269 case CmResourceTypeBusNumber
: return "CmResourceTypeBusNumber";
270 case CmResourceTypeConfigData
: return "CmResourceTypeConfigData";
271 case CmResourceTypeDevicePrivate
: return "CmResourceTypeDevicePrivate";
272 case CmResourceTypePcCardConfig
: return "CmResourceTypePcCardConfig";
273 default: return "*** INVALID RESOURCE TYPE ***";
279 PciDebugPrintIoResource(IN PIO_RESOURCE_DESCRIPTOR Descriptor
)
284 /* Print out the header */
285 DPRINT1(" IoResource Descriptor dump: Descriptor @0x%p\n", Descriptor
);
286 DPRINT1(" Option = 0x%x\n", Descriptor
->Option
);
287 DPRINT1(" Type = %u (%s)\n", Descriptor
->Type
, PciDebugCmResourceTypeToText(Descriptor
->Type
));
288 DPRINT1(" ShareDisposition = %u\n", Descriptor
->ShareDisposition
);
289 DPRINT1(" Flags = 0x%04X\n", Descriptor
->Flags
);
291 /* Loop private data */
292 Data
= (PULONG
)&Descriptor
->u
.DevicePrivate
;
293 for (i
= 0; i
< 6; i
+= 3)
295 /* Dump it in 32-bit triplets */
296 DPRINT1(" Data[%u] = %08x %08x %08x\n", i
, Data
[0], Data
[1], Data
[2]);
302 PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements
)
304 ULONG AlternativeLists
;
305 PIO_RESOURCE_LIST List
;
307 PIO_RESOURCE_DESCRIPTOR Descriptor
;
309 /* Make sure there's a list */
310 if (!Requirements
) return;
312 /* Grab the main list and the alternates as well */
313 AlternativeLists
= Requirements
->AlternativeLists
;
314 List
= Requirements
->List
;
316 /* Print out the initial header*/
317 DPRINT1(" IO_RESOURCE_REQUIREMENTS_LIST (PCI Bus Driver)\n");
318 DPRINT1(" InterfaceType %d\n", Requirements
->InterfaceType
);
319 DPRINT1(" BusNumber 0x%x\n", Requirements
->BusNumber
);
320 DPRINT1(" SlotNumber %d (0x%x), (d/f = 0x%x/0x%x)\n",
321 Requirements
->SlotNumber
,
322 Requirements
->SlotNumber
,
323 ((PCI_SLOT_NUMBER
*)&Requirements
->SlotNumber
)->u
.bits
.DeviceNumber
,
324 ((PCI_SLOT_NUMBER
*)&Requirements
->SlotNumber
)->u
.bits
.FunctionNumber
);
325 DPRINT1(" AlternativeLists %u\n", AlternativeLists
);
327 /* Scan alternative lists */
328 while (AlternativeLists
--)
330 /* Get the descriptor array, and the count of descriptors */
331 Descriptor
= List
->Descriptors
;
334 /* Print out each descriptor */
335 DPRINT1("\n List[%u].Count = %u\n", AlternativeLists
, Count
);
336 while (Count
--) PciDebugPrintIoResource(Descriptor
++);
338 /* Should've reached a new list now */
339 List
= (PIO_RESOURCE_LIST
)Descriptor
;
342 /* Terminate the dump */
348 PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource
)
350 /* Dump all the data in the partial */
351 DPRINT1(" Partial Resource Descriptor @0x%p\n", PartialResource
);
352 DPRINT1(" Type = %u (%s)\n", PartialResource
->Type
, PciDebugCmResourceTypeToText(PartialResource
->Type
));
353 DPRINT1(" ShareDisposition = %u\n", PartialResource
->ShareDisposition
);
354 DPRINT1(" Flags = 0x%04X\n", PartialResource
->Flags
);
355 DPRINT1(" Data[%d] = %08x %08x %08x\n",
357 PartialResource
->u
.Generic
.Start
.LowPart
,
358 PartialResource
->u
.Generic
.Start
.HighPart
,
359 PartialResource
->u
.Generic
.Length
);
364 PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList
)
366 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor
;
367 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
368 ULONG Count
, i
, ListCount
;
370 /* Make sure there's something to dump */
371 if (!PartialList
) return;
373 /* Get the full list count */
374 ListCount
= PartialList
->Count
;
375 FullDescriptor
= PartialList
->List
;
376 DPRINT1(" CM_RESOURCE_LIST (PCI Bus Driver) (List Count = %u)\n", PartialList
->Count
);
379 for (i
= 0; i
< ListCount
; i
++)
381 /* Loop full descriptor */
382 DPRINT1(" InterfaceType %d\n", FullDescriptor
->InterfaceType
);
383 DPRINT1(" BusNumber 0x%x\n", FullDescriptor
->BusNumber
);
385 /* Get partial count and loop partials */
386 Count
= FullDescriptor
->PartialResourceList
.Count
;
387 for (PartialDescriptor
= FullDescriptor
->PartialResourceList
.PartialDescriptors
;
389 PartialDescriptor
= PciNextPartialDescriptor(PartialDescriptor
))
391 /* Print each partial */
392 PciDebugPrintPartialResource(PartialDescriptor
);
397 /* Done printing data */