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