- IRP_MN_QUERY_RESOURCE_REQUIREMENTS half support now, PciQueryRequirements, PciAlloc...
[reactos.git] / reactos / 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, DebugLevel = 0;
129 PCHAR IrpString;
130
131 /* Only two functions are recognized */
132 switch (IoStackLocation->MajorFunction)
133 {
134 case IRP_MJ_POWER:
135
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);
140 break;
141
142 case IRP_MJ_PNP:
143
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);
148 break;
149
150 default:
151
152 /* Other functions are not decoded */
153 BreakMask = FALSE;
154 IrpString = "";
155 break;
156 }
157
158 /* Check if this is a PDO */
159 if (DeviceExtension->ExtensionType == PciPdoExtensionType)
160 {
161 /* Choose the correct debug level based on which function this is */
162 if (IoStackLocation->MajorFunction == IRP_MJ_POWER)
163 {
164 DebugLevel = 0x500;
165 }
166 else if (IoStackLocation->MajorFunction == IRP_MJ_PNP)
167 {
168 DebugLevel = 0x200;
169 }
170
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,
177 IrpString);
178 }
179 else if (DeviceExtension->ExtensionType == PciFdoExtensionType)
180 {
181 /* Choose the correct debug level based on which function this is */
182 if (IoStackLocation->MajorFunction == IRP_MJ_POWER)
183 {
184 DebugLevel = 0x400;
185 }
186 else if (IoStackLocation->MajorFunction == IRP_MJ_PNP)
187 {
188 DebugLevel = 0x100;
189 }
190
191 /* For an FDO, just dump the extension pointer and IRP string */
192 DPRINT1("FDO(%x)<-%s\n", DeviceExtension, IrpString);
193 }
194
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);
198
199 /* Return whether or not the debugger should be broken into for this IRP */
200 return ((1 << IoStackLocation->MinorFunction) & BreakMask);
201 }
202
203 VOID
204 NTAPI
205 PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData)
206 {
207 USHORT i;
208
209 /* Loop the PCI header */
210 for (i = 0; i < PCI_COMMON_HDR_LENGTH; i += 4)
211 {
212 /* Dump each DWORD and its offset */
213 DPRINT1(" %02x - %08x\n", i, *(PULONG)((ULONG_PTR)PciData + i));
214 }
215 }
216
217 VOID
218 NTAPI
219 PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps)
220 {
221 ULONG i;
222
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",
235 DeviceCaps->Address,
236 DeviceCaps->UINumber,
237 DeviceCaps->D1Latency,
238 DeviceCaps->D2Latency,
239 DeviceCaps->D3Latency);
240
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)]);
245
246 /* Dump and convert the power state mappings */
247 for (i = PowerSystemWorking; i < PowerSystemMaximum; i++)
248 DbgPrint(" %s", DevicePowerStates[DeviceCaps->DeviceState[i]]);
249
250 /* Finish the dump */
251 DbgPrint(" ]\n");
252 }
253
254 PCHAR
255 NTAPI
256 PciDebugCmResourceTypeToText(IN UCHAR Type)
257 {
258 /* What kind of resource it this? */
259 switch (Type)
260 {
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 ***";
272 }
273 }
274
275 VOID
276 NTAPI
277 PciDebugPrintIoResource(IN PIO_RESOURCE_DESCRIPTOR Descriptor)
278 {
279 ULONG i;
280 PULONG Data;
281
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);
288
289 /* Loop private data */
290 Data = (PULONG)&Descriptor->u.DevicePrivate;
291 for (i = 0; i < 6; i += 3)
292 {
293 /* Dump it in 32-bit triplets */
294 DPRINT1(" Data[%d] = %08x %08x %08x\n", i, Data[0], Data[1], Data[2]);
295 }
296 }
297
298 VOID
299 NTAPI
300 PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements)
301 {
302 ULONG AlternativeLists;
303 PIO_RESOURCE_LIST List;
304 ULONG Count;
305 PIO_RESOURCE_DESCRIPTOR Descriptor;
306
307 /* Make sure there's a list */
308 if (!Requirements) return;
309
310 /* Grab the main list and the alternates as well */
311 AlternativeLists = Requirements->AlternativeLists;
312 List = Requirements->List;
313
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);
324
325 /* Scan alternative lists */
326 while (AlternativeLists--)
327 {
328 /* Get the descriptor array, and the count of descriptors */
329 Descriptor = List->Descriptors;
330 Count = List->Count;
331
332 /* Print out each descriptor */
333 DPRINT1("\n List[%d].Count = %d\n", AlternativeLists, Count);
334 while (Count--) PciDebugPrintIoResource(Descriptor++);
335
336 /* Should've reached a new list now */
337 List = (PIO_RESOURCE_LIST)Descriptor;
338 }
339
340 /* Terminate the dump */
341 DPRINT1("\n");
342 }
343
344 /* EOF */