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 *******************************************************************/
15 /* GLOBALS ********************************************************************/
20 "QUERY_REMOVE_DEVICE",
22 "CANCEL_REMOVE_DEVICE",
26 "QUERY_DEVICE_RELATIONS",
30 "QUERY_RESOURCE_REQUIREMENTS",
32 "FILTER_RESOURCE_REQUIREMENTS",
33 "** UNKNOWN PNP IRP Minor Code **",
39 "QUERY_PNP_DEVICE_STATE",
40 "QUERY_BUS_INFORMATION",
41 "DEVICE_USAGE_NOTIFICATION"
52 PCHAR SystemPowerStates
[] =
63 PCHAR DevicePowerStates
[] =
72 ULONG PciBreakOnPdoPowerIrp
, PciBreakOnFdoPowerIrp
;
73 ULONG PciBreakOnPdoPnpIrp
, PciBreakOnFdoPnpIrp
;
75 /* FUNCTIONS ******************************************************************/
79 PciDebugPnpIrpTypeToText(IN USHORT MinorFunction
)
83 /* Catch invalid code */
84 if (MinorFunction
>= IRP_MN_SURPRISE_REMOVAL
)
86 /* New version of Windows? Or driver bug */
87 Text
= "** UNKNOWN PNP IRP Minor Code **";
91 /* Get the right text for it */
92 Text
= PnpCodes
[MinorFunction
];
95 /* Return the symbolic name for the IRP */
101 PciDebugPoIrpTypeToText(IN USHORT MinorFunction
)
105 /* Catch invalid code */
106 if (MinorFunction
>= IRP_MN_QUERY_POWER
)
108 /* New version of Windows? Or driver bug */
109 Text
= "** UNKNOWN PO IRP Minor Code **";
113 /* Get the right text for it */
114 Text
= PoCodes
[MinorFunction
];
117 /* Return the symbolic name for the IRP */
123 PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation
,
124 IN PPCI_FDO_EXTENSION DeviceExtension
,
127 PPCI_PDO_EXTENSION PdoDeviceExtension
;
128 ULONG BreakMask
, DebugLevel
= 0;
131 /* Only two functions are recognized */
132 switch (IoStackLocation
->MajorFunction
)
136 /* Get the string and the correct break mask for the extension */
137 BreakMask
= (DeviceExtension
->ExtensionType
== PciPdoExtensionType
) ?
138 PciBreakOnPdoPowerIrp
: PciBreakOnFdoPowerIrp
;
139 IrpString
= PciDebugPoIrpTypeToText(IoStackLocation
->MinorFunction
);
144 /* Get the string and the correct break mask for the extension */
145 BreakMask
= (DeviceExtension
->ExtensionType
== PciFdoExtensionType
) ?
146 PciBreakOnPdoPnpIrp
: PciBreakOnFdoPnpIrp
;
147 IrpString
= PciDebugPnpIrpTypeToText(IoStackLocation
->MinorFunction
);
152 /* Other functions are not decoded */
158 /* Check if this is a PDO */
159 if (DeviceExtension
->ExtensionType
== PciPdoExtensionType
)
161 /* Choose the correct debug level based on which function this is */
162 if (IoStackLocation
->MajorFunction
== IRP_MJ_POWER
)
166 else if (IoStackLocation
->MajorFunction
== IRP_MJ_PNP
)
171 /* For a PDO, print out the bus, device, and function number */
172 PdoDeviceExtension
= (PVOID
)DeviceExtension
;
173 DPRINT1("PDO(b=0x%x, d=0x%x, f=0x%x)<-%s\n",
174 PdoDeviceExtension
->ParentFdoExtension
->BaseBus
,
175 PdoDeviceExtension
->Slot
.u
.bits
.DeviceNumber
,
176 PdoDeviceExtension
->Slot
.u
.bits
.FunctionNumber
,
179 else if (DeviceExtension
->ExtensionType
== PciFdoExtensionType
)
181 /* Choose the correct debug level based on which function this is */
182 if (IoStackLocation
->MajorFunction
== IRP_MJ_POWER
)
186 else if (IoStackLocation
->MajorFunction
== IRP_MJ_PNP
)
191 /* For an FDO, just dump the extension pointer and IRP string */
192 DPRINT1("FDO(%x)<-%s\n", DeviceExtension
, IrpString
);
195 /* If the function is illegal for this extension, complain */
196 if (IoStackLocation
->MinorFunction
> MaxMinor
)
197 DPRINT1("Unknown IRP, minor = 0x%x\n", IoStackLocation
->MinorFunction
);
199 /* Return whether or not the debugger should be broken into for this IRP */
200 return ((1 << IoStackLocation
->MinorFunction
) & BreakMask
);
205 PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData
)
209 /* Loop the PCI header */
210 for (i
= 0; i
< PCI_COMMON_HDR_LENGTH
; i
+= 4)
212 /* Dump each DWORD and its offset */
213 DPRINT1(" %02x - %08x\n", i
, *(PULONG
)((ULONG_PTR
)PciData
+ i
));
219 PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps
)
223 /* Dump the capabilities */
224 DPRINT1("Capabilities\n Lock:%d, Eject:%d, Remove:%d, Dock:%d, UniqueId:%d\n",
225 DeviceCaps
->LockSupported
,
226 DeviceCaps
->EjectSupported
,
227 DeviceCaps
->Removable
,
228 DeviceCaps
->DockDevice
,
229 DeviceCaps
->UniqueID
);
230 DbgPrint(" SilentInstall:%d, RawOk:%d, SurpriseOk:%d\n",
231 DeviceCaps
->SilentInstall
,
232 DeviceCaps
->RawDeviceOK
,
233 DeviceCaps
->SurpriseRemovalOK
);
234 DbgPrint(" Address %08x, UINumber %08x, Latencies D1 %d, D2 %d, D3 %d\n",
236 DeviceCaps
->UINumber
,
237 DeviceCaps
->D1Latency
,
238 DeviceCaps
->D2Latency
,
239 DeviceCaps
->D3Latency
);
241 /* Dump and convert the wake levels */
242 DbgPrint(" System Wake: %s, Device Wake: %s\n DeviceState[PowerState] [",
243 SystemPowerStates
[min(DeviceCaps
->SystemWake
, PowerSystemMaximum
)],
244 DevicePowerStates
[min(DeviceCaps
->DeviceWake
, PowerDeviceMaximum
)]);
246 /* Dump and convert the power state mappings */
247 for (i
= PowerSystemWorking
; i
< PowerSystemMaximum
; i
++)
248 DbgPrint(" %s", DevicePowerStates
[DeviceCaps
->DeviceState
[i
]]);
250 /* Finish the dump */
256 PciDebugCmResourceTypeToText(IN UCHAR Type
)
258 /* What kind of resource it this? */
261 /* Pick the correct identifier string based on the type */
262 case CmResourceTypeDeviceSpecific
: return "CmResourceTypeDeviceSpecific";
263 case CmResourceTypePort
: return "CmResourceTypePort";
264 case CmResourceTypeInterrupt
: return "CmResourceTypeInterrupt";
265 case CmResourceTypeMemory
: return "CmResourceTypeMemory";
266 case CmResourceTypeDma
: return "CmResourceTypeDma";
267 case CmResourceTypeBusNumber
: return "CmResourceTypeBusNumber";
268 case CmResourceTypeConfigData
: return "CmResourceTypeConfigData";
269 case CmResourceTypeDevicePrivate
: return "CmResourceTypeDevicePrivate";
270 case CmResourceTypePcCardConfig
: return "CmResourceTypePcCardConfig";
271 default: return "*** INVALID RESOURCE TYPE ***";
277 PciDebugPrintIoResource(IN PIO_RESOURCE_DESCRIPTOR Descriptor
)
282 /* Print out the header */
283 DPRINT1(" IoResource Descriptor dump: Descriptor @0x%x\n", Descriptor
);
284 DPRINT1(" Option = 0x%x\n", Descriptor
->Option
);
285 DPRINT1(" Type = %d (%s)\n", Descriptor
->Type
, PciDebugCmResourceTypeToText(Descriptor
->Type
));
286 DPRINT1(" ShareDisposition = %d\n", Descriptor
->ShareDisposition
);
287 DPRINT1(" Flags = 0x%04X\n", Descriptor
->Flags
);
289 /* Loop private data */
290 Data
= (PULONG
)&Descriptor
->u
.DevicePrivate
;
291 for (i
= 0; i
< 6; i
+= 3)
293 /* Dump it in 32-bit triplets */
294 DPRINT1(" Data[%d] = %08x %08x %08x\n", i
, Data
[0], Data
[1], Data
[2]);
300 PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements
)
302 ULONG AlternativeLists
;
303 PIO_RESOURCE_LIST List
;
305 PIO_RESOURCE_DESCRIPTOR Descriptor
;
307 /* Make sure there's a list */
308 if (!Requirements
) return;
310 /* Grab the main list and the alternates as well */
311 AlternativeLists
= Requirements
->AlternativeLists
;
312 List
= Requirements
->List
;
314 /* Print out the initial header*/
315 DPRINT1(" IO_RESOURCE_REQUIREMENTS_LIST (PCI Bus Driver)\n");
316 DPRINT1(" InterfaceType %d\n", Requirements
->InterfaceType
);
317 DPRINT1(" BusNumber 0x%x\n", Requirements
->BusNumber
);
318 DPRINT1(" SlotNumber %d (0x%x), (d/f = 0x%x/0x%x)\n",
319 Requirements
->SlotNumber
,
320 Requirements
->SlotNumber
,
321 ((PCI_SLOT_NUMBER
*)&Requirements
->SlotNumber
)->u
.bits
.DeviceNumber
,
322 ((PCI_SLOT_NUMBER
*)&Requirements
->SlotNumber
)->u
.bits
.FunctionNumber
);
323 DPRINT1(" AlternativeLists %d\n", AlternativeLists
);
325 /* Scan alternative lists */
326 while (AlternativeLists
--)
328 /* Get the descriptor array, and the count of descriptors */
329 Descriptor
= List
->Descriptors
;
332 /* Print out each descriptor */
333 DPRINT1("\n List[%d].Count = %d\n", AlternativeLists
, Count
);
334 while (Count
--) PciDebugPrintIoResource(Descriptor
++);
336 /* Should've reached a new list now */
337 List
= (PIO_RESOURCE_LIST
)Descriptor
;
340 /* Terminate the dump */
346 PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource
)
348 /* Dump all the data in the partial */
349 DPRINT1(" Partial Resource Descriptor @0x%x\n", PartialResource
);
350 DPRINT1(" Type = %d (%s)\n", PartialResource
->Type
, PciDebugCmResourceTypeToText(PartialResource
->Type
));
351 DPRINT1(" ShareDisposition = %d\n", PartialResource
->ShareDisposition
);
352 DPRINT1(" Flags = 0x%04X\n", PartialResource
->Flags
);
353 DPRINT1(" Data[%d] = %08x %08x %08x\n",
355 PartialResource
->u
.Generic
.Start
.LowPart
,
356 PartialResource
->u
.Generic
.Start
.HighPart
,
357 PartialResource
->u
.Generic
.Length
);
362 PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList
)
364 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor
;
365 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
366 ULONG Count
, i
, ListCount
;
368 /* Make sure there's something to dump */
369 if (!PartialList
) return;
371 /* Get the full list count */
372 ListCount
= PartialList
->Count
;
373 FullDescriptor
= PartialList
->List
;
374 DPRINT1(" CM_RESOURCE_LIST (PCI Bus Driver) (List Count = %d)\n", PartialList
->Count
);
377 for (i
= 0; i
< ListCount
; i
++)
379 /* Loop full descriptor */
380 DPRINT1(" InterfaceType %d\n", FullDescriptor
->InterfaceType
);
381 DPRINT1(" BusNumber 0x%x\n", FullDescriptor
->BusNumber
);
383 /* Get partial count and loop partials */
384 Count
= FullDescriptor
->PartialResourceList
.Count
;
385 for (PartialDescriptor
= FullDescriptor
->PartialResourceList
.PartialDescriptors
;
387 PartialDescriptor
= PciNextPartialDescriptor(PartialDescriptor
))
389 /* Print each partial */
390 PciDebugPrintPartialResource(PartialDescriptor
);
395 /* Done printing data */