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