2402 lines
80 KiB
C
2402 lines
80 KiB
C
/*++
|
||
|
||
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;
|
||
}
|