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
;
129 //ULONG DebugLevel = 0;
132 /* Only two functions are recognized */
133 switch (IoStackLocation
->MajorFunction
)
137 /* Get the string and the correct break mask for the extension */
138 BreakMask
= (DeviceExtension
->ExtensionType
== PciPdoExtensionType
) ?
139 PciBreakOnPdoPowerIrp
: PciBreakOnFdoPowerIrp
;
140 IrpString
= PciDebugPoIrpTypeToText(IoStackLocation
->MinorFunction
);
145 /* Get the string and the correct break mask for the extension */
146 BreakMask
= (DeviceExtension
->ExtensionType
== PciFdoExtensionType
) ?
147 PciBreakOnPdoPnpIrp
: PciBreakOnFdoPnpIrp
;
148 IrpString
= PciDebugPnpIrpTypeToText(IoStackLocation
->MinorFunction
);
153 /* Other functions are not decoded */
159 /* Check if this is a PDO */
160 if (DeviceExtension
->ExtensionType
== PciPdoExtensionType
)
162 /* Choose the correct debug level based on which function this is */
163 if (IoStackLocation
->MajorFunction
== IRP_MJ_POWER
)
165 //DebugLevel = 0x500;
167 else if (IoStackLocation
->MajorFunction
== IRP_MJ_PNP
)
169 //DebugLevel = 0x200;
172 /* For a PDO, print out the bus, device, and function number */
173 PdoDeviceExtension
= (PVOID
)DeviceExtension
;
174 DPRINT1("PDO(b=0x%x, d=0x%x, f=0x%x)<-%s\n",
175 PdoDeviceExtension
->ParentFdoExtension
->BaseBus
,
176 PdoDeviceExtension
->Slot
.u
.bits
.DeviceNumber
,
177 PdoDeviceExtension
->Slot
.u
.bits
.FunctionNumber
,
180 else if (DeviceExtension
->ExtensionType
== PciFdoExtensionType
)
182 /* Choose the correct debug level based on which function this is */
183 if (IoStackLocation
->MajorFunction
== IRP_MJ_POWER
)
187 else if (IoStackLocation
->MajorFunction
== IRP_MJ_PNP
)
192 /* For an FDO, just dump the extension pointer and IRP string */
193 DPRINT1("FDO(%x)<-%s\n", DeviceExtension
, IrpString
);
196 /* If the function is illegal for this extension, complain */
197 if (IoStackLocation
->MinorFunction
> MaxMinor
)
198 DPRINT1("Unknown IRP, minor = 0x%x\n", IoStackLocation
->MinorFunction
);
200 /* Return whether or not the debugger should be broken into for this IRP */
201 return ((1 << IoStackLocation
->MinorFunction
) & BreakMask
);
206 PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData
)
210 /* Loop the PCI header */
211 for (i
= 0; i
< PCI_COMMON_HDR_LENGTH
; i
+= 4)
213 /* Dump each DWORD and its offset */
214 DPRINT1(" %02x - %08x\n", i
, *(PULONG
)((ULONG_PTR
)PciData
+ i
));
220 PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps
)
224 /* Dump the capabilities */
225 DPRINT1("Capabilities\n Lock:%d, Eject:%d, Remove:%d, Dock:%d, UniqueId:%d\n",
226 DeviceCaps
->LockSupported
,
227 DeviceCaps
->EjectSupported
,
228 DeviceCaps
->Removable
,
229 DeviceCaps
->DockDevice
,
230 DeviceCaps
->UniqueID
);
231 DbgPrint(" SilentInstall:%d, RawOk:%d, SurpriseOk:%d\n",
232 DeviceCaps
->SilentInstall
,
233 DeviceCaps
->RawDeviceOK
,
234 DeviceCaps
->SurpriseRemovalOK
);
235 DbgPrint(" Address %08x, UINumber %08x, Latencies D1 %d, D2 %d, D3 %d\n",
237 DeviceCaps
->UINumber
,
238 DeviceCaps
->D1Latency
,
239 DeviceCaps
->D2Latency
,
240 DeviceCaps
->D3Latency
);
242 /* Dump and convert the wake levels */
243 DbgPrint(" System Wake: %s, Device Wake: %s\n DeviceState[PowerState] [",
244 SystemPowerStates
[min(DeviceCaps
->SystemWake
, PowerSystemMaximum
)],
245 DevicePowerStates
[min(DeviceCaps
->DeviceWake
, PowerDeviceMaximum
)]);
247 /* Dump and convert the power state mappings */
248 for (i
= PowerSystemWorking
; i
< PowerSystemMaximum
; i
++)
249 DbgPrint(" %s", DevicePowerStates
[DeviceCaps
->DeviceState
[i
]]);
251 /* Finish the dump */
257 PciDebugCmResourceTypeToText(IN UCHAR Type
)
259 /* What kind of resource it this? */
262 /* Pick the correct identifier string based on the type */
263 case CmResourceTypeDeviceSpecific
: return "CmResourceTypeDeviceSpecific";
264 case CmResourceTypePort
: return "CmResourceTypePort";
265 case CmResourceTypeInterrupt
: return "CmResourceTypeInterrupt";
266 case CmResourceTypeMemory
: return "CmResourceTypeMemory";
267 case CmResourceTypeDma
: return "CmResourceTypeDma";
268 case CmResourceTypeBusNumber
: return "CmResourceTypeBusNumber";
269 case CmResourceTypeConfigData
: return "CmResourceTypeConfigData";
270 case CmResourceTypeDevicePrivate
: return "CmResourceTypeDevicePrivate";
271 case CmResourceTypePcCardConfig
: return "CmResourceTypePcCardConfig";
272 default: return "*** INVALID RESOURCE TYPE ***";
278 PciDebugPrintIoResource(IN PIO_RESOURCE_DESCRIPTOR Descriptor
)
283 /* Print out the header */
284 DPRINT1(" IoResource Descriptor dump: Descriptor @0x%x\n", Descriptor
);
285 DPRINT1(" Option = 0x%x\n", Descriptor
->Option
);
286 DPRINT1(" Type = %d (%s)\n", Descriptor
->Type
, PciDebugCmResourceTypeToText(Descriptor
->Type
));
287 DPRINT1(" ShareDisposition = %d\n", Descriptor
->ShareDisposition
);
288 DPRINT1(" Flags = 0x%04X\n", Descriptor
->Flags
);
290 /* Loop private data */
291 Data
= (PULONG
)&Descriptor
->u
.DevicePrivate
;
292 for (i
= 0; i
< 6; i
+= 3)
294 /* Dump it in 32-bit triplets */
295 DPRINT1(" Data[%d] = %08x %08x %08x\n", i
, Data
[0], Data
[1], Data
[2]);
301 PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements
)
303 ULONG AlternativeLists
;
304 PIO_RESOURCE_LIST List
;
306 PIO_RESOURCE_DESCRIPTOR Descriptor
;
308 /* Make sure there's a list */
309 if (!Requirements
) return;
311 /* Grab the main list and the alternates as well */
312 AlternativeLists
= Requirements
->AlternativeLists
;
313 List
= Requirements
->List
;
315 /* Print out the initial header*/
316 DPRINT1(" IO_RESOURCE_REQUIREMENTS_LIST (PCI Bus Driver)\n");
317 DPRINT1(" InterfaceType %d\n", Requirements
->InterfaceType
);
318 DPRINT1(" BusNumber 0x%x\n", Requirements
->BusNumber
);
319 DPRINT1(" SlotNumber %d (0x%x), (d/f = 0x%x/0x%x)\n",
320 Requirements
->SlotNumber
,
321 Requirements
->SlotNumber
,
322 ((PCI_SLOT_NUMBER
*)&Requirements
->SlotNumber
)->u
.bits
.DeviceNumber
,
323 ((PCI_SLOT_NUMBER
*)&Requirements
->SlotNumber
)->u
.bits
.FunctionNumber
);
324 DPRINT1(" AlternativeLists %d\n", AlternativeLists
);
326 /* Scan alternative lists */
327 while (AlternativeLists
--)
329 /* Get the descriptor array, and the count of descriptors */
330 Descriptor
= List
->Descriptors
;
333 /* Print out each descriptor */
334 DPRINT1("\n List[%d].Count = %d\n", AlternativeLists
, Count
);
335 while (Count
--) PciDebugPrintIoResource(Descriptor
++);
337 /* Should've reached a new list now */
338 List
= (PIO_RESOURCE_LIST
)Descriptor
;
341 /* Terminate the dump */
347 PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource
)
349 /* Dump all the data in the partial */
350 DPRINT1(" Partial Resource Descriptor @0x%x\n", PartialResource
);
351 DPRINT1(" Type = %d (%s)\n", PartialResource
->Type
, PciDebugCmResourceTypeToText(PartialResource
->Type
));
352 DPRINT1(" ShareDisposition = %d\n", PartialResource
->ShareDisposition
);
353 DPRINT1(" Flags = 0x%04X\n", PartialResource
->Flags
);
354 DPRINT1(" Data[%d] = %08x %08x %08x\n",
356 PartialResource
->u
.Generic
.Start
.LowPart
,
357 PartialResource
->u
.Generic
.Start
.HighPart
,
358 PartialResource
->u
.Generic
.Length
);
363 PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList
)
365 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor
;
366 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
367 ULONG Count
, i
, ListCount
;
369 /* Make sure there's something to dump */
370 if (!PartialList
) return;
372 /* Get the full list count */
373 ListCount
= PartialList
->Count
;
374 FullDescriptor
= PartialList
->List
;
375 DPRINT1(" CM_RESOURCE_LIST (PCI Bus Driver) (List Count = %d)\n", PartialList
->Count
);
378 for (i
= 0; i
< ListCount
; i
++)
380 /* Loop full descriptor */
381 DPRINT1(" InterfaceType %d\n", FullDescriptor
->InterfaceType
);
382 DPRINT1(" BusNumber 0x%x\n", FullDescriptor
->BusNumber
);
384 /* Get partial count and loop partials */
385 Count
= FullDescriptor
->PartialResourceList
.Count
;
386 for (PartialDescriptor
= FullDescriptor
->PartialResourceList
.PartialDescriptors
;
388 PartialDescriptor
= PciNextPartialDescriptor(PartialDescriptor
))
390 /* Print each partial */
391 PciDebugPrintPartialResource(PartialDescriptor
);
396 /* Done printing data */