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
PciDebugPnpIrpTypeToText(IN USHORT MinorFunction)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
PciDebugPoIrpTypeToText(IN USHORT MinorFunction)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
PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension,IN USHORT MaxMinor)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
PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData)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
PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps)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
PciDebugCmResourceTypeToText(IN UCHAR Type)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
PciDebugPrintIoResource(IN PIO_RESOURCE_DESCRIPTOR Descriptor)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
PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements)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
PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource)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
PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList)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