windows-nt/Source/XPSP1/NT/drivers/storage/kdext/minipkd/minipkd.c
2020-09-26 16:20:57 +08:00

2402 lines
80 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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; i<CurrentAdapter-1; i++) {
if (AdapterAddr == AdapterArr[i]) {
ValidAdapter = FALSE;
goto ShowIt;
}
}
}
//
// Read device object data.
//
if (InitTypeRead(AdapterAddr, nt!_DEVICE_OBJECT)) {
ValidAdapter = FALSE;
goto ShowIt;
}
//
// Let's make sure this is a valid device object by checking that
// the Type field is valid.
//
Type = (ULONG)ReadField(Type);
if (Type != IO_TYPE_DEVICE) {
ValidAdapter = FALSE;
} else {
//
// The DriverObject field will be non-null for a valid device object.
//
DriverObjectAddr = ReadField(DriverObject);
if (!DriverObjectAddr) {
ValidAdapter = FALSE;
goto ShowIt;
}
//
// The DeviceExtension field should also be non-null.
//
DeviceExtension = ReadField(DeviceExtension);
if (!DeviceExtension) {
ValidAdapter = FALSE;
goto ShowIt;
}
//
// Let's do one more check to be sure we're dealing with a valid
// device object. If it's valid, the extension's DeviceObject
// field will point back to the device object.
//
if (InitTypeRead(DeviceExtension, scsiport!COMMON_EXTENSION)) {
ValidAdapter = FALSE;
} else {
RemoveStatus = (ULONG)ReadField(IsRemoved);
if (RemoveStatus != NO_REMOVE && RemoveStatus != REMOVE_PENDING) {
ValidAdapter = FALSE;
} else {
//
// Ok, we know the device object is valid. Go ahead and
// get the rest of the information we need.
//
InitTypeRead(DriverObjectAddr, scsiport!DRIVER_OBJECT);
DriverNameBuffer = ReadField(DriverName.Buffer);
if (!DriverNameBuffer) {
MINIPKD_PRINT_ERROR(0);
return E_FAIL;
}
DriverNameLength = ReadField(DriverName.Length);
if (!DriverNameLength) {
MINIPKD_PRINT_ERROR(0);
return E_FAIL;
}
status = ReadMemory(
DriverNameBuffer,
(PVOID) NameBuffer,
(ULONG)DriverNameLength * sizeof(WCHAR),
&result);
if (!status) {
PWCHAR NoName = L"Driver name paged out";
RtlMoveMemory(NameBuffer,
NoName,
21 * sizeof(WCHAR));
}
}
}
}
ShowIt:
//
// Display some information about the adapter.
//
if (ValidAdapter) {
dprintf("%S %-20S DO %-16p DevExt %-16p %s\n",
L"Adapter",
NameBuffer,
AdapterAddr,
DeviceExtension,
(RemoveStatus == REMOVE_PENDING) ? "REMOVE PENDING" : "");
MpDumpChildren(DeviceExtension, 0);
}
//
// Advance current adapter index.
//
++CurrentAdapter;
}
return S_OK;
}
DECLARE_API (portconfig)
/*++
Routine Description:
Dumps supplied address as a PORT_CONFIGURATION_INFORMATION struct
Arguments:
args - string containing the address of a
PORT_CONFIGURATION_INFORMATION struct
Return Value:
none
--*/
{
ULONG64 address;
//
// Get the address of the struct.
//
GetExpressionEx(args, &address, &args);
//
// Dump the PORT_CONFIGURATION_INFORMATION
//
MpDumpPortConfigurationInformation(
address,
0);
return S_OK;
}
DECLARE_API (srb)
/*++
Routine Description:
Dumps supplied address as a SCSI_REQUEST_BLOCK struct
Arguments:
args - string containing the address of a
PORT_CONFIGURATION_INFORMATION struct
Return Value:
none
--*/
{
ULONG64 address;
//
// Get the address of the struct.
//
GetExpressionEx(args, &address, &args);
//
// Dump the PORT_CONFIGURATION_INFORMATION
//
MpDumpSrb(
address,
0);
return S_OK;
}
DECLARE_API (adapter)
/*++
Routine Description:
Dumps adapter information for the specified adapter.
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);
//
// If the supplied address points to a device, fixup the address to
// that of the device's extension.
//
InitTypeRead(Address, nt!_DEVICE_OBJECT);
Type = ReadField(Type);
DeviceExtension = Address;
if (Type == IO_TYPE_DEVICE) {
DeviceExtension = ReadField(DeviceExtension);
if (!DeviceExtension) {
MINIPKD_PRINT_ERROR(0);
return E_FAIL;
}
Address = DeviceExtension;
}
//
// Make sure an ADAPTER_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;
}
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<CdbLength; i++) {
dprintf("%x ", Cdb[i]);
}
dprintf("\n");
return;
}
VOID
MpDumpPortConfigurationInformation(
IN ULONG64 PortConfigInfo,
IN ULONG Depth
)
{
ULONG i;
ULONG_PTR range;
ULONG Fields;
UCHAR BusId[8];
ULONG status;
ULONG result;
ULONG Length = 0;
ULONG SystemIoBusNumber = 0;
INTERFACE_TYPE AdapterInterfaceType = 0;
ULONG BusInterruptLevel = 0;
ULONG BusInterruptVector = 0;
KINTERRUPT_MODE InterruptMode = 0;
ULONG MaximumTransferLength = 0;
ULONG NumberOfPhysicalBreaks = 0;
ULONG DmaChannel = 0;
ULONG DmaPort = 0;
DMA_WIDTH DmaWidth = 0;
DMA_SPEED DmaSpeed = 0;
ULONG AlignmentMask = 0;
ULONG NumberOfAccessRanges = 0;
PVOID Reserved = 0;
UCHAR NumberOfBuses = 0;
BOOLEAN ScatterGather = 0;
BOOLEAN Master = 0;
BOOLEAN CachesData = 0;
BOOLEAN AdapterScansDown = 0;
BOOLEAN AtdiskPrimaryClaimed = 0;
BOOLEAN AtdiskSecondaryClaimed = 0;
BOOLEAN Dma32BitAddresses = 0;
BOOLEAN DemandMode = 0;
BOOLEAN MapBuffers = 0;
BOOLEAN NeedPhysicalAddresses = 0;
BOOLEAN TaggedQueuing = 0;
BOOLEAN AutoRequestSense = 0;
BOOLEAN MultipleRequestPerLu = 0;
BOOLEAN ReceiveEvent = 0;
BOOLEAN RealModeInitialized = 0;
BOOLEAN BufferAccessScsiPortControlled = 0;
UCHAR MaximumNumberOfTargets = 0;
ULONG SlotNumber = 0;
ULONG BusInterruptLevel2 = 0;
ULONG BusInterruptVector2 = 0;
KINTERRUPT_MODE InterruptMode2 = 0;
ULONG DmaChannel2 = 0;
ULONG DmaPort2 = 0;
DMA_WIDTH DmaWidth2 = 0;
DMA_SPEED DmaSpeed2 = 0;
ULONG DeviceExtensionSize = 0;
ULONG SpecificLuExtensionSize = 0;
ULONG SrbExtensionSize = 0;
UCHAR Dma64BitAddresses = 0;
BOOLEAN ResetTargetSupported = 0;
UCHAR MaximumNumberOfLogicalUnits = 0;
BOOLEAN WmiDataProvider = 0;
ULONG64 InitiatorBusId = 0;
ULONG64 AccessRanges = 0;
FIELD_INFO deviceFields[] = {
{"Length", NULL, 0, COPY, 0, (PVOID) &Length },
{"SystemIoBusNumber", NULL, 0, COPY, 0, (PVOID) &SystemIoBusNumber },
{"AdapterInterfaceType", NULL, 0, COPY, 0, (PVOID) &AdapterInterfaceType },
{"BusInterruptLevel", NULL, 0, COPY, 0, (PVOID) &BusInterruptLevel },
{"BusInterruptVector", NULL, 0, COPY, 0, (PVOID) &BusInterruptVector },
{"InterruptMode", NULL, 0, COPY, 0, (PVOID) &InterruptMode },
{"MaximumTransferLength", NULL, 0, COPY, 0, (PVOID) &MaximumTransferLength },
{"NumberOfPhysicalBreaks", NULL, 0, COPY, 0, (PVOID) &NumberOfPhysicalBreaks },
{"DmaChannel", NULL, 0, COPY, 0, (PVOID) &DmaChannel },
{"DmaPort", NULL, 0, COPY, 0, (PVOID) &DmaPort },
{"DmaWidth", NULL, 0, COPY, 0, (PVOID) &DmaWidth },
{"DmaSpeed", NULL, 0, COPY, 0, (PVOID) &DmaSpeed },
{"AlignmentMask", NULL, 0, COPY, 0, (PVOID) &AlignmentMask },
{"NumberOfAccessRanges", NULL, 0, COPY, 0, (PVOID) &NumberOfAccessRanges },
{"Reserved", NULL, 0, COPY, 0, (PVOID) &Reserved },
{"NumberOfBuses", NULL, 0, COPY, 0, (PVOID) &NumberOfBuses },
{"ScatterGather", NULL, 0, COPY, 0, (PVOID) &ScatterGather },
{"Master", NULL, 0, COPY, 0, (PVOID) &Master },
{"CachesData", NULL, 0, COPY, 0, (PVOID) &CachesData },
{"AdapterScansDown", NULL, 0, COPY, 0, (PVOID) &AdapterScansDown },
{"AtdiskPrimaryClaimed", NULL, 0, COPY, 0, (PVOID) &AtdiskPrimaryClaimed },
{"AtdiskSecondaryClaimed", NULL, 0, COPY, 0, (PVOID) &AtdiskSecondaryClaimed },
{"Dma32BitAddresses", NULL, 0, COPY, 0, (PVOID) &Dma32BitAddresses },
{"DemandMode", NULL, 0, COPY, 0, (PVOID) &DemandMode },
{"MapBuffers", NULL, 0, COPY, 0, (PVOID) &MapBuffers },
{"NeedPhysicalAddresses", NULL, 0, COPY, 0, (PVOID) &NeedPhysicalAddresses },
{"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 },
{"RealModeInitialized", NULL, 0, COPY, 0, (PVOID) &RealModeInitialized },
{"BufferAccessScsiPortControlled", NULL, 0, COPY, 0, (PVOID) &BufferAccessScsiPortControlled},
{"MaximumNumberOfTargets", NULL, 0, COPY, 0, (PVOID) &MaximumNumberOfTargets },
{"SlotNumber", NULL, 0, COPY, 0, (PVOID) &SlotNumber },
{"BusInterruptLevel2", NULL, 0, COPY, 0, (PVOID) &BusInterruptLevel2 },
{"BusInterruptVector2", NULL, 0, COPY, 0, (PVOID) &BusInterruptVector2 },
{"InterruptMode2", NULL, 0, COPY, 0, (PVOID) &InterruptMode2 },
{"DmaChannel2", NULL, 0, COPY, 0, (PVOID) &DmaChannel2 },
{"DmaPort2", NULL, 0, COPY, 0, (PVOID) &DmaPort2 },
{"DmaWidth2", NULL, 0, COPY, 0, (PVOID) &DmaWidth2 },
{"DmaSpeed2", NULL, 0, COPY, 0, (PVOID) &DmaSpeed2 },
{"DeviceExtensionSize", NULL, 0, COPY, 0, (PVOID) &DeviceExtensionSize },
{"SpecificLuExtensionSize", NULL, 0, COPY, 0, (PVOID) &SpecificLuExtensionSize },
{"SrbExtensionSize", NULL, 0, COPY, 0, (PVOID) &SrbExtensionSize },
{"Dma64BitAddresses", NULL, 0, COPY, 0, (PVOID) &Dma64BitAddresses },
{"ResetTargetSupported", NULL, 0, COPY, 0, (PVOID) &ResetTargetSupported },
{"MaximumNumberOfLogicalUnits", NULL, 0, COPY, 0, (PVOID) &MaximumNumberOfLogicalUnits },
{"WmiDataProvider", NULL, 0, COPY, 0, (PVOID) &WmiDataProvider },
{"AccessRanges", NULL, 0, COPY, 0, (PVOID) &AccessRanges },
{"InitiatorBusId[0]", NULL, 0, DBG_DUMP_FIELD_RETURN_ADDRESS, 0, NULL },
};
SYM_DUMP_PARAM DevSym = {
sizeof (SYM_DUMP_PARAM),
"scsiport!_PORT_CONFIGURATION_INFORMATION",
DBG_DUMP_NO_PRINT,
PortConfigInfo,
NULL, NULL, NULL,
sizeof (deviceFields) / sizeof (FIELD_INFO),
&deviceFields[0]
};
if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) {
dprintf("Could not read _PORT_CONFIGURATION_INFORMATION @ %08p\n", PortConfigInfo);
return;
}
Fields = sizeof (deviceFields) / sizeof (FIELD_INFO);
InitiatorBusId = deviceFields[Fields-1].address;
xdprintfEx(Depth, ("PORT_CONFIGURATION_INFORMATION:\n"));
DumpUlongField("Length", Length, Depth);
DumpUlongField("SysIoBus", SystemIoBusNumber, Depth);
if (AdapterInterfaceType >= 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;
}