/*++ Copyright (C) Microsoft Corporation, 1992 - 1999 Module Name: minipkd.c Abstract: SCSI miniport debugger dxtension api Author: John Strange (johnstra) 7-Apr-2000 (Adapted from PeterWie's scsikd) Environment: User Mode Revision History: --*/ #include "pch.h" #include "port.h" FLAG_NAME LuFlags[] = { FLAG_NAME(LU_QUEUE_FROZEN), // 0001 FLAG_NAME(LU_LOGICAL_UNIT_IS_ACTIVE), // 0002 FLAG_NAME(LU_NEED_REQUEST_SENSE), // 0004 FLAG_NAME(LU_LOGICAL_UNIT_IS_BUSY), // 0008 FLAG_NAME(LU_QUEUE_IS_FULL), // 0010 FLAG_NAME(LU_PENDING_LU_REQUEST), // 0020 FLAG_NAME(LU_QUEUE_LOCKED), // 0040 FLAG_NAME(LU_QUEUE_PAUSED), // 0080 {0,0} }; FLAG_NAME AdapterFlags[] = { FLAG_NAME(PD_DEVICE_IS_BUSY), // 0X00001 FLAG_NAME(PD_NOTIFICATION_REQUIRED), // 0X00004 FLAG_NAME(PD_READY_FOR_NEXT_REQUEST), // 0X00008 FLAG_NAME(PD_FLUSH_ADAPTER_BUFFERS), // 0X00010 FLAG_NAME(PD_MAP_TRANSFER), // 0X00020 FLAG_NAME(PD_LOG_ERROR), // 0X00040 FLAG_NAME(PD_RESET_HOLD), // 0X00080 FLAG_NAME(PD_HELD_REQUEST), // 0X00100 FLAG_NAME(PD_RESET_REPORTED), // 0X00200 FLAG_NAME(PD_PENDING_DEVICE_REQUEST), // 0X00800 FLAG_NAME(PD_DISCONNECT_RUNNING), // 0X01000 FLAG_NAME(PD_DISABLE_CALL_REQUEST), // 0X02000 FLAG_NAME(PD_DISABLE_INTERRUPTS), // 0X04000 FLAG_NAME(PD_ENABLE_CALL_REQUEST), // 0X08000 FLAG_NAME(PD_TIMER_CALL_REQUEST), // 0X10000 FLAG_NAME(PD_WMI_REQUEST), // 0X20000 {0,0} }; char *MiniInterruptMode[] = { "LevelSensitive", "Latched" }; char *MiniInterfaceTypes[] = { "Internal", "Isa", "Eisa", "MicroChannel", "TurboChannel", "PCIBus", "VMEBus", "NuBus", "PCMCIABus", "CBus", "MPIBus", "MPSABus", "ProcessorInternal", "InternalPowerBus", "PNPISABus", "PNPBus" }; char *MiniDmaWidths[] = { "Width8Bits", "Width16Bits", "Width32Bits" }; char *MiniDmaSpeed[] = { "Compatible", "TypeA", "TypeB", "TypeC", "TypeF" }; #define MINIKD_MAX_SCSI_FUNCTION 26 char *MiniScsiFunction[] = { "SRB_FUNCTION_EXECUTE_SCSI", // 0x00 "SRB_FUNCTION_CLAIM_DEVICE", // 0x01 "SRB_FUNCTION_IO_CONTROL", // 0x02 "SRB_FUNCTION_RECEIVE_EVENT", // 0x03 "SRB_FUNCTION_RELEASE_QUEUE", // 0x04 "SRB_FUNCTION_ATTACH_DEVICE", // 0x05 "SRB_FUNCTION_RELEASE_DEVICE", // 0x06 "SRB_FUNCTION_SHUTDOWN", // 0x07 "SRB_FUNCTION_FLUSH", // 0x08 "***", // 0x09 "***", // 0x0a "***", // 0x0b "***", // 0x0c "***", // 0x0d "***", // 0x0e "***", // 0x0f "SRB_FUNCTION_ABORT_COMMAND", // 0x10 "SRB_FUNCTION_RELEASE_RECOVERY", // 0x11 "SRB_FUNCTION_RESET_BUS", // 0x12 "SRB_FUNCTION_RESET_DEVICE", // 0x13 "SRB_FUNCTION_TERMINATE_IO", // 0x14 "SRB_FUNCTION_FLUSH_QUEUE", // 0x15 "SRB_FUNCTION_REMOVE_DEVICE", // 0x16 "SRB_FUNCTION_WMI", // 0x17 "SRB_FUNCTION_LOCK_QUEUE", // 0x18 "SRB_FUNCTION_UNLOCK_QUEUE" // 0x19 }; #define MINIKD_MAX_SRB_STATUS 49 char *MiniScsiSrbStatus[] = { "SRB_STATUS_PENDING", // 0x00 "SRB_STATUS_SUCCESS", // 0x01 "SRB_STATUS_ABORTED", // 0x02 "SRB_STATUS_ABORT_FAILED", // 0x03 "SRB_STATUS_ERROR", // 0x04 "SRB_STATUS_BUSY", // 0x05 "SRB_STATUS_INVALID_REQUEST", // 0x06 "SRB_STATUS_INVALID_PATH_ID", // 0x07 "SRB_STATUS_NO_DEVICE", // 0x08 "SRB_STATUS_TIMEOUT", // 0x09 "SRB_STATUS_SELECTION_TIMEOUT", // 0x0a "SRB_STATUS_COMMAND_TIMEOUT", // 0x0b "***", // 0x0c "SRB_STATUS_MESSAGE_REJECTED", // 0x0d "SRB_STATUS_BUS_RESET", // 0x0e "SRB_STATUS_STATUS_PARITY_ERROR", // 0x0f "SRB_STATUS_REQUEST_SENSE_FAILED", // 0x10 "SRB_STATUS_NO_HBA", // 0x11 "SRB_STATUS_DATA_OVERRUN", // 0x12 "SRB_STATUS_UNEXPECTED_BUS_FREE", // 0x13 "SRB_STATUS_PHASE_SEQUENCE_FAILURE", // 0x14 "SRB_STATUS_BAD_SRB_BLOCK_LENGTH", // 0x15 "SRB_STATUS_REQUEST_FLUSHED", // 0x16 "***", // 0x17 "***", // 0x18 "***", // 0x19 "***", // 0x1a "***", // 0x1b "***", // 0x1c "***", // 0x1d "***", // 0x1e "***", // 0x1f "SRB_STATUS_INVALID_LUN", // 0x20 "SRB_STATUS_INVALID_TARGET_ID", // 0x21 "SRB_STATUS_BAD_FUNCTION", // 0x22 "SRB_STATUS_ERROR_RECOVERY", // 0x23 "SRB_STATUS_NOT_POWERED", // 0x24 "***", // 0x25 "***", // 0x26 "***", // 0x27 "***", // 0x28 "***", // 0x29 "***", // 0x2a "***", // 0x2b "***", // 0x2c "***", // 0x2d "***", // 0x2e "***", // 0x2f "SRB_STATUS_INTERNAL_ERROR" // 0x30 }; #define DumpUcharField(name, value, depth) \ xdprintfEx((depth), ("%s: 0x%02X\n", (name), (value))) #define DumpUshortField(name, value, depth) \ xdprintfEx((depth), ("%s: 0x%04X\n", (name), (value))) #define DumpUlongField(name, value, depth) \ xdprintfEx((depth), ("%s: 0x%08X\n", (name), (value))) #define DumpPointerField(name, value, depth) \ xdprintfEx((depth), ("%s: %08p\n", (name), (value))) #define DumpBooleanField(name, value, depth) \ xdprintfEx((depth), ("%s: %s\n", (name), (value) ? "YES" : "NO")) typedef struct _CommonExtensionFlags { // // True if this device object is a physical device object // BOOLEAN IsPdo : 1; // // True if this device object has processed it's first start and // has been initialized. // BOOLEAN IsInitialized : 1; // // Has WMI been initialized for this device object? // BOOLEAN WmiInitialized : 1; // // Has the miniport associated with this FDO or PDO indicated WMI // support? // BOOLEAN WmiMiniPortSupport : 1; } CommonExtensionFlags, *PCommonExtensionFlags; VOID MpDumpPdo( IN ULONG64 Address, IN OPTIONAL PADAPTER_EXTENSION Adapter, IN ULONG Detail, IN ULONG Depth ); VOID MpDumpFdoExtension( ULONG64 Address, ULONG64 DeviceObject, ULONG Detail, ULONG Depth ); VOID MpDumpExtension( IN ULONG64 Address, IN ULONG64 DeviceExtension, IN ULONG Detail, IN ULONG Depth ); VOID MpDumpPortConfigurationInformation( IN ULONG64 PortConfigInfo, IN ULONG Depth ); VOID MpDumpSrb( IN ULONG64 Srb, IN ULONG Depth ); VOID MpDumpAdapters( IN PDEVICE_OBJECT *Adapters, IN ULONG Depth ); VOID MpDumpSrbData( PSRB_DATA SrbData, ULONG Depth ); VOID MpDumpScatterGatherList( PSRB_SCATTER_GATHER List, ULONG Entries, ULONG Depth ); VOID MpDumpActiveRequests( IN ULONG64 ListHead, IN ULONG TickCount, IN ULONG Depth ); VOID MpDumpInterruptData( IN PINTERRUPT_DATA Data, IN PINTERRUPT_DATA RealData, IN ULONG Detail, IN ULONG Depth ); VOID MpDumpChildren( IN ULONG64 Adapter, IN ULONG Depth ); PUCHAR MpSecondsToString( ULONG Count ); VOID MpDumpRequests( IN ULONG64 DeviceObject, IN ULONG TickCount, IN ULONG Depth ); VOID MpDumpHwExports( IN ULONG64 Address ); DECLARE_API (exports) /*++ Routine Description: Dumps the specified miniport's service routine pointers Arguments: Return Value: none --*/ { ULONG64 address; // // Get the address of the struct. // GetExpressionEx(args, &address, &args); // // Dump the PORT_CONFIGURATION_INFORMATION // MpDumpHwExports(address); return S_OK; } DECLARE_API (adapters) /*++ Routine Description: Dumps adapter information. Arguments: Return Value: none --*/ { ULONG64 address; ULONG result; CHAR NameBuffer[512]; ULONG status; ULONG CurrentAdapter = 0; ULONG Adapters; ULONG64 DriverObjectAddr; ULONG64 DriverNameLength; ULONG64 DriverNameBuffer; ULONG64 DeviceExtension; ULONG64 AdapterAddr; ULONG RemoveStatus; ULONG Type; BOOLEAN ValidAdapter; ULONG64 *AdapterArr; ULONG i; // // Get the address of scsiport's global adapter list element count. // and read the count from the debuggee. If we can't get the address // or if we can't read the count, we give up. // address = GetExpression("scsiport!ScsiGlobalAdapterListElements"); if (address != 0) { Adapters = 0; status = ReadMemory(address, (PVOID) &Adapters, sizeof(ULONG), &result); if (!status) { MINIPKD_PRINT_ERROR(0); return E_FAIL; } else if (Adapters == 0) { dprintf("There are no configured SCSI adapters.\n"); return S_OK; } } else { MINIPKD_PRINT_ERROR(0); return E_FAIL; } // // Get the address of scsiport's global adapter list and read // the address from the debuggee. If we can't get the address // or read it, we can't continue. // address = GetExpression("scsiport!ScsiGlobalAdapterList"); if (address) { status = ReadMemory(address, (PVOID) &address, sizeof(ULONG64), &result); if (!status) { MINIPKD_PRINT_ERROR(status); return E_FAIL; } else if (address == (ULONG64)-1 || address == (ULONG64)0) { dprintf("There are no configured SCSI adapters.\n"); return S_OK; } } else { MINIPKD_PRINT_ERROR(0); return E_FAIL; } // // Allocate memory to hold an array of addresses. We use the array to // check for duplicate device objects. // AdapterArr = _alloca(sizeof(ULONG64) * Adapters); // // Display adapter information. // while (CurrentAdapter < Adapters) { ValidAdapter = TRUE; // // Read the address of the device object (fdo) and update address // to point to the next one. The amount by which we bump the address // depends on the size of a pointer on the debuggee. // ReadPtr(address, &AdapterAddr); address += (IsPtr64()) ? sizeof(ULONG64) : sizeof(ULONG); // // Save the address of the adapter. // AdapterArr[CurrentAdapter] = AdapterAddr; // // If this address is a duplicate, we don't need to display info on it // again. // if (CurrentAdapter > 0) { for (i=0; iIsPdo) { MINIPKD_PRINT_ERROR(0); return E_FAIL; } MpDumpExtension(Address, DeviceExtension, 0, 0); return S_OK; } DECLARE_API (lun) /*++ Routine Description: Dumps LUN extension information at the specified address. Arguments: args - string containing the address of the device object or device extension Return Value: none --*/ { ULONG64 Address; ULONG64 Type; ULONG64 DeviceExtension; ULONG detail = 0; UCHAR Block; PCommonExtensionFlags Flags = (PCommonExtensionFlags) &Block; // // Convert the argument string to an address. // GetExpressionEx(args, &Address, &args); // // Read the Type and DeviceExtension fields from the supplied address. // InitTypeRead(Address, nt!_DEVICE_OBJECT); Type = ReadField(Type); DeviceExtension = ReadField(DeviceExtension); if (!DeviceExtension) { MINIPKD_PRINT_ERROR(0); return E_FAIL; } // // If the supplied address points to a device, fixup the address to // that of the device's extension. // if (Type == IO_TYPE_DEVICE) { Address = DeviceExtension; } // // Make sure an LOGICAL_UNIT_EXTENSION object lives at the address we have. // InitTypeRead(Address, scsiport!COMMON_EXTENSION); Block = (UCHAR)ReadField(IsPdo); if (!Flags->IsPdo) { MINIPKD_PRINT_ERROR(0); return E_FAIL; } MpDumpExtension(Address, DeviceExtension, 0, 0); return S_OK; } VOID MpDumpExtension( IN ULONG64 Address, IN ULONG64 DeviceExtension, IN ULONG Detail, IN ULONG Depth ) { ULONG tmp; ULONG IsRemoved = 0; ULONG SrbFlags = 0; ULONG WmiScsiPortRegInfoBufSize = 0; ULONG PagingPathCount = 0; ULONG HibernatePathCount = 0; ULONG DumpPathCount = 0; ULONG64 WmiScsiPortRegInfoBuf = 0; ULONG64 DeviceObject = 0; ULONG64 LowerDeviceObject = 0; ULONG64 IdleTimer = 0; ULONG64 MajorFunction = 0; DEVICE_POWER_STATE CurrentDeviceState = 0; DEVICE_POWER_STATE DesiredDeviceState = 0; SYSTEM_POWER_STATE CurrentSystemState = 0; #if 0 BOOLEAN IsPdo = 0; BOOLEAN IsInitialized = 0; BOOLEAN WmiInitialized = 0; BOOLEAN WmiMiniPortSupport = 0; UCHAR CurrentPnpState = 0; UCHAR PreviousPnpState = 0; #else ULONG IsPdo = 0; ULONG IsInitialized = 0; ULONG WmiInitialized = 0; ULONG WmiMiniPortSupport = 0; ULONG CurrentPnpState = 0; ULONG PreviousPnpState = 0; #endif FIELD_INFO deviceFields[] = { {"IsPdo", NULL, 0, COPY, 0, (PVOID) &IsPdo }, {"IsInitialized", NULL, 0, COPY, 0, (PVOID) &IsInitialized }, {"WmiInitialized", NULL, 0, COPY, 0, (PVOID) &WmiInitialized }, {"WmiMiniPortSupport", NULL, 0, COPY, 0, (PVOID) &WmiMiniPortSupport }, {"IsRemoved", NULL, 0, COPY, 0, (PVOID) &IsRemoved }, {"DeviceObject", NULL, 0, COPY, 0, (PVOID) &DeviceObject }, {"LowerDeviceObject", NULL, 0, COPY, 0, (PVOID) &LowerDeviceObject }, {"SrbFlags", NULL, 0, COPY, 0, (PVOID) &SrbFlags }, {"CurrentDeviceState", NULL, 0, COPY, 0, (PVOID) &CurrentDeviceState }, {"CurrentSystemState", NULL, 0, COPY, 0, (PVOID) &CurrentSystemState }, {"DesiredDeviceState", NULL, 0, COPY, 0, (PVOID) &DesiredDeviceState }, {"IdleTimer", NULL, 0, COPY, 0, (PVOID) &IdleTimer }, {"CurrentPnpState", NULL, 0, COPY, 0, (PVOID) &CurrentPnpState }, {"PreviousPnpState", NULL, 0, COPY, 0, (PVOID) &PreviousPnpState }, {"MajorFunction", NULL, 0, COPY, 0, (PVOID) &MajorFunction }, {"PagingPathCount", NULL, 0, COPY, 0, (PVOID) &PagingPathCount }, {"HibernatePathCount", NULL, 0, COPY, 0, (PVOID) &HibernatePathCount }, {"DumpPathCount", NULL, 0, COPY, 0, (PVOID) &DumpPathCount }, {"WmiScsiPortRegInfoBuf", NULL, 0, COPY, 0, (PVOID) &WmiScsiPortRegInfoBuf }, {"WmiScsiPortRegInfoBufSize", NULL, 0, COPY, 0, (PVOID) &WmiScsiPortRegInfoBufSize }, }; SYM_DUMP_PARAM DevSym = { sizeof (SYM_DUMP_PARAM), "scsiport!COMMON_EXTENSION", DBG_DUMP_NO_PRINT, Address, NULL, NULL, NULL, sizeof (deviceFields) / sizeof (FIELD_INFO), &deviceFields[0] }; if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) { dprintf("%08p: Could not read device object\n", Address); return; } dprintf("Miniport %s device extension at address %08p\n", (IsPdo ? "physical" : "functional"), Address); xdprintfEx(Depth, ("Common Extension:\n")); Depth += 1; tmp = Depth; if(IsInitialized) { xdprintfEx(tmp, ("Initialized " )); tmp = 0; } if(IsRemoved) { xdprintfEx(tmp, ("Removed " )); tmp = 0; } switch(IsRemoved) { case REMOVE_PENDING: { xdprintfEx(tmp, ("RemovePending")); tmp = 0; break; } case REMOVE_COMPLETE: { xdprintfEx(tmp, ("RemoveComplete")); tmp = 0; break; } } if(WmiMiniPortSupport) { if(WmiInitialized) { xdprintfEx(tmp, ("WmiInit")); } else { xdprintfEx(tmp, ("Wmi")); } tmp = 0; } if(tmp == 0) { dprintf("\n"); } tmp = 0; xdprintfEx(Depth, ("DO ")); dprintf("%08p LowerObject %08p SRB Flags %#08lx\n", DeviceObject, LowerDeviceObject, SrbFlags ); xdprintfEx(Depth, ("Current Power ")); dprintf("(D%d,S%d) Desired Power D%d Idle %#08lx\n", CurrentDeviceState - 1, CurrentSystemState - 1, DesiredDeviceState - 1, IdleTimer); xdprintfEx(Depth, ("Current Pnp state ")); dprintf("%x Previous state 0x%x\n", CurrentPnpState, PreviousPnpState); xdprintfEx(Depth, ("DispatchTable ")); dprintf("%08p UsePathCounts (P%d, H%d, C%d)\n", MajorFunction, PagingPathCount, HibernatePathCount, DumpPathCount); if(WmiMiniPortSupport) { xdprintfEx(Depth, ("WmiInfo ")); dprintf("%08p WmiInfoSize %#08lx\n", WmiScsiPortRegInfoBuf, WmiScsiPortRegInfoBufSize); } if(IsPdo) { xdprintfEx(Depth - 1, ("Logical Unit Extension:\n")); MpDumpPdo(Address, NULL, Detail, Depth); } else { xdprintfEx(Depth - 1, ("Adapter Extension:\n")); MpDumpFdoExtension(Address, DeviceExtension, Detail, Depth); } return; } VOID MpDumpHwExports( ULONG64 Address ) { ULONG result; ULONG64 HwFindAdapter; ULONG64 HwInitialize; ULONG64 HwStartIo; ULONG64 HwInterrupt; ULONG64 HwResetBus; ULONG64 HwDmaStarted; ULONG64 HwRequestInterrupt; ULONG64 HwTimerRequest; ULONG64 HwAdapterControl; FIELD_INFO deviceFields[] = { {"HwFindAdapter", NULL, 0, COPY, 0, (PVOID) &HwFindAdapter }, {"HwInitialize", NULL, 0, COPY, 0, (PVOID) &HwInitialize }, {"HwStartIo", NULL, 0, COPY, 0, (PVOID) &HwStartIo }, {"HwInterrupt", NULL, 0, COPY, 0, (PVOID) &HwInterrupt }, {"HwResetBus", NULL, 0, COPY, 0, (PVOID) &HwResetBus }, {"HwDmaStarted", NULL, 0, COPY, 0, (PVOID) &HwDmaStarted }, {"HwRequestInterrupt", NULL, 0, COPY, 0, (PVOID) &HwRequestInterrupt }, {"HwTimerRequest", NULL, 0, COPY, 0, (PVOID) &HwTimerRequest }, {"HwAdapterControl", NULL, 0, COPY, 0, (PVOID) &HwAdapterControl }, }; SYM_DUMP_PARAM DevSym = { sizeof (SYM_DUMP_PARAM), "scsiport!_ADAPTER_EXTENSION", DBG_DUMP_NO_PRINT, Address, NULL, NULL, NULL, sizeof (deviceFields) / sizeof (FIELD_INFO), &deviceFields[0] }; if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) { dprintf("%08p: Could not read device object\n", Address); return; } dprintf("HwFindAdapter : %08p\n", HwFindAdapter); dprintf("HwInitialize : %08p\n", HwInitialize); dprintf("HwStartIo : %08p\n", HwStartIo); dprintf("HwInterrupt : %08p\n", HwInterrupt); dprintf("HwResetBus : %08p\n", HwResetBus); dprintf("HwDmaStarted : %08p\n", HwDmaStarted); dprintf("HwRequestInterrupt: %08p\n", HwRequestInterrupt); dprintf("HwTimerRequest : %08p\n", HwTimerRequest); dprintf("HwAdapterControl : %08p\n", HwAdapterControl); return; } VOID MpDumpFdoExtension( ULONG64 Address, ULONG64 DeviceExtension, ULONG Detail, ULONG Depth ) { PADAPTER_EXTENSION realAdapter = (PADAPTER_EXTENSION) Address; ULONG tmp = Depth; WCHAR name[256]; ULONG Result; ULONG64 DeviceName = 0; ULONG64 InterfaceName = 0; ULONG64 InterfaceNameLen = 0; ULONG64 HwDeviceExtension = 0; ULONG64 SrbExtensionBuffer = 0; ULONG64 NonCachedExtension = 0; ULONG64 PortNumber = 0; ULONG64 AdapterNumber = 0; ULONG64 ActiveRequestCount = 0; ULONG64 IsMiniportDetected = 0; ULONG64 IsInVirtualSlot = 0; ULONG64 IsPnp = 0; ULONG64 HasInterrupt = 0; ULONG64 DisablePower = 0; ULONG64 DisableStop = 0; ULONG VirtualSlotNumber = 0; ULONG RealBusNumber = 0; ULONG RealSlotNumber = 0; ULONG64 NumberOfBuses = 0; ULONG64 MaximumTargetIds = 0; ULONG64 MaxLuCount = 0; ULONG64 DisableCount = 0; ULONG64 SynchronizeExecution = 0; ULONG64 MapRegisterBase = 0; ULONG64 DmaAdapterObject = 0; ULONG64 PortConfig = 0; ULONG64 AllocatedResources = 0; ULONG64 TranslatedResources = 0; ULONG64 InterruptLevel = 0; ULONG64 IoAddress = 0; ULONG64 MapBuffers = 0; ULONG64 RemapBuffers = 0; ULONG64 MasterWithAdapter = 0; ULONG64 TaggedQueuing= 0; ULONG64 AutoRequestSense = 0; ULONG64 MultipleRequestPerLu = 0; ULONG64 ReceiveEvent = 0; ULONG64 CachesData = 0; ULONG64 Dma64BitAddresses = 0; ULONG64 Dma32BitAddresses = 0; ULONG64 DeviceState = 0; ULONG64 TickCount = 0; ULONG64 AdapterExtension = 0; FIELD_INFO deviceFields[] = { {"DeviceName", NULL, 0, COPY, 0, (PVOID) &DeviceName }, {"InterfaceName.Buffer", NULL, 0, COPY, 0, (PVOID) &InterfaceName }, {"InterfaceName.Length", NULL, 0, COPY, 0, (PVOID) &InterfaceNameLen }, {"HwDeviceExtension", NULL, 0, COPY, 0, (PVOID) &HwDeviceExtension }, {"SrbExtensionBuffer", NULL, 0, COPY, 0, (PVOID) &SrbExtensionBuffer }, {"NonCachedExtension", NULL, 0, COPY, 0, (PVOID) &NonCachedExtension }, {"PortNumber", NULL, 0, COPY, 0, (PVOID) &PortNumber }, {"AdapterNumber", NULL, 0, COPY, 0, (PVOID) &AdapterNumber }, {"ActiveRequestCount", NULL, 0, COPY, 0, (PVOID) &ActiveRequestCount }, {"SynchronizeExecution", NULL, 0, COPY, 0, (PVOID) &SynchronizeExecution }, {"DeviceState", NULL, 0, COPY, 0, (PVOID) &DeviceState }, {"TickCount", NULL, 0, COPY, 0, (PVOID) &TickCount }, {"IsMiniportDetected", NULL, 0, COPY, 0, (PVOID) &IsMiniportDetected }, {"IsInVirtualSlot", NULL, 0, COPY, 0, (PVOID) &IsInVirtualSlot }, {"IsPnp", NULL, 0, COPY, 0, (PVOID) &IsPnp }, {"HasInterrupt", NULL, 0, COPY, 0, (PVOID) &HasInterrupt }, {"DisablePower", NULL, 0, COPY, 0, (PVOID) &DisablePower }, {"DisableStop", NULL, 0, COPY, 0, (PVOID) &DisableStop }, {"RealBusNumber", NULL, 0, COPY, 0, (PVOID) &RealBusNumber }, {"RealSlotNumber", NULL, 0, COPY, 0, (PVOID) &RealSlotNumber }, {"VirtualSlotNumber.u.AsULONG", NULL, 0, COPY, 0, (PVOID) &VirtualSlotNumber }, {"NumberOfBuses", NULL, 0, COPY, 0, (PVOID) &NumberOfBuses }, {"MaximumTargetIds", NULL, 0, COPY, 0, (PVOID) &MaximumTargetIds }, {"MaxLuCount", NULL, 0, COPY, 0, (PVOID) &MaxLuCount }, {"DisableCount", NULL, 0, COPY, 0, (PVOID) &DisableCount }, {"MapRegisterBase", NULL, 0, COPY, 0, (PVOID) &MapRegisterBase }, {"DmaAdapterObject", NULL, 0, COPY, 0, (PVOID) &DmaAdapterObject }, {"PortConfig", NULL, 0, COPY, 0, (PVOID) &PortConfig }, {"AllocatedResources", NULL, 0, COPY, 0, (PVOID) &AllocatedResources }, {"TranslatedResources", NULL, 0, COPY, 0, (PVOID) &TranslatedResources }, {"InterruptLevel", NULL, 0, COPY, 0, (PVOID) &InterruptLevel }, {"IoAddress", NULL, 0, COPY, 0, (PVOID) &IoAddress }, {"MapBuffers", NULL, 0, COPY, 0, (PVOID) &MapBuffers }, {"RemapBuffers", NULL, 0, COPY, 0, (PVOID) &RemapBuffers }, {"MasterWithAdapter", NULL, 0, COPY, 0, (PVOID) &MasterWithAdapter }, {"TaggedQueuing", NULL, 0, COPY, 0, (PVOID) &TaggedQueuing }, {"AutoRequestSense", NULL, 0, COPY, 0, (PVOID) &AutoRequestSense }, {"MultipleRequestPerLu", NULL, 0, COPY, 0, (PVOID) &MultipleRequestPerLu }, {"ReceiveEvent", NULL, 0, COPY, 0, (PVOID) &ReceiveEvent }, {"CachesData", NULL, 0, COPY, 0, (PVOID) &CachesData }, {"Dma64BitAddresses", NULL, 0, COPY, 0, (PVOID) &Dma64BitAddresses }, {"Dma32BitAddresses", NULL, 0, COPY, 0, (PVOID) &Dma32BitAddresses }, }; SYM_DUMP_PARAM DevSym = { sizeof (SYM_DUMP_PARAM), "scsiport!ADAPTER_EXTENSION", DBG_DUMP_NO_PRINT, Address, NULL, NULL, NULL, sizeof (deviceFields) / sizeof (FIELD_INFO), &deviceFields[0] }; if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) { dprintf("%08p: Could not read device object\n", Address); return; } if(!ReadMemory(DeviceName, (PVOID) name, sizeof(WCHAR) * 256, &Result)) { dprintf("Error reading DeviceName at address %p\n", DeviceName); return; } xdprintfEx(Depth, ("Device: %S\n", name)); if (!ReadMemory(InterfaceName, (PVOID) name, sizeof(WCHAR) * (ULONG)InterfaceNameLen, &Result)) { dprintf("Error reading interface name at address %p\n", InterfaceName); return; } xdprintfEx(Depth, ("Interface: %S\n", name)); DumpPointerField("Hw Device Extension", HwDeviceExtension, Depth); DumpPointerField("SRB Extension", SrbExtensionBuffer, Depth); DumpPointerField("Non-cached Extension", NonCachedExtension, Depth); DumpUlongField("Port", PortNumber, Depth); DumpUlongField("Adapter", AdapterNumber, Depth); DumpUlongField("Active Requests", ActiveRequestCount+1, Depth); DumpPointerField("Sync Routine", SynchronizeExecution, Depth); DumpUlongField("PNP State", DeviceState, Depth); DumpUlongField("Tick Count", TickCount, Depth); xdprintfEx(Depth, ("Adapter Info:\n")); Depth++; if (IsMiniportDetected) xdprintfEx(Depth, ("Miniport detected\n")); if (IsInVirtualSlot) xdprintfEx(Depth, ("In virtual slot\n")); if (IsPnp) xdprintfEx(Depth, ("PNP adapter\n")); if (HasInterrupt) xdprintfEx(Depth, ("Has interrupt connected\n")); if (DisablePower) xdprintfEx(Depth, ("Can be powered off\n")); if (DisableStop) xdprintfEx(Depth, ("Can be stopped\n")); Depth--; xdprintfEx(Depth, ("Real Bus/Slot: 0x%08X/0x%08X\n", RealBusNumber, RealSlotNumber)); DumpUlongField("Virtual PCI Slot", VirtualSlotNumber, Depth); DumpUcharField("Buses", NumberOfBuses, Depth); DumpUcharField("Max Target IDs", MaximumTargetIds, Depth); DumpUcharField("Max LUs", MaxLuCount, Depth); DumpUlongField("Disables", DisableCount, Depth); DumpPointerField("Map Register Base", MapRegisterBase, Depth); DumpPointerField("DMA Adapter", DmaAdapterObject, Depth); DumpPointerField("Port Config Info", PortConfig, Depth); DumpPointerField("Allocated Resources", AllocatedResources, Depth); DumpPointerField("Translated Resources", TranslatedResources, Depth); DumpUlongField("Interrupt Lvl", InterruptLevel, Depth); DumpPointerField("IO Address", IoAddress, Depth); DumpBooleanField("Must map buffers", MapBuffers, Depth); DumpBooleanField("Must remap buffers", RemapBuffers, Depth); DumpBooleanField("Bus Master", MasterWithAdapter, Depth); DumpBooleanField("Supports Tagged Queuing", TaggedQueuing, Depth); DumpBooleanField("Supports auto request sense", AutoRequestSense, Depth); DumpBooleanField("Supports multiple requests per LU", MultipleRequestPerLu, Depth); DumpBooleanField("Supports receive event", ReceiveEvent, Depth); DumpBooleanField("Caches data", CachesData, Depth); DumpBooleanField("Handles 64b DMA", Dma64BitAddresses, Depth); DumpBooleanField("Handles 32b DMA", Dma32BitAddresses, Depth); xdprintfEx(Depth, ("Logical Unit Info:\n")); MpDumpChildren(DeviceExtension, Depth); return; } VOID MpDumpChildren( IN ULONG64 AdapterExtensionAddr, IN ULONG Depth ) { ULONG i; ULONG64 realLun; ULONG64 realLuns[8]; ULONG64 lun; ULONG CurrentPnpState=0, PreviousPnpState=0, CurrentDeviceState=0; ULONG DesiredDeviceState=0, CurrentSystemState=0; ULONG64 DeviceObject=0, NextLogicalUnit=0; ULONG result; ULONG PathId=0, TargetId=0, Lun=0, ucd; ULONG IsClaimed=0, IsMissing=0, IsEnumerated=0, IsVisible=0, IsMismatched=0; ULONG b6, b7, b8; InitTypeRead(AdapterExtensionAddr, scsiport!_ADAPTER_EXTENSION); realLuns[0] = ReadField(LogicalUnitList[0].List); realLuns[1] = ReadField(LogicalUnitList[1].List); realLuns[2] = ReadField(LogicalUnitList[2].List); realLuns[3] = ReadField(LogicalUnitList[3].List); realLuns[4] = ReadField(LogicalUnitList[4].List); realLuns[5] = ReadField(LogicalUnitList[5].List); realLuns[6] = ReadField(LogicalUnitList[6].List); realLuns[7] = ReadField(LogicalUnitList[7].List); Depth++; for (i = 0; i < NUMBER_LOGICAL_UNIT_BINS; i++) { realLun = realLuns[i]; while ((realLun != 0) && (!CheckControlC())) { FIELD_INFO deviceFields[] = { {"PathId", NULL, 0, COPY, 0, (PVOID) &PathId}, {"TargetId", NULL, 0, COPY, 0, (PVOID) &TargetId}, {"IsClaimed", NULL, 0, COPY, 0, (PVOID) &IsClaimed}, {"IsMissing", NULL, 0, COPY, 0, (PVOID) &IsMissing}, {"IsEnumerated", NULL, 0, COPY, 0, (PVOID) &IsEnumerated}, {"IsVisible", NULL, 0, COPY, 0, (PVOID) &IsVisible}, {"IsMismatched", NULL, 0, COPY, 0, (PVOID) &IsMismatched}, {"DeviceObject", NULL, 0, COPY, 0, (PVOID) &DeviceObject}, {"NextLogicalUnit", NULL, 0, COPY, 0, (PVOID) &NextLogicalUnit}, {"CommonExtension.CurrentPnpState", NULL, 0, COPY, 0, (PVOID) &CurrentPnpState}, {"CommonExtension.PreviousPnpState" , NULL, 0, COPY, 0, (PVOID) &PreviousPnpState}, {"CommonExtension.CurrentDeviceState", NULL, 0, COPY, 0, (PVOID) &CurrentDeviceState}, {"CommonExtension.DesiredDeviceState", NULL, 0, COPY, 0, (PVOID) &DesiredDeviceState}, {"CommonExtension.CurrentSystemState", NULL, 0, COPY, 0, (PVOID) &CurrentSystemState}, }; SYM_DUMP_PARAM DevSym = { sizeof (SYM_DUMP_PARAM), "scsiport!_LOGICAL_UNIT_EXTENSION", DBG_DUMP_NO_PRINT, realLun, NULL, NULL, NULL, sizeof (deviceFields) / sizeof (FIELD_INFO), &deviceFields[0] }; xdprintfEx(Depth, ("LUN ")); dprintf("%08p ", realLun); if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) { dprintf("%08lx: Could not read device object\n", realLun); return; } result = (ULONG) InitTypeRead(realLun, scsiport!_LOGICAL_UNIT_EXTENSION); if (result != 0) { dprintf("could not init read type (%x)\n", result); return; } lun = ReadField(Lun); Lun = (UCHAR) lun; dprintf("@ (%3d,%3d,%3d) %c%c%c%c%c pnp(%02x/%02x) pow(%d%c,%d) DevObj %08p\n", PathId, TargetId, Lun, (IsClaimed ? 'c' : ' '), (IsMissing ? 'm' : ' '), (IsEnumerated ? 'e' : ' '), (IsVisible ? 'v' : ' '), (IsMismatched ? 'r' : ' '), CurrentPnpState, PreviousPnpState, CurrentDeviceState - 1, ((DesiredDeviceState == PowerDeviceUnspecified) ? ' ' : '*'), CurrentSystemState - 1, DeviceObject); realLun = ReadField(NextLogicalUnit); } } return; } VOID MpDumpInterruptData( IN PINTERRUPT_DATA Data, IN PINTERRUPT_DATA RealData, IN ULONG Detail, IN ULONG Depth ) { xdprintfEx(Depth, ("Interrupt Data @0x%p:\n", RealData)); Depth++; DumpFlags(Depth, "Flags", Data->InterruptFlags, AdapterFlags); xdprintfEx(Depth, ("Ready LUN 0x%p Wmi Events 0x%p\n", Data->ReadyLogicalUnit, Data->WmiMiniPortRequests)); { ULONG count = 0; PSRB_DATA request = Data->CompletedRequests; xdprintfEx(Depth, ("Completed Request List (@0x%p): ", &(RealData->CompletedRequests))); Depth += 1; while((request != NULL) && (!CheckControlC())) { SRB_DATA data; ULONG result; if(Detail != 0) { if(count == 0) { dprintf("\n"); } xdprintfEx(Depth, ("SrbData 0x%p ", request)); } count++; if(!ReadMemory((ULONG_PTR)request, (PVOID) &data, sizeof(SRB_DATA), &result)) { dprintf("Error reading structure\n"); break; } if(Detail != 0) { dprintf("Srb 0x%p Irp 0x%p\n", data.CurrentSrb, data.CurrentIrp); } request = data.CompletedRequests; } Depth -= 1; if((Detail == 0) || (count == 0)) { dprintf("%d entries\n", count); } else { xdprintfEx(Depth + 1, ("%d entries\n", count)); } } return; } VOID MpDumpPdo( IN ULONG64 Address, IN OPTIONAL PADAPTER_EXTENSION Adapter, IN ULONG Detail, IN ULONG Depth ) { ULONG result; ULONG offset; ULONG PortNumber = 0; ULONG PathId = 0; ULONG TargetId = 0; ULONG Lun = 0; ULONG64 HwLogicalUnitExtension = 0; ULONG64 AdapterExtension = 0; ULONG IsClaimed = 0; ULONG IsMissing = 0; ULONG IsEnumerated = 0; ULONG IsVisible = 0; ULONG IsMismatched = 0; ULONG luflags = 0; ULONG RetryCount = 0; ULONG CurrentKey = 0; ULONG QueueLockCount = 0; ULONG QueuePauseCount = 0; ULONG LockRequest = 0; ULONG RequestTimeoutCounter = 0; ULONG64 NextLogicalUnit = 0; ULONG64 ReadyLogicalUnit = 0; ULONG64 PendingRequest = 0; ULONG64 BusyRequest = 0; ULONG64 CurrentUntaggedRequest = 0; ULONG64 AbortSrb = 0; ULONG64 CompletedAbort = 0; ULONG QueueCount = 0; ULONG MaxQueueDepth = 0; ULONG64 TargetDeviceMapKey = 0; ULONG64 LunDeviceMapKey = 0; ULONG64 ActiveFailedRequest = 0; ULONG64 BlockedFailedRequest = 0; ULONG64 RequestSenseIrp = 0; ULONG64 RequestListFlink = 0; ULONG64 RequestList = 0; ULONG64 CommonExtensionDeviceObject = 0; ULONG64 RequestSenseSrb = 0; ULONG64 RequestSenseMdl = 0; ULONG Fields; ULONG TickCount; FIELD_INFO deviceFields[] = { {"PortNumber", "", 0, COPY, 0, (PVOID) &PortNumber }, {"PathId", "", 0, COPY, 0, (PVOID) &PathId }, {"TargetId", "", 0, COPY, 0, (PVOID) &TargetId }, {"Lun", "", 0, COPY, 0, (PVOID) &Lun }, {"HwLogicalUnitExtension", "", 0, COPY, 0, (PVOID) &HwLogicalUnitExtension }, {"AdapterExtension", "", 0, COPY, 0, (PVOID) &AdapterExtension }, {"IsClaimed", "", 0, COPY, 0, (PVOID) &IsClaimed }, {"IsMissing", "", 0, COPY, 0, (PVOID) &IsMissing }, {"IsEnumerated", "", 0, COPY, 0, (PVOID) &IsEnumerated }, {"IsVisible", "", 0, COPY, 0, (PVOID) &IsVisible }, {"IsMismatched", "", 0, COPY, 0, (PVOID) &IsMismatched }, {"LuFlags", "", 0, COPY, 0, (PVOID) &luflags }, {"RetryCount", "", 0, COPY, 0, (PVOID) &RetryCount }, {"CurrentKey", "", 0, COPY, 0, (PVOID) &CurrentKey }, {"QueueLockCount", "", 0, COPY, 0, (PVOID) &QueueLockCount }, {"QueuePauseCount", "", 0, COPY, 0, (PVOID) &QueuePauseCount }, {"LockRequest", "", 0, COPY, 0, (PVOID) &LockRequest }, {"RequestTimeoutCounter", "", 0, COPY, 0, (PVOID) &RequestTimeoutCounter }, {"RetryCount", "", 0, COPY, 0, (PVOID) &RetryCount }, {"CurrentKey", "", 0, COPY, 0, (PVOID) &CurrentKey }, {"QueueLockCount", "", 0, COPY, 0, (PVOID) &QueueLockCount }, {"QueuePauseCount", "", 0, COPY, 0, (PVOID) &QueuePauseCount }, {"LockRequest", "", 0, COPY, 0, (PVOID) &LockRequest }, {"RequestTimeoutCounter", "", 0, COPY, 0, (PVOID) &RequestTimeoutCounter }, {"NextLogicalUnit", "", 0, COPY, 0, (PVOID) &NextLogicalUnit }, {"ReadyLogicalUnit", "", 0, COPY, 0, (PVOID) &ReadyLogicalUnit }, {"PendingRequest", "", 0, COPY, 0, (PVOID) &PendingRequest }, {"BusyRequest", "", 0, COPY, 0, (PVOID) &BusyRequest }, {"CurrentUntaggedRequest", "", 0, COPY, 0, (PVOID) &CurrentUntaggedRequest }, {"AbortSrb", "", 0, COPY, 0, (PVOID) &AbortSrb }, {"CompletedAbort", "", 0, COPY, 0, (PVOID) &CompletedAbort }, {"QueueCount", "", 0, COPY, 0, (PVOID) &QueueCount }, {"MaxQueueDepth", "", 0, COPY, 0, (PVOID) &MaxQueueDepth }, {"TargetDeviceMapKey", "", 0, COPY, 0, (PVOID) &TargetDeviceMapKey }, {"LunDeviceMapKey", "", 0, COPY, 0, (PVOID) &LunDeviceMapKey }, {"ActiveFailedRequest", "", 0, COPY, 0, (PVOID) &ActiveFailedRequest }, {"BlockedFailedRequest", "", 0, COPY, 0, (PVOID) &BlockedFailedRequest }, {"RequestSenseIrp", "", 0, COPY, 0, (PVOID) &RequestSenseIrp }, {"CommonExtension.DeviceObject", "", 0, COPY, 0, (PVOID) &CommonExtensionDeviceObject }, {"RequestList.Flink", "", 0, COPY, 0, (PVOID) &RequestListFlink }, {"RequestList", "", 0, ADDROF, 0, NULL }, {"RequestSenseSrb", "", 0, ADDROF, 0, NULL }, {"RequestSenseMdl", "", 0, ADDROF, 0, NULL }, }; SYM_DUMP_PARAM DevSym = { sizeof (SYM_DUMP_PARAM), "scsiport!_LOGICAL_UNIT_EXTENSION", DBG_DUMP_NO_PRINT, Address, NULL, NULL, NULL, sizeof (deviceFields) / sizeof (FIELD_INFO), &deviceFields[0] }; if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) { dprintf("%08p: Could not read device object\n", Address); return; } Fields = sizeof (deviceFields) / sizeof (FIELD_INFO); RequestList = deviceFields[Fields-3].address; RequestSenseSrb = deviceFields[Fields-2].address; RequestSenseMdl = deviceFields[Fields-1].address; InitTypeRead(AdapterExtension, scsiport!_ADAPTER_EXTENSION); TickCount = (ULONG) ReadField(TickCount); xdprintfEx(Depth, ("Address (Port, PathId, TargetId, Lun): (%d, %d, %d, %d)\n", PortNumber, PathId, TargetId, Lun)); DumpPointerField("HW Logical Unit Ext", HwLogicalUnitExtension, Depth); DumpPointerField("Adapter Ext", AdapterExtension, Depth); xdprintfEx(Depth, ("State:")); if (IsClaimed) xdprintf(0, " Claimed"); if (IsMissing) xdprintf(0, " Missing"); if (IsEnumerated) xdprintf(0, " Enumerated"); if (IsVisible) xdprintf(0, " Visible"); if (IsMismatched) xdprintf(0, " Mismatched"); dprintf("\n"); DumpFlags(Depth, "LuFlags", luflags, LuFlags); DumpUcharField("Retries ", RetryCount, Depth); DumpUlongField("Key ", CurrentKey, Depth); DumpUlongField("Locks ", QueueLockCount, Depth); DumpUlongField("Pauses ", QueuePauseCount, Depth); DumpUlongField("Current Lock ", LockRequest, Depth); DumpUlongField("Timeou ", RequestTimeoutCounter, Depth); xdprintfEx(Depth, ("Next LUN: %p Ready LUN: %p\n", NextLogicalUnit, ReadyLogicalUnit)); xdprintfEx(Depth, ("Requests:\n")); Depth++; DumpPointerField("Pending ", PendingRequest, Depth); DumpPointerField("Busy ", BusyRequest, Depth); DumpPointerField("Untagged ", CurrentUntaggedRequest, Depth); Depth--; xdprintfEx(Depth, ("Abort SRB Info:\n")); Depth++; DumpPointerField("Current ", AbortSrb, Depth); DumpPointerField("Completed", CompletedAbort, Depth); Depth--; xdprintfEx(Depth, ("Queue Depth: %03d (Max: %03d)\n", QueueCount, MaxQueueDepth)); xdprintfEx(Depth, ("Device Map Keys:\n")); Depth++; DumpUlongField("Target ", (ULONG)TargetDeviceMapKey, Depth); DumpUlongField("Lun ", (ULONG)LunDeviceMapKey, Depth); Depth--; if(((PVOID)ActiveFailedRequest != NULL) || ((PVOID)BlockedFailedRequest != NULL)) { xdprintfEx(Depth, ("Failed Requests:\n")); Depth++; if((PVOID)ActiveFailedRequest != NULL) { DumpPointerField("Active", ActiveFailedRequest, Depth); } if((PVOID)BlockedFailedRequest != NULL) { DumpPointerField("Blocked", BlockedFailedRequest, Depth); } Depth--; } xdprintfEx(Depth, ("Request Sense:\n")); Depth++; DumpPointerField("IRP", RequestSenseIrp, Depth); DumpPointerField("SRB", RequestSenseSrb, Depth); DumpPointerField("MDL", RequestSenseMdl, Depth); Depth--; if (RequestListFlink == RequestList) { xdprintfEx(Depth, ("Request List @")); dprintf("%08p is empty\n", RequestList); } else { xdprintfEx(Depth, ("Request list @")); dprintf("%08p:\n", RequestList); MpDumpActiveRequests(RequestList, TickCount, Depth + 2); } #if 0 // if(Detail != 0) { xdprintfEx(Depth, ("Queued requests:\n")); MpDumpRequests( CommonExtensionDeviceObject, TickCount, Depth + 2 ); // } #endif return; } ULONG64 MpGetOffsetOfField( IN PCCHAR Type, IN PCCHAR Field ) { FIELD_INFO offsetField[] = { {Field, NULL, 0, DBG_DUMP_FIELD_RETURN_ADDRESS, 0, NULL }, }; SYM_DUMP_PARAM DevSym = { sizeof (SYM_DUMP_PARAM), Type, DBG_DUMP_NO_PRINT, 0, NULL, NULL, NULL, 1, &offsetField[0] }; if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) { return (ULONG)-1; } return offsetField[0].address; } VOID MpDumpActiveRequests( IN ULONG64 ListHead, IN ULONG TickCount, IN ULONG Depth ) { ULONG64 lastEntry; ULONG64 entry; ULONG64 realEntry; ULONG64 OffsetOfRequestList; ULONG64 CurrentSrb = 0; ULONG64 CurrentIrp = 0; ULONG64 RequestList = 0; ULONG SrbTickCount = 0; FIELD_INFO deviceFields[] = { {"CurrentSrb", NULL, 0, COPY, 0, (PVOID) &CurrentSrb }, {"CurrentIrp", NULL, 0, COPY, 0, (PVOID) &CurrentIrp }, {"TickCount", NULL, 0, COPY, 0, (PVOID) &SrbTickCount }, {"RequestList", NULL, 0, DBG_DUMP_FIELD_RETURN_ADDRESS, 0, NULL}, }; SYM_DUMP_PARAM DevSym = { sizeof (SYM_DUMP_PARAM), "scsiport!_SRB_DATA", DBG_DUMP_NO_PRINT, 0, NULL, NULL, NULL, sizeof (deviceFields) / sizeof (FIELD_INFO), &deviceFields[0] }; OffsetOfRequestList = MpGetOffsetOfField("scsiport!_SRB_DATA", "RequestList"); entry = ListHead; realEntry = entry; InitTypeRead(ListHead, nt!_LIST_ENTRY); lastEntry = ReadField(Blink); xdprintf(Depth, "Tick count is %d\n", TickCount); do { ULONG64 realSrbData; ULONG result; InitTypeRead(realEntry, nt!_LIST_ENTRY); entry = ReadField(Flink); // // entry points to the list entry element of the srb data. Calculate // the address of the start of the srb data block. // realSrbData = entry - OffsetOfRequestList; xdprintfEx(Depth, ("SrbData ")); dprintf("%08p ", realSrbData); // // Read the SRB_DATA information we need. // DevSym.addr = realSrbData; if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) { dprintf("%08p: Could not read device object\n", realSrbData); return; } RequestList = deviceFields[3].address; // // Update realEntry. // realEntry = RequestList; dprintf("Srb %08p Irp %08p %s\n", CurrentSrb, CurrentIrp, MpSecondsToString(TickCount - SrbTickCount)); } while((entry != lastEntry) && (!CheckControlC())); return; } VOID MpDumpSrbData( PSRB_DATA SrbData, ULONG Depth ) { if (SrbData->Type != SRB_DATA_TYPE) { dprintf("Type (%#x) does not match SRB_DATA_TYPE (%#x)\n", SrbData->Type, SRB_DATA_TYPE); } xdprintfEx(Depth, ("Lun 0x%p Srb 0x%p Irp 0x%p\n", SrbData->LogicalUnit, SrbData->CurrentSrb, SrbData->CurrentIrp)); xdprintfEx(Depth, ("Sense 0x%p Tag 0x%08lx Next Completed 0x%p\n", SrbData->RequestSenseSave, SrbData->QueueTag, SrbData->CompletedRequests)); xdprintfEx(Depth, ("Retry 0x%02x Seq 0x%08lx Flags 0x%08lx\n", SrbData->ErrorLogRetryCount, SrbData->SequenceNumber, SrbData->Flags)); xdprintfEx(Depth, ("Request List: Next 0x%p Previous 0x%p\n", SrbData->RequestList.Flink, SrbData->RequestList.Blink)); xdprintfEx(Depth, ("Data Offset 0x%p Original Data Buffer 0x%p\n", SrbData->DataOffset, SrbData->OriginalDataBuffer)); xdprintfEx(Depth, ("Map Registers 0x%p (0x%02x) SG List 0x%p\n", SrbData->MapRegisterBase, SrbData->NumberOfMapRegisters, SrbData->ScatterGatherList)); if (SrbData->ScatterGatherList != NULL) { UCHAR buffer[512]; PSRB_SCATTER_GATHER scatterGatherList = (PSRB_SCATTER_GATHER) &buffer; ULONG result; result = ReadMemory((ULONG_PTR)SrbData->ScatterGatherList, (PVOID) scatterGatherList, (sizeof(SRB_SCATTER_GATHER) * SrbData->NumberOfMapRegisters), &result); if (result == 0) { xdprintfEx(Depth+1, ("Error reading scatter gather list %#p\n", SrbData->ScatterGatherList)); return; } MpDumpScatterGatherList(scatterGatherList, SrbData->NumberOfMapRegisters, Depth + 1); } return; } VOID MpDumpScatterGatherList( PSRB_SCATTER_GATHER List, ULONG Entries, ULONG Depth ) { ULONG i; BOOLEAN start = TRUE; for (i = 0; i < Entries; i++) { if (start) { // BUGBUG - PhysicalAddress should be 64 bits but isn't xdprintfEx(Depth, ("0x%016I64x (0x%08lx), ", List[i].Address, List[i].Length)); } else { // BUGBUG - PhysicalAddress should be 64 bits but isn't dprintf("0x%016I64x (0x%08lx),\n", List[i].Address, List[i].Length); } start = !start; } if (start == FALSE) { dprintf("\n"); } } PUCHAR MpSecondsToString( ULONG Count ) { static UCHAR string[64] = ""; UCHAR tmp[16]; ULONG seconds = 0; ULONG minutes = 0; ULONG hours = 0; ULONG days = 0; string[0] = '\0'; if (Count == 0) { sprintf(string, "<1s"); return string; } seconds = Count % 60; Count /= 60; if (Count != 0) { minutes = Count % 60; Count /= 60; } if (Count != 0) { hours = Count % 24; Count /= 24; } if (Count != 0) { days = Count; } if (days != 0) { sprintf(tmp, "%dd", days); strcat(string, tmp); } if (hours != 0) { sprintf(tmp, "%dh", hours); strcat(string, tmp); } if (minutes != 0) { sprintf(tmp, "%dm", minutes); strcat(string, tmp); } if (seconds != 0) { sprintf(tmp, "%ds", seconds); strcat(string, tmp); } return string; } VOID MpDumpRequests( IN ULONG64 DeviceObject, IN ULONG TickCount, IN ULONG Depth ) { ULONG result; LIST_ENTRY listHead; PLIST_ENTRY realEntry; ULONG64 DeviceQueue; ULONG offset; // // Read the queue out of the device object. // result = GetFieldData(DeviceObject, "nt!_DEVICE_OBJECT", "DeviceQueue.DeviceListHead", sizeof(LIST_ENTRY), &listHead); if (result) { dprintf("GetFieldValue @(%s %d) failed (%08X)\n", __FILE__, __LINE__, result); return; } if (listHead.Flink == listHead.Blink) { xdprintf(Depth, "Device Queue is empty\n"); return; } result = GetFieldData(DeviceObject, "nt!_DEVICE_OBJECT", "DeviceQueue", sizeof(ULONG64), &DeviceQueue); if (result) { dprintf("GetFieldData @(%s %d) failed (%08X)\n", __FILE__, __LINE__, result); return; } result = GetFieldOffset("nt!_KDEVICE_QUEUE", "DeviceListHead", &offset); realEntry = (LIST_ENTRY*)(DeviceQueue + offset); return; #if 0 do { LIST_ENTRY entry; PIRP realIrp; PIO_STACK_LOCATION realStack; PSCSI_REQUEST_BLOCK realSrb; PSRB_DATA realSrbData; SRB_DATA srbData; ULONG result; // // we've got a pointer to the first list_entry in the list. Read the // whole thing in so we can see where the next entry will be. // if(!ReadMemory((ULONG_PTR) realEntry, &entry, sizeof(LIST_ENTRY), &result)) { dprintf("Error reading list entry\n"); break; } realEntry = entry.Flink; // // entry points to the middle of an irp. Figure out the address of // of the beginning of the irp (save it) and then figure out the // address of the current irp stack location from there. // realIrp = CONTAINING_RECORD( realEntry, IRP, Tail.Overlay.DeviceQueueEntry.DeviceListEntry); if(!ReadMemory((ULONG_PTR) &(realIrp->Tail.Overlay.CurrentStackLocation), &realStack, sizeof(PIO_STACK_LOCATION), &result)) { dprintf("Error reading stack address %p\n", &(realIrp->Tail.Overlay.CurrentStackLocation)); break; } // // Load the SRB field of the stack location. // if(!ReadMemory( (ULONG_PTR) &(realStack->Parameters.Scsi.Srb), &realSrb, sizeof(PSCSI_REQUEST_BLOCK), &result)) { dprintf("Error reading srb address\n"); break; } // // Pick out the pointer to the srb data and read that in. // if(!ReadMemory( (ULONG_PTR) &(realSrb->OriginalRequest), &realSrbData, sizeof(PSRB_DATA), &result)) { dprintf("Error reading srbData address\n"); break; } xdprintf(Depth, "SrbData 0x%p ", realSrbData); if(!ReadMemory((ULONG_PTR)realSrbData, (PVOID) &srbData, sizeof(SRB_DATA), &result)) { dprintf("Error reading structure\n"); break; } dprintf("Srb 0x%p Irp 0x%p %s\n", srbData.CurrentSrb, srbData.CurrentIrp, MpSecondsToString(TickCount - srbData.TickCount)); } while((realEntry != listHead.Blink) && (!CheckControlC())); return; #endif } VOID MpDumpAccessRange( IN ULONG64 address, IN ULONG Depth ) { ULONG64 RangeStart; ULONG RangeLength; BOOLEAN RangeInMemory; InitTypeRead(address, scsiport!_ACCESS_RANGE); RangeStart = ReadField(RangeStart.QuadPart); RangeLength = (ULONG) ReadField(RangeLength); RangeInMemory = (BOOLEAN) ReadField(RangeInMemory); xdprintfEx(Depth, ("@ %08p %08p %08x %s\n", address, RangeStart, RangeLength, RangeInMemory ? "YES" : "NO")); return; } VOID MpDumpSrb( IN ULONG64 Srb, IN ULONG Depth ) { ULONG result = 0; USHORT Length = 0; UCHAR Function = 0; UCHAR SrbStatus = 0; UCHAR ScsiStatus = 0; UCHAR PathId = 0; UCHAR TargetId = 0; UCHAR Lun = 0; UCHAR QueueTag = 0; UCHAR QueueAction = 0; UCHAR CdbLength = 0; UCHAR SenseInfoBufferLength = 0; ULONG Flags = 0; ULONG DataTransferLength = 0; ULONG TimeOutValue = 0; ULONG64 DataBuffer = 0; ULONG64 SenseInfoBuffer = 0; ULONG64 NextSrb = 0; ULONG64 OriginalRequest = 0; ULONG64 SrbExtension = 0; ULONG InternalStatus = 0; ULONG64 AddrOfCdb = 0; UCHAR Cdb[16]; ULONG i; FIELD_INFO deviceFields[] = { {"Length", NULL, 0, COPY, 0, (PVOID) &Length }, {"Function", NULL, 0, COPY, 0, (PVOID) &Function }, {"SrbStatus", NULL, 0, COPY, 0, (PVOID) &SrbStatus }, {"ScsiStatus", NULL, 0, COPY, 0, (PVOID) &ScsiStatus }, {"PathId", NULL, 0, COPY, 0, (PVOID) &PathId }, {"TargetId", NULL, 0, COPY, 0, (PVOID) &TargetId }, {"Lun", NULL, 0, COPY, 0, (PVOID) &Lun }, {"QueueTag", NULL, 0, COPY, 0, (PVOID) &QueueTag }, {"QueueAction", NULL, 0, COPY, 0, (PVOID) &QueueAction }, {"CdbLength", NULL, 0, COPY, 0, (PVOID) &CdbLength }, {"SenseInfoBufferLength", NULL, 0, COPY, 0, (PVOID) &SenseInfoBufferLength }, {"SrbFlags", NULL, 0, COPY, 0, (PVOID) &Flags }, {"DataTransferLength", NULL, 0, COPY, 0, (PVOID) &DataTransferLength }, {"TimeOutValue", NULL, 0, COPY, 0, (PVOID) &TimeOutValue }, {"DataBuffer", NULL, 0, COPY, 0, (PVOID) &DataBuffer }, {"SenseInfoBuffer", NULL, 0, COPY, 0, (PVOID) &SenseInfoBuffer }, {"NextSrb", NULL, 0, COPY, 0, (PVOID) &NextSrb }, {"OriginalRequest", NULL, 0, COPY, 0, (PVOID) &OriginalRequest }, {"SrbExtension", NULL, 0, COPY, 0, (PVOID) &SrbExtension }, {"InternalStatus", NULL, 0, COPY, 0, (PVOID) &InternalStatus }, {"Cdb", NULL, 0, ADDROF, 0, NULL }, }; SYM_DUMP_PARAM DevSym = { sizeof (SYM_DUMP_PARAM), "scsiport!_SCSI_REQUEST_BLOCK", DBG_DUMP_NO_PRINT, Srb, NULL, NULL, NULL, sizeof (deviceFields) / sizeof (FIELD_INFO), &deviceFields[0] }; if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) { dprintf("Could not read SRB @ %08p\n", Srb); return; } AddrOfCdb = deviceFields[(sizeof (deviceFields) / sizeof (FIELD_INFO)) - 1].address; if (!ReadMemory((ULONG64)AddrOfCdb, Cdb, sizeof(UCHAR) * 16, &result)) { dprintf("Error reading access range\n"); return; } xdprintf(Depth, "SCSI_REQUEST_BLOCK:\n"); DumpUshortField("Length", Length, Depth); if (Function < MINIKD_MAX_SCSI_FUNCTION) { xdprintfEx(Depth, ("%s: 0x%02X (%s)\n", "Function", Function, MiniScsiFunction[Function])); } else { xdprintfEx(Depth, ("%s: 0x%02X (???)\n", "Function", Function)); } xdprintfEx(Depth, ("%s: 0x%02X (", "Status", SrbStatus)); if (SrbStatus & SRB_STATUS_AUTOSENSE_VALID) { dprintf("SRB_STATUS_AUTOSENSE_VALID | "); } if (SrbStatus & SRB_STATUS_QUEUE_FROZEN) { dprintf("SRB_STATUS_QUEUE_FROZEN | "); } if (SRB_STATUS(SrbStatus) < MINIKD_MAX_SCSI_FUNCTION) { dprintf("%s)", MiniScsiSrbStatus[SRB_STATUS(SrbStatus)]); } else { dprintf("???)"); } dprintf("\n"); DumpUcharField("ScsiStatus ", ScsiStatus, Depth); DumpUcharField("PathId ", PathId, Depth); DumpUcharField("TargetId ", TargetId, Depth); DumpUcharField("Lun ", Lun, Depth); DumpUcharField("QueueTag ", QueueTag, Depth); DumpUcharField("QueueAction", QueueAction, Depth); DumpUcharField("CdbLength ", CdbLength, Depth); DumpUcharField("SenseInfoBufferLength", SenseInfoBufferLength, Depth); DumpFlags(Depth, "SrbFlags", Flags, SrbFlags); DumpUlongField("DataTransferLength", DataTransferLength, Depth); DumpUlongField("TimeOutValue ", TimeOutValue, Depth); DumpPointerField("DataBuffer ", DataBuffer, Depth); DumpPointerField("SenseInfoBuffer ", SenseInfoBuffer, Depth); DumpPointerField("NextSrb ", NextSrb, Depth); DumpPointerField("OriginalRequest ", OriginalRequest, Depth); DumpPointerField("SrbExtension ", SrbExtension, Depth); DumpUlongField("InternalStatus ", InternalStatus, Depth); xdprintfEx(Depth, ("%s: ", "Cdb")); for (i=0; i= 0 && AdapterInterfaceType < MaximumInterfaceType) { xdprintfEx(Depth, ("%s: 0x%X (%s)\n", "AdapterInterfaceType", AdapterInterfaceType, MiniInterfaceTypes[AdapterInterfaceType])); } else { xdprintfEx(Depth, ("%s: 0x%X (???)\n", "AdapterInterfaceType", AdapterInterfaceType)); } DumpUlongField("BusIntLvl", BusInterruptLevel, Depth); DumpUlongField("BusIntVector", BusInterruptVector, Depth); if (InterruptMode >= 0 && InterruptMode <= Latched) { xdprintfEx(Depth, ("%s: 0x%X (%s)\n", "InterruptMode", InterruptMode, MiniInterruptMode[InterruptMode])); } else { xdprintfEx(Depth, ("%s: 0x%X (???)\n", "InterruptMode", InterruptMode)); } DumpUlongField("MaximumTransferLength", MaximumTransferLength, Depth); DumpUlongField("NumberOfPhysicalBreaks", NumberOfPhysicalBreaks, Depth); DumpUlongField("DmaChannel", DmaChannel, Depth); DumpUlongField("DmaPort", DmaPort, Depth); if (DmaWidth >= 0 && DmaWidth < MaximumDmaWidth) { xdprintfEx(Depth, ("%s: 0x%X (%s)\n", "DmaWidth", DmaWidth, MiniDmaWidths[DmaWidth])); } else { xdprintfEx(Depth, ("%s: 0x%X (???)\n", "DmaWidth", DmaWidth)); } if (DmaSpeed >= 0 && DmaSpeed < MaximumDmaSpeed) { xdprintfEx(Depth, ("%s: 0x%X (%s)\n", "DmaSpeed", DmaSpeed, MiniDmaWidths[DmaSpeed])); } else { xdprintfEx(Depth, ("%s: 0x%X (???)\n", "DmaSpeed", DmaSpeed)); } DumpUlongField("AlignmentMask", AlignmentMask, Depth); DumpPointerField("Reserved", (ULONG_PTR)Reserved, Depth); DumpUlongField("NumberOfBuses", NumberOfBuses, Depth); status = ReadMemory(InitiatorBusId, (PVOID) BusId, sizeof(UCHAR) * 8, &result); if (!status) { dprintf("Error reading initiator bus id @ %08p\n", InitiatorBusId); return; } xdprintfEx(Depth, ("%s: ", "InitiatorBusId")); for (i = 0; i < 8; i++) { xdprintfEx(Depth, ("%02x ", BusId[i])); } xdprintfEx(Depth, ("\n")); DumpBooleanField("ScatterGather ", ScatterGather, Depth); DumpBooleanField("Master ", Master, Depth); DumpBooleanField("AdapterScansDown ", AdapterScansDown, Depth); DumpBooleanField("AtdiskPrimaryClaimed ", AtdiskPrimaryClaimed, Depth); DumpBooleanField("AtdiskSecondaryClaimed ", AtdiskSecondaryClaimed, Depth); DumpBooleanField("Dma32BitAddresses ", Dma32BitAddresses, Depth); DumpBooleanField("DemandMode ", DemandMode, Depth); DumpBooleanField("MapBuffers ", MapBuffers, Depth); DumpBooleanField("NeedPhysicalAddresses ", NeedPhysicalAddresses, Depth); DumpBooleanField("TaggedQueuing ", TaggedQueuing, Depth); DumpBooleanField("AutoRequestSense ", AutoRequestSense, Depth); DumpBooleanField("MultipleRequestPerLu ", MultipleRequestPerLu, Depth); DumpBooleanField("ReceiveEvent ", ReceiveEvent, Depth); DumpBooleanField("RealModeInitialized ", RealModeInitialized, Depth); DumpBooleanField("BufScsiPortControlled ", BufferAccessScsiPortControlled, Depth); DumpUlongField("MaximumNumberOfTargets", MaximumNumberOfTargets, Depth); DumpUlongField("SlotNumber", SlotNumber, Depth); DumpUlongField("BusInterruptLevel2", BusInterruptLevel2, Depth); DumpUlongField("BusInterruptVector2", BusInterruptVector2, Depth); if (InterruptMode2 >= 0 && InterruptMode2 <= Latched) { xdprintfEx(Depth, ("%s: 0x%X (%s)\n", "InterruptMode2", InterruptMode2, MiniInterruptMode[InterruptMode2])); } else { xdprintfEx(Depth, ("%s: 0x%X (???)\n", "InterruptMode2", InterruptMode2)); } DumpUlongField("DmaChannel2", DmaChannel2, Depth); DumpUlongField("DmaPort2", DmaPort2, Depth); if (DmaWidth2 >= 0 && DmaWidth2 < MaximumDmaWidth) { xdprintfEx(Depth, ("%s: 0x%X (%s)\n", "DmaWidth2", DmaWidth2, MiniDmaWidths[DmaWidth2])); } else { xdprintfEx(Depth, ("%s: 0x%X (???)\n", "DmaWidth2", DmaWidth2)); } DumpUlongField("DeviceExtensionSize ", DeviceExtensionSize, Depth); DumpUlongField("SpecificLuExtensionSize ", SpecificLuExtensionSize, Depth); DumpUlongField("SrbExtensionSize ", SrbExtensionSize, Depth); DumpUlongField("Dma64BitAddresses ", Dma64BitAddresses, Depth); DumpUlongField("ResetTargetSupported ", ResetTargetSupported, Depth); DumpUlongField("MaxLogicalUnits ", MaximumNumberOfLogicalUnits, Depth); DumpUlongField("WmiDataProvider ", WmiDataProvider, Depth); DumpUlongField("NumberOfAccessRanges", NumberOfAccessRanges, Depth); xdprintfEx(Depth, ("Access Ranges...\n")); Depth++; for (i = 0; i < NumberOfAccessRanges; i++) { MpDumpAccessRange(AccessRanges, Depth); AccessRanges += sizeof(ACCESS_RANGE); } return; }