xref: /reactos/drivers/bus/pcix/debug.c (revision 9393fc32)
1 /*
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
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <pci.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* GLOBALS ********************************************************************/
17 
18 PCHAR PnpCodes[] =
19 {
20     "START_DEVICE",
21     "QUERY_REMOVE_DEVICE",
22     "REMOVE_DEVICE",
23     "CANCEL_REMOVE_DEVICE",
24     "STOP_DEVICE",
25     "QUERY_STOP_DEVICE",
26     "CANCEL_STOP_DEVICE",
27     "QUERY_DEVICE_RELATIONS",
28     "QUERY_INTERFACE",
29     "QUERY_CAPABILITIES",
30     "QUERY_RESOURCES",
31     "QUERY_RESOURCE_REQUIREMENTS",
32     "QUERY_DEVICE_TEXT",
33     "FILTER_RESOURCE_REQUIREMENTS",
34     "** UNKNOWN PNP IRP Minor Code **",
35     "READ_CONFIG",
36     "WRITE_CONFIG",
37     "EJECT",
38     "SET_LOCK",
39     "QUERY_ID",
40     "QUERY_PNP_DEVICE_STATE",
41     "QUERY_BUS_INFORMATION",
42     "DEVICE_USAGE_NOTIFICATION"
43 };
44 
45 PCHAR PoCodes[] =
46 {
47     "WAIT_WAKE",
48     "POWER_SEQUENCE",
49     "SET_POWER",
50     "QUERY_POWER",
51 };
52 
53 PCHAR SystemPowerStates[] =
54 {
55     "Unspecified",
56     "Working",
57     "Sleeping1",
58     "Sleeping2",
59     "Sleeping3",
60     "Hibernate",
61     "Shutdown"
62 };
63 
64 PCHAR DevicePowerStates[] =
65 {
66     "Unspecified",
67     "D0",
68     "D1",
69     "D2",
70     "D3"
71 };
72 
73 ULONG PciBreakOnPdoPowerIrp, PciBreakOnFdoPowerIrp;
74 ULONG PciBreakOnPdoPnpIrp, PciBreakOnFdoPnpIrp;
75 
76 /* FUNCTIONS ******************************************************************/
77 
78 PCHAR
79 NTAPI
80 PciDebugPnpIrpTypeToText(IN USHORT MinorFunction)
81 {
82     PCHAR Text;
83 
84     /* Catch invalid code */
85     if (MinorFunction >= IRP_MN_SURPRISE_REMOVAL)
86     {
87         /* New version of Windows? Or driver bug */
88         Text = "** UNKNOWN PNP IRP Minor Code **";
89     }
90     else
91     {
92         /* Get the right text for it */
93         Text = PnpCodes[MinorFunction];
94     }
95 
96     /* Return the symbolic name for the IRP */
97     return Text;
98 }
99 
100 PCHAR
101 NTAPI
102 PciDebugPoIrpTypeToText(IN USHORT MinorFunction)
103 {
104     PCHAR Text;
105 
106     /* Catch invalid code */
107     if (MinorFunction >= IRP_MN_QUERY_POWER)
108     {
109         /* New version of Windows? Or driver bug */
110         Text = "** UNKNOWN PO IRP Minor Code **";
111     }
112     else
113     {
114         /* Get the right text for it */
115         Text = PoCodes[MinorFunction];
116     }
117 
118     /* Return the symbolic name for the IRP */
119     return Text;
120 }
121 
122 BOOLEAN
123 NTAPI
124 PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation,
125                            IN PPCI_FDO_EXTENSION DeviceExtension,
126                            IN USHORT MaxMinor)
127 {
128     PPCI_PDO_EXTENSION PdoDeviceExtension;
129     ULONG BreakMask;
130     //ULONG DebugLevel = 0;
131     PCHAR IrpString;
132 
133     /* Only two functions are recognized */
134     switch (IoStackLocation->MajorFunction)
135     {
136         case IRP_MJ_POWER:
137 
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);
142             break;
143 
144         case IRP_MJ_PNP:
145 
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);
150             break;
151 
152         default:
153 
154             /* Other functions are not decoded */
155             BreakMask = FALSE;
156             IrpString = "";
157             break;
158     }
159 
160     /* Check if this is a PDO */
161     if (DeviceExtension->ExtensionType == PciPdoExtensionType)
162     {
163         /* Choose the correct debug level based on which function this is */
164         if (IoStackLocation->MajorFunction == IRP_MJ_POWER)
165         {
166             //DebugLevel = 0x500;
167         }
168         else if (IoStackLocation->MajorFunction == IRP_MJ_PNP)
169         {
170             //DebugLevel = 0x200;
171         }
172 
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,
179                 IrpString);
180     }
181     else if (DeviceExtension->ExtensionType == PciFdoExtensionType)
182     {
183         /* Choose the correct debug level based on which function this is */
184         if (IoStackLocation->MajorFunction == IRP_MJ_POWER)
185         {
186             //DebugLevel = 0x400;
187         }
188         else if (IoStackLocation->MajorFunction == IRP_MJ_PNP)
189         {
190             //DebugLevel = 0x100;
191         }
192 
193         /* For an FDO, just dump the extension pointer and IRP string */
194         DPRINT1("FDO(%p)<-%s\n", DeviceExtension, IrpString);
195     }
196 
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);
200 
201     /* Return whether or not the debugger should be broken into for this IRP */
202     return ((1 << IoStackLocation->MinorFunction) & BreakMask);
203 }
204 
205 VOID
206 NTAPI
207 PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData)
208 {
209     USHORT i;
210 
211     /* Loop the PCI header */
212     for (i = 0; i < PCI_COMMON_HDR_LENGTH; i += 4)
213     {
214         /* Dump each DWORD and its offset */
215         DPRINT1("  %02x - %08x\n", i, *(PULONG)((ULONG_PTR)PciData + i));
216     }
217 }
218 
219 VOID
220 NTAPI
221 PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps)
222 {
223     ULONG i;
224 
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",
237              DeviceCaps->Address,
238              DeviceCaps->UINumber,
239              DeviceCaps->D1Latency,
240              DeviceCaps->D2Latency,
241              DeviceCaps->D3Latency);
242 
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)]);
247 
248     /* Dump and convert the power state mappings */
249     for (i = PowerSystemWorking; i < PowerSystemMaximum; i++)
250         DbgPrint(" %s", DevicePowerStates[DeviceCaps->DeviceState[i]]);
251 
252     /* Finish the dump */
253     DbgPrint(" ]\n");
254 }
255 
256 PCHAR
257 NTAPI
258 PciDebugCmResourceTypeToText(IN UCHAR Type)
259 {
260     /* What kind of resource it this? */
261     switch (Type)
262     {
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 ***";
274     }
275 }
276 
277 VOID
278 NTAPI
279 PciDebugPrintIoResource(IN PIO_RESOURCE_DESCRIPTOR Descriptor)
280 {
281     ULONG i;
282     PULONG Data;
283 
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);
290 
291     /* Loop private data */
292     Data = (PULONG)&Descriptor->u.DevicePrivate;
293     for (i = 0; i < 6; i += 3)
294     {
295         /* Dump it in 32-bit triplets */
296         DPRINT1("        Data[%u] = %08x  %08x  %08x\n", i, Data[0], Data[1], Data[2]);
297     }
298 }
299 
300 VOID
301 NTAPI
302 PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements)
303 {
304     ULONG AlternativeLists;
305     PIO_RESOURCE_LIST List;
306     ULONG Count;
307     PIO_RESOURCE_DESCRIPTOR Descriptor;
308 
309     /* Make sure there's a list */
310     if (!Requirements) return;
311 
312     /* Grab the main list and the alternates as well */
313     AlternativeLists = Requirements->AlternativeLists;
314     List = Requirements->List;
315 
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);
326 
327     /* Scan alternative lists */
328     while (AlternativeLists--)
329     {
330         /* Get the descriptor array, and the count of descriptors */
331         Descriptor = List->Descriptors;
332         Count = List->Count;
333 
334         /* Print out each descriptor */
335         DPRINT1("\n     List[%u].Count = %u\n", AlternativeLists, Count);
336         while (Count--) PciDebugPrintIoResource(Descriptor++);
337 
338         /* Should've reached a new list now */
339         List = (PIO_RESOURCE_LIST)Descriptor;
340     }
341 
342     /* Terminate the dump */
343     DPRINT1("\n");
344 }
345 
346 VOID
347 NTAPI
348 PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource)
349 {
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",
356             0,
357             PartialResource->u.Generic.Start.LowPart,
358             PartialResource->u.Generic.Start.HighPart,
359             PartialResource->u.Generic.Length);
360 }
361 
362 VOID
363 NTAPI
364 PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList)
365 {
366     PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
367     PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
368     ULONG Count, i, ListCount;
369 
370     /* Make sure there's something to dump */
371     if (!PartialList) return;
372 
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);
377 
378     /* Loop full list */
379     for (i = 0; i < ListCount; i++)
380     {
381         /* Loop full descriptor */
382         DPRINT1("     InterfaceType        %d\n", FullDescriptor->InterfaceType);
383         DPRINT1("     BusNumber            0x%x\n", FullDescriptor->BusNumber);
384 
385         /* Get partial count and loop partials */
386         Count = FullDescriptor->PartialResourceList.Count;
387         for (PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
388              Count;
389              PartialDescriptor = CmiGetNextPartialDescriptor(PartialDescriptor))
390         {
391             /* Print each partial */
392             PciDebugPrintPartialResource(PartialDescriptor);
393             Count--;
394         }
395 
396         /* Go to the next full descriptor */
397         FullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)PartialDescriptor;
398     }
399 
400     /* Done printing data */
401     DPRINT1("\n");
402 }
403 
404 
405 /* EOF */
406