windows-nt/Source/XPSP1/NT/base/tools/kdexts2/pcmcia.c
2020-09-26 16:20:57 +08:00

1168 lines
32 KiB
C
Raw 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) 1997 Microsoft Corporation
Module Name:
pcmcia.c
Abstract:
WinDbg Extension Api to dump PCMCIA driver structures.
This module references some routines & types defined
in devnode.c
Author:
Ravisankar Pudipeddi (ravisp) 1-Dec-1997
Neil Sandlin (neilsa) 1-June-1999
Environment:
User Mode.
--*/
#include "precomp.h"
#pragma hdrstop
#define FLAG_NAME(flag) {flag, #flag}
//
// Table of PCMCIA device extension flags
// update them from pcmcia.h
//
FLAG_NAME PcmciaDeviceFlags[] = {
FLAG_NAME(PCMCIA_DEVICE_STARTED),
FLAG_NAME(PCMCIA_DEVICE_LOGICALLY_REMOVED),
FLAG_NAME(PCMCIA_DEVICE_PHYSICALLY_REMOVED),
FLAG_NAME(PCMCIA_DEVICE_MULTIFUNCTION),
FLAG_NAME(PCMCIA_DEVICE_WAKE_PENDING),
FLAG_NAME(PCMCIA_DEVICE_LEGACY_DETECTED),
FLAG_NAME(PCMCIA_DEVICE_DELETED),
FLAG_NAME(PCMCIA_DEVICE_CARDBUS),
FLAG_NAME(PCMCIA_FILTER_ADDED_MEMORY),
FLAG_NAME(PCMCIA_MEMORY_24BIT),
FLAG_NAME(PCMCIA_CARDBUS_NOT_SUPPORTED),
FLAG_NAME(PCMCIA_USE_POLLED_CSC),
FLAG_NAME(PCMCIA_ATTRIBUTE_MEMORY_MAPPED),
FLAG_NAME(PCMCIA_SOCKET_REGISTER_BASE_MAPPED),
FLAG_NAME(PCMCIA_INTMODE_COMPAQ),
FLAG_NAME(PCMCIA_POWER_WORKER_POWERUP),
FLAG_NAME(PCMCIA_SOCKET_POWER_REQUESTED),
FLAG_NAME(PCMCIA_CONFIG_STATUS_DEFERRED),
FLAG_NAME(PCMCIA_POWER_STATUS_DEFERRED),
FLAG_NAME(PCMCIA_INT_ROUTE_INTERFACE),
{0,0}
};
//
// Table of PCMCIA socket structure flags
// update them from pcmcia.h
//
FLAG_NAME PcmciaSocketFlags[] = {
FLAG_NAME(SOCKET_CARD_IN_SOCKET),
FLAG_NAME(SOCKET_CARD_INITIALIZED),
FLAG_NAME(SOCKET_CARD_POWERED_UP),
FLAG_NAME(SOCKET_CARD_CONFIGURED),
FLAG_NAME(SOCKET_CARD_MULTIFUNCTION),
FLAG_NAME(SOCKET_CARD_CARDBUS),
FLAG_NAME(SOCKET_CARD_MEMORY),
FLAG_NAME(SOCKET_CHANGE_INTERRUPT),
FLAG_NAME(SOCKET_CUSTOM_INTERFACE),
FLAG_NAME(SOCKET_INSERTED_SOUND_PENDING),
FLAG_NAME(SOCKET_REMOVED_SOUND_PENDING),
FLAG_NAME(SOCKET_SUPPORT_MESSAGE_SENT),
FLAG_NAME(SOCKET_MEMORY_WINDOW_ENABLED),
FLAG_NAME(SOCKET_CARD_STATUS_CHANGE),
FLAG_NAME(SOCKET_POWER_STATUS_DEFERRED),
{0,0}
};
ENUM_NAME PcmciaControllerTypeEnum[] = {
ENUM_NAME(PcmciaIntelCompatible),
ENUM_NAME(PcmciaCardBusCompatible),
ENUM_NAME(PcmciaElcController),
ENUM_NAME(PcmciaDatabook),
ENUM_NAME(PcmciaPciPcmciaBridge),
ENUM_NAME(PcmciaCirrusLogic),
ENUM_NAME(PcmciaTI),
ENUM_NAME(PcmciaTopic),
ENUM_NAME(PcmciaRicoh),
ENUM_NAME(PcmciaDatabookCB),
ENUM_NAME(PcmciaOpti),
ENUM_NAME(PcmciaTrid),
ENUM_NAME(PcmciaO2Micro),
ENUM_NAME(PcmciaNEC),
ENUM_NAME(PcmciaNEC_98),
ENUM_NAME(PcmciaInvalidControllerType),
{0,0}
};
ENUM_NAME PcmciaSocketPowerWorkerStates[] = {
ENUM_NAME(SPW_Stopped),
ENUM_NAME(SPW_Exit),
ENUM_NAME(SPW_RequestPower),
ENUM_NAME(SPW_ReleasePower),
ENUM_NAME(SPW_SetPowerOn),
ENUM_NAME(SPW_SetPowerOff),
ENUM_NAME(SPW_ParentPowerUp),
ENUM_NAME(SPW_ParentPowerUpComplete),
{0,0}
};
ENUM_NAME PcmciaPdoPowerWorkerStates[] = {
ENUM_NAME(PPW_Stopped),
ENUM_NAME(PPW_Exit),
ENUM_NAME(PPW_InitialState),
ENUM_NAME(PPW_PowerUp),
ENUM_NAME(PPW_PowerUpComplete),
ENUM_NAME(PPW_PowerDown),
ENUM_NAME(PPW_PowerDownComplete),
ENUM_NAME(PPW_SendIrpDown),
ENUM_NAME(PPW_16BitConfigure),
ENUM_NAME(PPW_Deconfigure),
ENUM_NAME(PPW_VerifyCard),
ENUM_NAME(PPW_CardBusRefresh),
ENUM_NAME(PPW_CardBusDelay),
{0,0}
};
PUCHAR DeviceTypeTable[] = {
"Multifunction",
"Memory card",
"Serial",
"Parallel",
"ATA",
"Video",
"Network controller",
"AIMS",
"Scsi controller",
"Modem"
};
VOID
DumpEnum(
ULONG EnumVal,
PENUM_NAME EnumTable
)
/*++
Routine Description:
Prints the supplied enum value in a readable string format
by looking it up in the supplied enum table
Arguments:
EnumVal - Enum to be printed
EnumTable - Table in which the enum is looked up to find
the string to be printed
Return Value:
None
--*/
{
ULONG i;
for (i=0; EnumTable[i].Name != NULL; i++) {
if (EnumTable[i].EnumVal == EnumVal) {
break;
}
}
if (EnumTable[i].Name != NULL) {
dprintf("%s", EnumTable[i].Name);
} else {
dprintf("Unknown ");
}
return;
}
ULONG64
SocFld (ULONG64 Addr, PUCHAR Field) {
ULONG64 Temp;
GetFieldValue(Addr, "pcmcia!SOCKET", Field, Temp);
return Temp;
}
VOID
DumpSocket(ULONG64 Socket, ULONG Depth)
/*++
Routine Description
Dumps the socket structure
Arguments
Socket - Pointer to the socket structure
Depth - Indentation at which to print
Return Value
None
--*/
{
ULONG64 tmp;
dprintf("\n");
xdprintf(Depth,""); dprintf("NextSocket 0x%p\n", SocFld(Socket, "NextSocket"));
xdprintf(Depth,""); dprintf("SocketFnPtr 0x%p\n", SocFld(Socket, "SocketFnPtr"));
xdprintf(Depth,""); dprintf("Fdo devext 0x%p\n", SocFld(Socket, "DeviceExtension"));
xdprintf(Depth,""); dprintf("PdoList 0x%p\n", SocFld(Socket, "PdoList"));
DumpFlags(Depth, "Socket Flags", (ULONG) SocFld(Socket, "Flags"), PcmciaSocketFlags);
xdprintf(Depth,"Revision 0x%x\n", (ULONG) SocFld(Socket, "Revision"));
xdprintf(Depth,"SocketNumber 0x%x\n", (ULONG) SocFld(Socket, "SocketNumber"));
xdprintf(Depth,"NumberOfFunctions %d\n", (ULONG) SocFld(Socket, "NumberOfFunctions"));
xdprintf(Depth,"AddressPort 0x%x\n", (ULONG) SocFld(Socket, "AddressPort"));
xdprintf(Depth,"RegisterOffset 0x%x\n", (ULONG) SocFld(Socket, "RegisterOffset"));
xdprintf(Depth,"CBReg Base 0x%I64x size 0x%x\n",
SocFld(Socket, "CardBusSocketRegisterBase"),
SocFld(Socket, "CardBusSocketRegisterSize"));
xdprintf(Depth,"CisCache 0x%x\n", (ULONG) SocFld(Socket, "CisCache"));
if (tmp = SocFld(Socket, "PciDeviceRelations")) {
xdprintf(Depth,"PciDeviceRelations 0x%p\n", tmp);
}
xdprintf(Depth,"PowerRequests %d\n", (ULONG) SocFld(Socket, "PowerRequests"));
xdprintf(Depth,"PowerWorker State: ");
DumpEnum((ULONG) SocFld(Socket, "WorkerState"), PcmciaSocketPowerWorkerStates);
dprintf("\n");
if (SocFld(Socket, "WorkerState") != SPW_Stopped) {
xdprintf(Depth," Worker Phase %d\n", (ULONG) SocFld(Socket, "WorkerPhase"));
xdprintf(Depth," PowerData 0x%x\n", (ULONG) SocFld(Socket, "PowerData"));
xdprintf(Depth,""); dprintf(" PowerCompletionRoutine 0x%p\n", SocFld(Socket, "PowerCompletionRoutine"));
xdprintf(Depth,""); dprintf(" PowerCompletionContext 0x%p\n", SocFld(Socket, "PowerCompletionContext"));
xdprintf(Depth," CallerStatus 0x%x\n", (ULONG) SocFld(Socket, "CallerStatus"));
xdprintf(Depth," DeferredStatus 0x%x\n", (ULONG) SocFld(Socket, "DeferredStatus"));
xdprintf(Depth," DeferredPowerRequests 0x%x\n", (ULONG) SocFld(Socket, "DeferredPowerRequests"));
}
dprintf("\n");
return;
}
VOID
DumpDevicePowerState(IN DEVICE_POWER_STATE PowerState)
/*++
Routine Description
Converts the supplied enum device power state to a
string & dumps it.
Arguments
PowerState - Device power state
Return Value
None
--*/
{
dprintf(" DevicePowerState: ");
switch (PowerState) {
case PowerDeviceUnspecified: {
dprintf("PowerDeviceUnspecfied\n");
break;
}
case PowerDeviceD0: {
dprintf("PowerDeviceD0\n");
break;
}
case PowerDeviceD1: {
dprintf("PowerDeviceD1\n");
break;
}
case PowerDeviceD2: {
dprintf("PowerDeviceD2\n");
break;
}
case PowerDeviceD3: {
dprintf("PowerDeviceD3\n");
break;
}
default:
dprintf("???\n");
}
}
VOID
DumpSystemPowerState(IN SYSTEM_POWER_STATE PowerState)
/*++
Routine Description
Converts the supplied enum system power state to a
string & dumps it.
Arguments
PowerState - System power state
Return Value
None
--*/
{
dprintf(" SystemPowerState: ");
switch (PowerState) {
case PowerSystemUnspecified: {
dprintf("PowerSystemUnspecfied\n");
break;
}
case PowerSystemWorking:{
dprintf("PowerSystemWorking\n");
break;
}
case PowerSystemSleeping1: {
dprintf("PowerSystemSleeping1\n");
break;
}
case PowerSystemSleeping2: {
dprintf("PowerSystemSleeping2\n");
break;
}
case PowerSystemSleeping3: {
dprintf("PowerSystemSleeping3\n");
break;
}
case PowerSystemHibernate: {
dprintf("PowerSystemHibernate\n");
break;
}
case PowerSystemShutdown: {
dprintf("PowerSystemShutdown\n");
break;
}
default:
dprintf("???\n");
}
}
ULONG64
ConfigFld (ULONG64 Addr, PUCHAR Field) {
ULONG64 Temp;
GetFieldValue(Addr, "pcmcia!SOCKET_CONFIGURATION", Field, Temp);
return Temp;
}
VOID
DumpSocketConfiguration(ULONG64 Config, ULONG Depth)
/*++
Routine Description
Dumps the current configuration of the socket
Arguments
Config - Pointer to the current configuration for the socket
Depth - Indentation at which to print
Return Value
None
--*/
{
ULONG i;
ULONG NumberOfIoPortRanges, NumberOfMemoryRanges;
CHAR Buffer[40], Buffer2[40], Buffer3[40];
xdprintf(Depth, "Irq 0x%x\n", (ULONG) ConfigFld(Config, "Irq"));
xdprintf(Depth, "ReadyIrq 0x%x\n", (ULONG) ConfigFld(Config, "ReadyIrq"));
if ((NumberOfIoPortRanges = (ULONG) ConfigFld(Config, "NumberOfIoPortRanges")) > 0) {
xdprintf(Depth,
"%x I/O range(s) configured, %s: ",
NumberOfIoPortRanges,
(ConfigFld(Config, "Io16BitAccess") ? "16-bit access" : "8-bit access"));
for (i = 0; i < NumberOfIoPortRanges; i++) {
if (CheckControlC()) {
break;
}
sprintf(Buffer, "IoPortBase[%d]", i);
sprintf(Buffer2, "IoPortLength[%d]", i);
xdprintf(Depth+1, "Base 0x%x, length 0x%x\n",
(ULONG) ConfigFld(Config, Buffer), (ULONG) ConfigFld(Config, Buffer2) +1);
}
}
if ((NumberOfMemoryRanges = (ULONG) ConfigFld(Config, "NumberOfMemoryRanges")) > 0) {
xdprintf(Depth, "%x memory range(s) configured", NumberOfMemoryRanges);
if (ConfigFld(Config, "Mem16BitAccess")) {
dprintf(", 16-bit access");
} else {
dprintf(", 8-bit access");
}
dprintf(":\n");
for (i = 0; i < NumberOfMemoryRanges; i++) {
if (CheckControlC()) {
break;
}
sprintf(Buffer, "MemoryHostBase[%d]", i);
sprintf(Buffer2, "MemoryCardBase[%d]", i);
sprintf(Buffer3, "MemoryLength[%d]", i);
xdprintf(Depth+1,"Host base 0x%x, card base 0x%x, length 0x%x\n",
(ULONG) ConfigFld(Config, Buffer), (ULONG) ConfigFld(Config, Buffer2),
(ULONG) ConfigFld(Config, Buffer3));
}
}
}
VOID
DumpIrqMask(ULONG IrqMask)
/*++
Routine Description
Dumps IRQ values as specified by the supplied mask.
Arguments
IrqMask - Values correspoinging to bits set to 1 in this mask are dumped:
the value of a bit is 0-based, counted from LSB to MSB
Return Value
None
--*/
{
ULONG temp, index, count;
temp = 1;
index = 0;
count = 0;
while (temp) {
if (temp & IrqMask) {
if (count > 0) {
//
// Print trailing comma
//
dprintf(",");
}
dprintf("%x", index);
count++;
}
temp <<= 1; index++;
}
dprintf("\n");
}
ULONG64
EntryFld (ULONG64 Addr, PUCHAR Field) {
ULONG64 Temp;
GetFieldValue(Addr, "pcmcia!CONFIG_ENTRY", Field, Temp);
return Temp;
}
VOID
DumpConfigEntry(ULONG64 Config, ULONG Depth)
/*++
Routine Description
Dumps a single "config entry", i.e. the encapsulation of a
CISTPL_CONFIG_ENTRY tuple on a pc-card
Arguments
Config - Pointer to the config entry
Depth - Indentation at which to print
Return Value
None
--*/
{
ULONG i;
ULONG NumberOfIoPortRanges, NumberOfMemoryRanges, IrqMask;
CHAR buffer[40], buffer2[40], buffer3[40];
if (EntryFld(Config, "Flags") & PCMCIA_INVALID_CONFIGURATION) {
xdprintf(Depth, "**This is an invalid configuration**\n");
}
xdprintf(Depth, "Index: 0x%x\n", (ULONG) EntryFld(Config, "IndexForThisConfiguration"));
if ((NumberOfIoPortRanges = (ULONG) EntryFld(Config, "NumberOfIoPortRanges")) > 0) {
for (i = 0; i < NumberOfIoPortRanges; i++) {
ULONG IoPortBase;
if (CheckControlC()) {
break;
}
sprintf(buffer,"IoPortBase[%d]",i);
sprintf(buffer2,"IoPortLength[%d]",i);
sprintf(buffer3,"IoPortAlignment[%d]",i);
if ((IoPortBase = (ULONG) EntryFld(Config, buffer)) == 0) {
xdprintf(Depth,"I/O Any range of ");
} else {
xdprintf(Depth,"I/O Base 0x%x, ", IoPortBase);
}
dprintf("length 0x%x, alignment 0x%x, ",
(ULONG) EntryFld(Config, buffer2)+1,
(ULONG) EntryFld(Config, buffer3));
if (EntryFld(Config, "Io16BitAccess") && EntryFld(Config, "Io8BitAccess")) {
dprintf("16/8-bit access");
} else if (EntryFld(Config, "Io16BitAccess")) {
dprintf("16-bit access");
} else if (EntryFld(Config, "Io8BitAccess")) {
dprintf("8-bit access");
}
dprintf("\n");
}
}
if ((NumberOfMemoryRanges = (ULONG) EntryFld(Config, "NumberOfMemoryRanges")) > 0) {
for (i = 0; i < NumberOfMemoryRanges; i++) {
if (CheckControlC()) {
break;
}
sprintf(buffer,"MemoryHostBase[%d]",i);
sprintf(buffer2,"MemoryCardBase[%d]",i);
sprintf(buffer3,"MemoryLength[%d]",i);
xdprintf(Depth,"MEM Host base 0x%x, card base 0x%x, len 0x%x\n",
(ULONG) EntryFld(Config, buffer),
(ULONG) EntryFld(Config, buffer2),
(ULONG) EntryFld(Config, buffer3));
}
}
if ((IrqMask = (ULONG) EntryFld(Config, "IrqMask")) != 0) {
xdprintf(Depth,"IRQ - one of: ", IrqMask);
DumpIrqMask(IrqMask);
}
//
// Have to dump level/share disposition information some time..
//
}
VOID
DumpPcCardType(UCHAR Type,
ULONG Depth)
/*++
Routine Description
Prints the device type of the pc-card
Arguments
Type - Device type value
Depth - Indentation
Return value
None
--*/
{
PUCHAR s;
xdprintf(Depth,"Device type: ");
//
// Type should be <= number of DeviceTypeTable entries - 1
//
if ((ULONG) Type >= sizeof(DeviceTypeTable)) {
dprintf("Unknown\n");
} else {
dprintf("%s\n", DeviceTypeTable[(ULONG) Type]);
}
}
VOID
DumpConfigEntryChain(ULONG64 ConfigEntryChain,
ULONG Depth)
/*++
Routine Description
Dumps the chain of config entries
Arguments
ConfigEntryChain - pointer to head of config entry list
Depth - indentation
--*/
{
ULONG64 ce;
ce = ConfigEntryChain;
while (ce != 0) {
if (CheckControlC()) {
break;
}
xdprintf(Depth, ""); dprintf("ConfigEntry: 0x%p\n", ce);
if (!GetFieldValue(ce, "pcmcia!CONFIG_ENTRY", "NextEntry", ConfigEntryChain)) {
DumpConfigEntry(ce, Depth+1);
ce = ConfigEntryChain;
} else {
ce = 0;
}
}
}
ULONG64
SocDataFld (ULONG64 Addr, PUCHAR Field) {
ULONG64 Temp;
GetFieldValue(Addr, "pcmcia!SOCKET_DATA", Field, Temp);
return Temp;
}
VOID
DumpSocketData(ULONG64 SocketData, ULONG Depth)
/*++
Routine Description
Dumps the socket data structure hanging off the device extension
for a pc-card pdo, which describes in entirety the pc-card, it's
resource/power requirements etc.
Arguments
SocketData - Pointer to the socket data structure
Depth - Indentation at which to print
Return Value
None
--*/
{
ULONG d;
CHAR Mfg[80]={0}, Ident[80]={0};
ULONG64 DefaultConfiguration;
xdprintf(Depth, "");
dprintf("NextSocketData 0x%p PrevSocketData 0x%p\n",
SocDataFld(SocketData, "Next"), SocDataFld(SocketData, "Prev"));
xdprintf(Depth, ""); dprintf("PdoExtension 0x%p\n", SocDataFld(SocketData, "PdoExtension"));
GetFieldValue(SocketData, "pcmcia!SOCKET_DATA", "Mfg", Mfg);
GetFieldValue(SocketData, "pcmcia!SOCKET_DATA", "Ident", Ident);
xdprintf(Depth, "Manufacturer: %s Identifier: %s\n", Mfg, Ident);
DumpPcCardType((UCHAR) SocDataFld(SocketData, "DeviceType"), Depth);
xdprintf(Depth,"CisCrc: 0x%X LastEntryInCardConfig: 0x%x\n",
(ULONG) SocDataFld(SocketData, "CisCrc"), (ULONG) SocDataFld(SocketData, "LastEntryInCardConfig"));
xdprintf(Depth, "Manufacturer Code: 0x%x Info: 0x%x\n",
(ULONG) SocDataFld(SocketData, "ManufacturerCode"),
(ULONG) SocDataFld(SocketData, "ManufacturerInfo"));
xdprintf(Depth, "Config Register Base: 0x%I64x\n", SocDataFld(SocketData, "ConfigRegisterBase"));
//
// Dump all the config entries hanging off this socket's pc-card
//
DumpConfigEntryChain(SocDataFld(SocketData, "ConfigEntryChain"), Depth);
xdprintf(Depth, ""); dprintf("Default Configuration: 0x%p\n",
(DefaultConfiguration = SocDataFld(SocketData, "DefaultConfiguration")));
if (DefaultConfiguration != 0) {
DumpConfigEntry(DefaultConfiguration, Depth+1);
}
xdprintf(Depth,"Vcc: 0x%x Vpp1: 0x%x Vpp2 0x%x\n",
(ULONG) SocDataFld(SocketData, "Vcc"),
(ULONG) SocDataFld(SocketData, "Vpp1"),
(ULONG) SocDataFld(SocketData, "Vpp2"));
xdprintf(Depth,"Audio: 0x%x RegistersPresentMask 0x%x\n",
(ULONG) SocDataFld(SocketData, "Audio"),
(ULONG) SocDataFld(SocketData, "RegistersPresentMask"));
xdprintf(Depth, "ConfigIndex used for current card configuration: 0x%x\n",
(ULONG) SocDataFld(SocketData, "ConfigIndexUsed"));
xdprintf(Depth, "Function number (in a multifunc. card): 0x%x\n",
(ULONG) SocDataFld(SocketData, "Function"));
xdprintf(Depth, "Instance number: 0x%x\n", (ULONG) SocDataFld(SocketData, "Instance"));
xdprintf(Depth, "Mf ResourceMap: irq index %x.%x, i/o index %x.%x, mem index %x.%x\n",
(ULONG) SocDataFld(SocketData, "MfIrqResourceMapIndex"),
(ULONG) SocDataFld(SocketData, "MfNeedsIrq"),
(ULONG) SocDataFld(SocketData, "MfIoPortResourceMapIndex"),
(ULONG) SocDataFld(SocketData, "MfIoPortCount"),
(ULONG) SocDataFld(SocketData, "MfMemoryResourceMapIndex"),
(ULONG) SocDataFld(SocketData, "MfMemoryCount"));
}
ULONG64
PDOxFld (ULONG64 Addr, PUCHAR Field) {
ULONG64 Temp;
GetFieldValue(Addr, "pcmcia!PDO_EXTENSION", Field, Temp);
return Temp;
}
ULONG64
FDOxFld (ULONG64 Addr, PUCHAR Field) {
ULONG64 Temp;
GetFieldValue(Addr, "pcmcia!FDO_EXTENSION", Field, Temp);
return Temp;
}
VOID
DevExtPcmcia(
ULONG64 Extension
)
/*++
Routine Description:
Dump a PCMCIA Device extension.
Arguments:
Extension Address of the extension to be dumped.
Return Value:
None.
--*/
{
ULONG64 DeviceObject=0;
ULONG64 socketDataPtr;
ULONG Flags, depth;
if (!ReadPointer(Extension, &DeviceObject)) {
dprintf(
"Failed to read PCMCIA extension at %08p, giving up.\n",
Extension
);
return;
}
if (GetFieldValue(DeviceObject, "nt!_DEVICE_OBJECT", "Flags", Flags)) {
return;
}
if (Flags & DO_BUS_ENUMERATED_DEVICE) {
//
// This is the extension for a PC-Card PDO
//
ULONG64 socketPtr, Capabilities;
ULONG64 DeviceId;
UCHAR deviceId[PCMCIA_MAXIMUM_DEVICE_ID_LENGTH];
if (GetFieldValue(Extension, "pcmcia!PDO_EXTENSION", "DeviceId", DeviceId)) {
return;
}
dprintf("PDO Extension, Device Object 0x%p\n",PDOxFld(Extension, "DeviceObject"));
DumpFlags(0, " Device Flags", (ULONG) PDOxFld(Extension, "Flags"), PcmciaDeviceFlags);
dprintf(" NextPdo 0x%p LowerDevice 0x%p PciPdo 0x%p\n",
PDOxFld(Extension, "NextPdoInFdoChain"),
PDOxFld(Extension, "LowerDevice"),
PDOxFld(Extension, "PciPdo"));
dprintf(" DeviceId 0x%p: ", DeviceId);
if (DeviceId != 0) {
ULONG status;
ReadMemory(DeviceId, deviceId, PCMCIA_MAXIMUM_DEVICE_ID_LENGTH, &status);
dprintf("%s", deviceId);
}
dprintf("\n");
dprintf(" Socket: 0x%x\n", PDOxFld(Extension, "Socket"));
socketDataPtr = PDOxFld(Extension, "SocketData");
while (socketDataPtr != 0) {
//
// Dump socket data structure
//
dprintf(" SocketData 0x%x\n", socketDataPtr);
DumpSocketData(socketDataPtr, 2);
socketDataPtr = SocDataFld(socketDataPtr, "Next");
}
DumpDevicePowerState((ULONG) PDOxFld(Extension, "DevicePowerState"));
DumpSystemPowerState((ULONG) PDOxFld(Extension, "SystemPowerState"));
dprintf(" WaitWakeIrp 0x%p\n", PDOxFld(Extension, "WaitWakeIrp"));
dprintf(" PendingPowerIrp 0x%p\n", PDOxFld(Extension, "PendingPowerIrp"));
dprintf(" DeviceCapabilities (at 0x%p): \n", (Capabilities = PDOxFld(Extension, "Capabilities")));
if (Capabilities != 0) {
DumpDeviceCapabilities(Capabilities);
}
dprintf(" ConfigurationPhase: %d\n", (ULONG) PDOxFld(Extension, "ConfigurationPhase"));
dprintf(" PowerWorker State: ");
DumpEnum((ULONG) PDOxFld(Extension, "PowerWorkerState"), PcmciaPdoPowerWorkerStates);
dprintf("\n");
if ((ULONG) PDOxFld(Extension, "PowerWorkerState") != PPW_Stopped) {
dprintf(" Worker Phase %d\n", (ULONG) PDOxFld(Extension, "PowerWorkerPhase"));
dprintf(" Worker Sequence 0x%x\n", (ULONG) PDOxFld(Extension, "PowerWorkerSequence"));
}
} else {
//
// This is the extension for the pcmcia controller FDO
//
ULONG64 addr, PdoList, NextFdo, Capabilities;
ULONG depth;
ULONG model, revision;
ULONG ControllerType, off;
if (GetFieldValue(Extension, "pcmcia!FDO_EXTENSION", "PdoList", PdoList)) {
return;
}
dprintf("FDO Extension, Device Object 0x%p\n", FDOxFld(Extension, "DeviceObject"));
dprintf(" DriverObject 0x%p, RegistryPath 0x%p\n",
FDOxFld(Extension, "DriverObject"), FDOxFld(Extension, "RegistryPath"));
DumpFlags(0, " Device Flags", (ULONG) FDOxFld(Extension, "Flags"), PcmciaDeviceFlags);
dprintf(" ControllerType (%x): ", (ControllerType = (ULONG) FDOxFld(Extension, "ControllerType")));
DumpEnum(PcmciaClassFromControllerType(ControllerType), PcmciaControllerTypeEnum);
if (model = PcmciaModelFromControllerType(ControllerType)) {
dprintf("%d", model);
}
if (revision = PcmciaRevisionFromControllerType(ControllerType)) {
dprintf(", rev(%d)", revision);
}
dprintf("\n");
dprintf(" Child PdoList head 0x%p ", PdoList);
GetFieldOffset("nt!_DEVICE_OBJECT","DeviceExtension", &off);
if ((PdoList != 0) &&
ReadPointer( PdoList + off ,
&addr)) {
dprintf("device extension 0x%p\n", addr);
} else {
dprintf("\n");
}
dprintf(" LivePdoCount 0x%x\n", (ULONG) FDOxFld(Extension, "LivePdoCount"));
dprintf(" NextFdo 0x%p ", (NextFdo = FDOxFld(Extension, "NextFdo")));
if ((NextFdo != 0) &&
ReadPointer(NextFdo + off,
&addr)) {
dprintf("device extension 0x%p\n", addr);
} else {
dprintf("\n");
}
dprintf(" Pdo (for this fdo) 0x%p\n", FDOxFld(Extension, "Pdo"));
dprintf(" LowerDevice 0x%p\n", FDOxFld(Extension, "LowerDevice"));
dprintf(" SocketList 0x%p\n", FDOxFld(Extension, "SocketList"));
dprintf(" IRQ mask 0x%x allows IRQs: ", (ULONG) FDOxFld(Extension, "AllocatedIrqMask"));
DumpIrqMask((ULONG) FDOxFld(Extension, "AllocatedIrqMask"));
dprintf(" Memory window physical address 0x%p\n", FDOxFld(Extension, "PhysicalBase"));
dprintf(" Memory window virtual address 0x%p\n", FDOxFld(Extension, "AttributeMemoryBase"));
dprintf(" Memory window size 0x%x\n", (ULONG) FDOxFld(Extension, "AttributeMemorySize"));
dprintf(" DeviceDispatchIndex %x\n", (ULONG) FDOxFld(Extension, "DeviceDispatchIndex"));
dprintf(" PCCard Ready Delay Iterations 0x%x (%d)\n",
(ULONG) FDOxFld(Extension, "ReadyDelayIter"), (ULONG) FDOxFld(Extension, "ReadyDelayIter"));
dprintf(" PCCard Ready Stall in usecs 0x%x (%d)\n",
(ULONG) FDOxFld(Extension, "ReadyStall"), (ULONG) FDOxFld(Extension, "ReadyStall"));
dprintf(" Number of sockets powered up %d\n",
(ULONG) FDOxFld(Extension, "NumberOfSocketsPoweredUp"));
DumpDevicePowerState((ULONG) FDOxFld(Extension, "DevicePowerState"));
DumpSystemPowerState((ULONG) FDOxFld(Extension, "SystemPowerState"));
//
// Pending wait wake irp
//
dprintf(" WaitWakeIrp: %p\n", FDOxFld(Extension, "WaitWakeIrp"));
//
// Dump saved register context
//
dprintf(" PCI Context range, buffer: %p(%d), %p\n",
FDOxFld(Extension, "PciContext.Range"), (ULONG) FDOxFld(Extension, "PciContext.RangeCount"),
FDOxFld(Extension, "PciContextBuffer"));
dprintf(" Cardbus Context range: %p(%d)\n",
FDOxFld(Extension, "CardbusContext.Range"), (ULONG) FDOxFld(Extension, "CardbusContext.RangeCount"));
dprintf(" Exca Context range: %p(%d)\n",
FDOxFld(Extension, "ExcaContext.Range"), (ULONG) FDOxFld(Extension, "ExcaContext.RangeCount"));
//
// Dump capabilities
//
dprintf(" DeviceCapabilities (at 0x%p): \n", (Capabilities = FDOxFld(Extension, "Capabilities")));
if (Capabilities != 0) {
DumpDeviceCapabilities(Capabilities);
}
}
}
DECLARE_API( socket )
/*++
Routine Description:
Dump a socket
Arguments:
args - the location of the socket to dump
Return Value:
None
--*/
{
ULONG64 socketAddr=0;
ULONG depth, status;
socketAddr = GetExpression(args);
if (ReadMemory(socketAddr, &depth, sizeof(depth), &status)) {
dprintf("Socket at %p:\n", socketAddr);
DumpSocket(socketAddr, 0);
} else {
dprintf("Could not read socket at %p\n", socketAddr);
}
return S_OK;
}
VOID
DumpFlagsBrief(ULONG Flags)
{
if (Flags & PCMCIA_DEVICE_STARTED) {
dprintf(" ST");
} else {
dprintf(" NS");
}
if (Flags & PCMCIA_DEVICE_LOGICALLY_REMOVED) {
dprintf(" RM");
}
if (Flags & PCMCIA_DEVICE_PHYSICALLY_REMOVED) {
dprintf(" EJ");
}
if (Flags & PCMCIA_DEVICE_DELETED) {
dprintf(" DL");
}
if (Flags & PCMCIA_DEVICE_MULTIFUNCTION) {
dprintf(" MF");
}
if (Flags & PCMCIA_DEVICE_WAKE_PENDING) {
dprintf(" WP");
}
if (Flags & PCMCIA_DEVICE_LEGACY_DETECTED) {
dprintf(" LD");
}
if (Flags & PCMCIA_DEVICE_CARDBUS) {
dprintf(" CB");
}
}
DECLARE_API( pcmcia )
/*++
Routine Description:
Dumps overview of pcmcia driver state
Arguments:
args - the location of the socket to dump
Return Value:
None
--*/
{
ULONG64 addr;
ULONG64 fdoDevObj, pdoDevObj, pSocket;
ULONG64 Extension;
ULONG Count = 0, off;
UCHAR deviceId[PCMCIA_MAXIMUM_DEVICE_ID_LENGTH];
if (args[0] != '\0') {
dprintf("!pcmcia - dumps general pcmcia driver state\n\n");
dprintf("flag descriptions:\n");
dprintf(" ST - Started\n");
dprintf(" NS - Not Started\n");
dprintf(" RM - Logically Removed\n");
dprintf(" EJ - Physically Ejected\n");
dprintf(" DL - Deleted\n");
dprintf(" MF - MultiFunction\n");
dprintf(" WP - Wake Pending\n");
dprintf(" LD - Legacy Detected\n");
dprintf(" CB - CardBus\n");
}
addr = GetExpression( "pcmcia!fdolist" );
if (addr == 0) {
dprintf("Error retrieving address of pcmcia!fdolist\n");
return E_INVALIDARG;
}
if (!ReadPointer(addr, &fdoDevObj)) {
dprintf("Failed to read fdolist at %08p, giving up.\n", addr);
return E_INVALIDARG;
}
GetFieldOffset("nt!_DEVICE_OBJECT", "DeviceExtension", &off);
while(fdoDevObj) {
ULONG64 NextFdo;
ULONG64 CbReg;
if (CheckControlC()) {
break;
}
if (!ReadPointer(fdoDevObj+off,&Extension)) {
dprintf("Failed to read fdo extension address at %08p, giving up.\n", fdoDevObj+off);
return E_INVALIDARG;
}
if (GetFieldValue(Extension, "pcmcia!FDO_EXTENSION", "NextFdo", NextFdo)) {
dprintf("GetFieldValue failed for fdo extension at %08p, giving up.\n", Extension);
return E_INVALIDARG;
}
dprintf("\nFDO %.8p ext %.8p\n", fdoDevObj, Extension);
if (GetFieldValue(Extension, "pcmcia!FDO_EXTENSION", "CardBusSocketRegisterBase", CbReg)) {
dprintf("GetFieldValue failed for fdo extension at %08p, giving up.\n", Extension);
return E_INVALIDARG;
}
if (CbReg) {
dprintf(" CbReg %.8p\n\n", CbReg);
} else {
dprintf("\n");
}
//
// Print list of PDOs enumerated by this FDO
//
pdoDevObj = FDOxFld(Extension, "PdoList");
pSocket = FDOxFld(Extension, "SocketList");
if (!pdoDevObj) {
xdprintf(2, "*no PDO's enumerated*\n");
} else {
xdprintf(2, "pdolist:");
}
while(pdoDevObj) {
if (CheckControlC()) {
break;
}
if (!ReadPointer(pdoDevObj+off,&Extension)) {
return E_INVALIDARG;
}
dprintf(" %.8p", pdoDevObj);
pdoDevObj = PDOxFld(Extension, "NextPdoInFdoChain");
}
dprintf("\n");
//
// Print list of sockets
//
if (!pSocket) {
xdprintf(2, "*no sockets!*\n");
}
while(pSocket) {
ULONG64 NextSocket;
ULONG SocketNumber;
if (CheckControlC()) {
break;
}
if (GetFieldValue(pSocket, "pcmcia!SOCKET", "NextSocket", NextSocket)) {
return E_INVALIDARG;
}
dprintf(" Socket %.8p\n", pSocket);
dprintf(" base %.8p", SocFld(pSocket, "AddressPort"));
if (SocketNumber = (ULONG) SocFld(pSocket, "SocketNumber")) {
dprintf(".%d", SocketNumber);
}
dprintf("\n");
//
// Dump pdo's in socket list
//
pdoDevObj = SocFld(pSocket, "PdoList");
if (!pdoDevObj) {
xdprintf(3, "*empty*\n");
}
while(pdoDevObj) {
ULONG64 DeviceId;
ULONG status;
if (CheckControlC()) {
break;
}
if (!ReadPointer(pdoDevObj + off,&Extension)) {
return E_INVALIDARG;
}
if (GetFieldValue(Extension, "pcmcia!PDO_EXTENSION", "DeviceId", DeviceId)) {
return E_INVALIDARG;
}
dprintf(" PDO %.8p ext %.8p", pdoDevObj, Extension);
DumpFlagsBrief((ULONG) PDOxFld(Extension, "Flags"));
dprintf("\n");
if (DeviceId != 0) {
ReadMemory(DeviceId, deviceId, PCMCIA_MAXIMUM_DEVICE_ID_LENGTH, &status);
dprintf(" %s\n", deviceId);
}
pdoDevObj = PDOxFld(Extension, "NextPdoInSocket");
}
pSocket = NextSocket;
}
fdoDevObj = NextFdo;
}
return S_OK;
}