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

866 lines
23 KiB
C

/*++
Copyright (C) Microsoft Corporation, 1999 - 1999
Module Name:
sbp2kdx.c
Abstract
Kernel debugger extension dll for sbp2port.sys (1394 sbp2 protocol driver)
Author:
Dan Knudson (dankn) 25 Jun 1999
Revision History:
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <stdio.h>
#include <stdlib.h>
#include <ntverp.h>
#include <windows.h>
#include <ntosp.h>
#include <wdbgexts.h>
#include <sbp2port.h>
//
// Utility routine prototypes
//
void
DisplayAddressContext(
char *Name,
PADDRESS_CONTEXT Context,
char *Indent
);
void
DisplayAsyncContextFlags(
ULONG Flags
);
void
DisplayDeviceFlags(
ULONG Flags
);
void
DisplayDeviceInformation(
PDEVICE_INFORMATION Info,
ULONG Index
);
void
DisplayLeaf(
char *Name,
PTEXTUAL_LEAF Leaf,
char *Indent
);
void
DisplayStatusFifoBlock(
char *Name,
PSTATUS_FIFO_BLOCK Block
);
//
// Global variables
//
char Indent0[] = "", Indent1[] = " ", Indent2[] = " ";
EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER, 0 };
WINDBG_EXTENSION_APIS ExtensionApis;
USHORT SavedMajorVersion;
USHORT SavedMinorVersion;
BOOLEAN Verbose, OrbFields;
char *Help[] =
{
"\n",
" *** SBP2PORT.SYS Debugger Extensions ***\n\n",
"Command Displays...\n",
"---------------------------------------------------------------\n",
"arc <addr> async request context\n",
"fdoext <fdo> [-v] fdo device extension (-v = verbose)\n",
"help this\n",
"pdoext <pdo> [-v] [-o] pdo device extension (-o = Orb fields)\n\n",
"NOTE: ' !devnode 0 1 ohci1394 ' shows the pdo device stack\n",
"NOTE: pdoext.BusFdo shows the fdo address\n",
"\n",
NULL
};
BOOL
WINAPI
DLLMain(
HINSTANCE hInstance,
ULONG ulReason,
LPVOID pvReserved
)
{
return (TRUE);
}
void
WinDbgExtensionDllInit(
PWINDBG_EXTENSION_APIS pExtensionApis,
USHORT MajorVersion,
USHORT MinorVersion
)
{
ExtensionApis = *pExtensionApis;
SavedMajorVersion = MajorVersion;
SavedMinorVersion = MinorVersion;
return;
}
void
CheckVersion(
void
)
{
// no-op?
}
LPEXT_API_VERSION
ExtensionApiVersion(
void
)
{
return (&ApiVersion);
}
DECLARE_API(arc)
{
ULONG bytesRead;
ULONG_PTR p;
ASYNC_REQUEST_CONTEXT context, *pcontext;
dprintf ("\n");
if (args[0] == 0)
{
dprintf ("usage: arc <address> \n\n");
return;
}
sscanf (args, "%lx", &p);
if (!ReadMemory (p, &context, sizeof (context), &bytesRead))
{
dprintf ("Unable to read context\n\n");
return;
}
if (bytesRead < sizeof (context))
{
dprintf(
"Only read %d bytes of context, expected %d\n\n",
bytesRead,
sizeof (context)
);
return;
}
OrbFields = TRUE; // so address context below will get displayed
// BUGUG validation? like : if (context.Tag != SBP2_ASYNC_CONTEXT_TAG)
pcontext = (PASYNC_REQUEST_CONTEXT) p;
dprintf ("&OrbList = x%p\n", &pcontext->OrbList);
dprintf (" Flink = x%p\n", context.OrbList.Flink);
dprintf (" Blink = x%p\n", context.OrbList.Blink);
dprintf ("&LookasideList = x%p\n", &pcontext->LookasideList);
dprintf (" Next = x%p\n", context.LookasideList.Next);
dprintf ("Tag = x%x\n", context.Tag);
dprintf ("DeviceObject = x%p\n", context.DeviceObject);
dprintf ("Srb = x%p\n", context.Srb);
DisplayAsyncContextFlags (context.Flags);
dprintf ("CmdOrb = x%p\n", context.CmdOrb);
dprintf ("CmdOrbAddress = x%x%08x\n", context.CmdOrbAddress.u.HighQuad, context.CmdOrbAddress.u.LowQuad);
dprintf ("PartialMdl = x%p\n", context.PartialMdl);
dprintf ("RequestMdl = x%p\n", context.RequestMdl);
dprintf ("PageTableContext\n");
dprintf (" MaxPages = x%x\n", context.PageTableContext.MaxPages);
dprintf (" NumberOfPages = x%x\n", context.PageTableContext.NumberOfPages);
dprintf (" PageTable = x%p\n", context.PageTableContext.PageTable);
DisplayAddressContext (" AddressContext\n", &context.PageTableContext.AddressContext, Indent2);
dprintf ("DataMappingHandle = x%p\n", context.DataMappingHandle);
dprintf ("Packet = x%p\n", context.Packet);
dprintf ("\n");
}
DECLARE_API(fdoext)
{
ULONG bytesRead, i;
ULONG_PTR p;
DEVICE_OBJECT obj;
FDO_DEVICE_EXTENSION ext;
dprintf ("\n");
//
// Get the fdo pointer & any args from the cmd line
//
if (args[0] == 0)
{
dprintf ("usage: fdoext <fdo address> [-v]\n\n");
return;
}
sscanf (args, "%lx", &p);
Verbose = (BOOLEAN) strstr (args, "-v");
//
// Read the DEVICE_OBJECT to retrieve the device extension pointer
//
if (!ReadMemory (p, &obj, sizeof (obj), &bytesRead))
{
dprintf ("Unable to read pdo\n\n");
return;
}
if (bytesRead < sizeof (obj))
{
dprintf(
"Only read %d bytes of pdo, expected %d\n\n",
bytesRead,
sizeof (obj)
);
return;
}
p = (ULONG_PTR) obj.DeviceExtension;
//
// Read the device extension
//
if (!ReadMemory (p, &ext, sizeof (ext), &bytesRead))
{
dprintf ("Unable to read pdo extension\n\n");
return;
}
if (bytesRead < sizeof (ext))
{
dprintf(
"Only read %d bytes of fdo extension, expected %d\n\n",
bytesRead,
sizeof (ext)
);
return;
}
if (ext.Type != SBP2_FDO)
{
dprintf ("Not a fdo extension (ext.Type=x%x)\n\n", ext.Type);
return;
}
//
// Display the extension fields
//
dprintf ("DeviceObject = x%p\n", ext.DeviceObject);
dprintf ("LowerDeviceObject = x%p\n", ext.LowerDeviceObject);
DisplayDeviceFlags (ext.DeviceFlags);
dprintf ("ConfigRom\n");
dprintf (" CR_Info = x%x\n", ext.ConfigRom.CR_Info);
dprintf (" CR_Signiture = x%x\n", ext.ConfigRom.CR_Signiture);
dprintf (" CR_BusInfoBlockCaps = x%x\n", ext.ConfigRom.CR_BusInfoBlockCaps);
dprintf (" CR_Node_UniqueID[0] = x%x\n", ext.ConfigRom.CR_Node_UniqueID[0]);
dprintf (" CR_Node_UniqueID[1] = x%x\n", ext.ConfigRom.CR_Node_UniqueID[1]);
dprintf (" CR_Root_Info = x%x\n", ext.ConfigRom.CR_Root_Info);
for (i = 0; i < SBP2_MAX_LUNS_PER_NODE; i++)
{
DisplayDeviceInformation (ext.DeviceList + i, i);
}
dprintf ("DeviceListSize = x%x\n", ext.DeviceListSize);
DisplayLeaf ("VendorLeaf", ext.VendorLeaf, Indent1);
dprintf ("MaxClassTransferSize = x%x\n", ext.MaxClassTransferSize);
dprintf ("Sbp2ObjectDirectory = x%p\n", ext.Sbp2ObjectDirectory);
dprintf ("\n");
}
DECLARE_API(help)
{
ULONG i;
for (i = 0; Help[i]; i++)
{
dprintf (Help[i]);
}
return;
}
DECLARE_API(pdoext)
{
ULONG bytesRead;
ULONG_PTR p;
DEVICE_OBJECT obj;
DEVICE_EXTENSION ext;
dprintf ("\n");
//
// Get the fdo pointer & any args from the cmd line
//
if (args[0] == 0)
{
dprintf ("usage: pdoext <pdo address> [-v]\n\n");
return;
}
sscanf (args, "%lx", &p);
Verbose = (BOOLEAN) strstr (args, "-v");
OrbFields = (BOOLEAN) strstr (args, "-o");
//
// Read the DEVICE_OBJECT to retrieve the device extension pointer
//
if (!ReadMemory (p, &obj, sizeof (obj), &bytesRead))
{
dprintf ("Unable to read pdo\n\n");
return;
}
if (bytesRead < sizeof (obj))
{
dprintf(
"Only read %d bytes of pdo, expected %d\n\n",
bytesRead,
sizeof (obj)
);
return;
}
p = (ULONG_PTR) obj.DeviceExtension;
//
// Read the device extension
//
if (!ReadMemory (p, &ext, sizeof (ext), &bytesRead))
{
dprintf ("Unable to read pdo extension\n\n");
return;
}
if (bytesRead < sizeof (ext))
{
dprintf(
"Only read %d bytes of pdo extension, expected %d\n\n",
bytesRead,
sizeof (ext)
);
return;
}
if (ext.Type != SBP2_PDO)
{
dprintf ("Not a pdo extension (ext.Type=x%x)\n\n", ext.Type);
return;
}
//
// Display the extension fields
//
dprintf ("DeviceObject = x%p\n", ext.DeviceObject);
dprintf ("LowerDeviceObject = x%p\n", ext.LowerDeviceObject);
DisplayDeviceFlags (ext.DeviceFlags);
dprintf ("BusFdo = x%p\n", ext.BusFdo);
DisplayDeviceInformation (ext.DeviceInfo, 0xffffffff);
dprintf ("MaxOrbListDepth = %d\n", ext.MaxOrbListDepth);
dprintf ("&PendingOrbList = x%p\n", &((PDEVICE_EXTENSION) p)->PendingOrbList);
if (Verbose)
{
dprintf (" Flink = x%p\n", ext.PendingOrbList.Flink);
dprintf (" Blink = x%p\n", ext.PendingOrbList.Blink);
}
dprintf ("OrbListDepth = %d\n", ext.OrbListDepth);
dprintf ("CurrentKey = x%x\n", ext.CurrentKey);
dprintf ("LastFetchedContext = x%p\n", ext.LastFetchedContext);
dprintf ("NextContextToFree = x%p\n", ext.NextContextToFree);
dprintf ("DevicePowerState = %d\n", (ULONG) ext.DevicePowerState);
dprintf ("SystemPowerState = %d\n", (ULONG) ext.SystemPowerState);
dprintf ("PowerDeferredIrp = x%p\n", ext.PowerDeferredIrp);
dprintf ("DeferredPowerRequest = x%p\n", ext.DeferredPowerRequest);
dprintf ("PagingPathCount = %d\n", (ULONG) ext.PagingPathCount);
dprintf ("HibernateCount = %d\n", (ULONG) ext.HibernateCount);
dprintf ("CrashDumpCount = %d\n", (ULONG) ext.CrashDumpCount);
dprintf ("HandleCount = %d\n", (ULONG) ext.HandleCount);
dprintf ("IdleCounter = x%p\n", &((PDEVICE_EXTENSION) p)->IdleCounter);
// DueTime
dprintf ("Reserved = x%x (%d)\n", ext.Reserved, ext.Reserved);
dprintf ("LastTransactionStatus = x%x\n", ext.LastTransactionStatus);
dprintf ("ReservedMdl = x%p\n", ext.ReservedMdl);
dprintf ("&InquiryData = x%p\n", &((PDEVICE_EXTENSION) p)->InquiryData);
dprintf ("InitiatorAddressId = x%d\n", ext.InitiatorAddressId);
dprintf ("CurrentGeneration = x%d\n", ext.CurrentGeneration);
dprintf ("MaxControllerPhySpeed = x%d\n", ext.MaxControllerPhySpeed);
dprintf ("OrbReadPayloadMask = x%d\n", (ULONG) ext.OrbReadPayloadMask);
dprintf ("OrbWritePayloadMask = x%d\n", (ULONG) ext.OrbWritePayloadMask);
if (Verbose)
{
dprintf ("HostControllerInformation\n");
dprintf (" HostCapabilities = x%d\n", ext.HostControllerInformation.HostCapabilities);
dprintf (" MaxAsyncReadReq = x%d\n", ext.HostControllerInformation.MaxAsyncReadRequest);
dprintf (" MaxAsyncWriteReq = x%d\n", ext.HostControllerInformation.MaxAsyncWriteRequest);
dprintf ("HostRoutineAPI\n");
dprintf (" PhysAddrMappingRtn = x%p\n", ext.HostRoutineAPI.PhysAddrMappingRoutine);
dprintf (" Context = x%p\n", ext.HostRoutineAPI.Context);
}
if (OrbFields)
{
dprintf ("TaskOrb\n");
dprintf (" OrbAddress = x%x%08x\n", ext.TaskOrb.OrbAddress.u.HighQuad, ext.TaskOrb.OrbAddress.u.LowQuad);
dprintf (" Reserved = x%x%08x\n", ext.TaskOrb.Reserved.u.HighQuad, ext.TaskOrb.Reserved.u.LowQuad);
dprintf (" OrbInfo = x%x\n", ext.TaskOrb.OrbInfo);
dprintf (" Reserved1 = x%x\n", ext.TaskOrb.Reserved1);
dprintf (" StatusBlockAddress = x%x%08x\n", ext.TaskOrb.StatusBlockAddress.u.HighQuad, ext.TaskOrb.StatusBlockAddress.u.LowQuad);
dprintf ("ManagementOrb\n");
dprintf (" Reserved[0] = x%x%08x\n", ext.ManagementOrb.Reserved[0].u.HighQuad, ext.ManagementOrb.Reserved[0].u.LowQuad);
dprintf (" Reserved[1] = x%x%08x\n", ext.ManagementOrb.Reserved[1].u.HighQuad, ext.ManagementOrb.Reserved[1].u.LowQuad);
dprintf (" OrbInfo = x%x\n", ext.ManagementOrb.OrbInfo);
dprintf (" Reserved1 = x%x\n", ext.ManagementOrb.Reserved1);
dprintf (" StatusBlockAddress = x%x%08x\n", ext.ManagementOrb.StatusBlockAddress.u.HighQuad, ext.ManagementOrb.StatusBlockAddress.u.LowQuad);
}
DisplayAddressContext ("TaskOrbContext\n", &ext.TaskOrbContext, Indent1);
DisplayAddressContext ("ManagementOrbContext\n", &ext.ManagementOrbContext, Indent1);
DisplayStatusFifoBlock ("ManagementOrbStatusBlock\n", &ext.ManagementOrbStatusBlock);
DisplayAddressContext ("ManagementOrbStatusContext\n", &ext.ManagementOrbStatusContext, Indent1);
DisplayStatusFifoBlock ("TaskOrbStatusBlock\n", &ext.TaskOrbStatusBlock);
DisplayAddressContext ("TaskOrbStatusContext\n", &ext.TaskOrbStatusContext, Indent1);
DisplayAddressContext ("GlobalStatusContext\n", &ext.GlobalStatusContext, Indent1);
if (Verbose)
{
dprintf ("LoginResponse\n");
dprintf (" LengthAndLoginId = x%x\n", ext.LoginResponse.LengthAndLoginId);
dprintf (" Csr_Off_High = x%x\n", ext.LoginResponse.Csr_Off_High);
dprintf (" Csr_Off_Low = x%x\n", ext.LoginResponse.Csr_Off_Low);
dprintf (" Reserved = x%x\n", ext.LoginResponse.Reserved);
}
DisplayAddressContext ("LoginRespContext\n", &ext.LoginRespContext, Indent1);
if (Verbose)
{
dprintf ("&QueryLoginResponse = x%p\n", &((PDEVICE_EXTENSION) p)->QueryLoginResponse);
dprintf (" LengthAndNumLogins = x%x\n", ext.QueryLoginResponse.LengthAndNumLogins);
dprintf (" Elements[0]\n");
dprintf (" NodeAndLoginId = x%x\n", ext.QueryLoginResponse.Elements[0].NodeAndLoginId);
dprintf (" EUI64 = x%x%08x\n", ext.QueryLoginResponse.Elements[0].EUI64.u.HighQuad, ext.QueryLoginResponse.Elements[0].EUI64.u.LowQuad);
}
// there's 3 more elements in the Elements[] array above we could display
DisplayAddressContext ("QueryLoginRespContext\n", &ext.QueryLoginRespContext, Indent1);
dprintf ("&StatusFifoListHead = x%p\n", &((PDEVICE_EXTENSION) p)->StatusFifoListHead);
// KSPIN_LOCK StatusFifoLock;
dprintf ("StatusFifoBase = x%p\n", ext.StatusFifoBase);
dprintf ("&FreeContextListHead = x%p\n", &((PDEVICE_EXTENSION) p)->FreeContextListHead);
dprintf ("&BusReqContxtListHead = x%p\n", &((PDEVICE_EXTENSION) p)->BusRequestContextListHead);
dprintf ("&BusReqIrpIrbListHead = x%p\n", &((PDEVICE_EXTENSION) p)->BusRequestIrpIrbListHead);
// KSPIN_LOCK BusRequestLock;
// KSPIN_LOCK FreeContextLock;
dprintf ("AsyncContextBase = x%p\n", ext.AsyncContextBase);
DisplayAddressContext ("OrbPoolContext\n", &ext.OrbPoolContext, Indent1);
// KSPIN_LOCK ExtensionDataSpinLock;
// KDPC DeviceManagementTimeoutDpc;
// KTIMER DeviceManagementTimer;
dprintf ("\n");
}
//
// Utility funcs
//
void
DisplayAddressContext(
char *Name,
PADDRESS_CONTEXT pContext,
char *Indent
)
{
char *postIndent = (Indent == Indent1 ? Indent1 : Indent0);
if (!OrbFields)
{
return;
}
dprintf (Name);
dprintf ("%sDeviceObject%s = x%p\n", Indent, postIndent, pContext->DeviceObject);
dprintf ("%sAddress%s = x%x%08x\n", Indent, postIndent, pContext->Address.u.HighQuad, pContext->Address.u.LowQuad);
dprintf ("%sReservedAddr%s = x%x%08x\n", Indent, postIndent, pContext->ReservedAddr.u.HighQuad, pContext->ReservedAddr.u.LowQuad);
dprintf ("%sAddressHandle%s = x%p\n", Indent, postIndent, pContext->AddressHandle);
dprintf ("%sRequestMdl%s = x%p\n", Indent, postIndent, pContext->RequestMdl);
dprintf ("%sTransactionType%s = x%x\n", Indent, postIndent, pContext->TransactionType);
dprintf ("%sReserved%s = x%p\n", Indent, postIndent, pContext->Reserved);
}
void
DisplayAsyncContextFlags(
ULONG Flags
)
{
ULONG i;
char *flagNames[] =
{
"TIMER_STARTED",
"COMPLETED",
"PAGE_ALLOC",
"DATA_ALLOC",
NULL
};
dprintf ("DeviceFlags = x%x, ", Flags);
for (i = 0; Flags && flagNames[i]; i++)
{
if (Flags & (1 << i))
{
dprintf (flagNames[i]);
Flags &= ~(1 << i);
}
}
if (Flags)
{
dprintf ("<inval flag(s)=x%x>", Flags);
}
dprintf ("\n");
}
void
DisplayDeviceFlags(
ULONG Flags
)
{
ULONG i;
char *flagNames[] =
{
"STOPPED ",
"RESET_IN_PROGRESS ",
"REMOVED ",
"LOGIN_IN_PROGRESS ",
"RECONNECT ",
"CLAIMED ",
"INITIALIZING ",
"QUEUE_LOCKED ",
"SPC_CMD_SET ",
"INITIALIZED ",
"REMOVE_PENDING ",
"DEVICE_FAILED ",
NULL
};
dprintf ("DeviceFlags = x%x, ", Flags);
for (i = 0; Flags && flagNames[i]; i++)
{
if (Flags & (1 << i))
{
dprintf (flagNames[i]);
Flags &= ~(1 << i);
}
}
if (Flags)
{
dprintf ("<inval flag(s)=x%x>", Flags);
}
dprintf ("\n");
}
void
DisplayDeviceInformation(
PDEVICE_INFORMATION Info,
ULONG Index
)
{
ULONG bytesRead;
DEVICE_INFORMATION info;
if (Index == 0xffffffff)
{
//
// Called from pdoext(), Info is simple a debugee pointer, need
// to read in the data
//
dprintf ("DeviceInfo = x%p\n", Info);
if (!Verbose)
{
return;
}
if (!ReadMemory ((ULONG_PTR) Info, &info, sizeof (info), &bytesRead))
{
dprintf (" <Unable to read device information>\n");
return;
}
if (bytesRead < sizeof (info))
{
dprintf(
" <Only read %d bytes of device information, expected %d>\n",
bytesRead,
sizeof (info)
);
return;
}
Info = &info;
}
else
{
//
// Called from fdoext(), Info data is valid
//
if (!Verbose || !Info->DeviceObject)
{
return;
}
dprintf ("DeviceInfo[%d]\n", Index);
}
dprintf (" DeviceObject = x%p\n", Info->DeviceObject);
dprintf (" Lun = x%x\n", Info->Lun);
dprintf (" CmdSetId = x%x\n", Info->CmdSetId);
dprintf (" UnitCharactristics = x%x\n", Info->UnitCharacteristics);
dprintf (" MgmtAgentBaseReg = x%x%08x\n", Info->ManagementAgentBaseReg.u.HighQuad, Info->ManagementAgentBaseReg.u.LowQuad);
dprintf (" CsrRegisterBase = x%x%08x\n", Info->CsrRegisterBase.u.HighQuad, Info->CsrRegisterBase.u.LowQuad);
dprintf (" ConfigRom = x%p\n", Info->ConfigRom);
// display crom
DisplayLeaf (" ModelLeaf", Info->ModelLeaf, Indent2);
DisplayLeaf (" VendorLeaf", Info->VendorLeaf, Indent2);
dprintf (" GenericName = %s\n", Info->GenericName);
dprintf (" MaxClassXferSize = x%x\n", Info->MaxClassTransferSize);
}
void
DisplayLeaf(
char *Name,
PTEXTUAL_LEAF Leaf,
char *Indent
)
{
char *postIndent = (Indent == Indent1 ? Indent1 : Indent0);
BYTE buf[sizeof (TEXTUAL_LEAF) + SBP2_MAX_TEXT_LEAF_LENGTH];
ULONG bytesRead, length;
ULONG_PTR p = (ULONG_PTR) Leaf;
PTEXTUAL_LEAF leaf = (PTEXTUAL_LEAF) buf;
dprintf ("%-22.22s= x%p\n", Name, p);
if (Leaf && Verbose)
{
//
// First read in, byte swap, & display the fixed size of the leaf
//
if (!ReadMemory (p, buf, sizeof (*leaf), &bytesRead))
{
dprintf (" <Unable to read leaf>\n");
return;
}
if (bytesRead < sizeof (*leaf))
{
dprintf(
" <Only read %d bytes of leaf, expected %d>\n",
bytesRead,
sizeof (buf)
);
return;
}
{
ULONG *p = (ULONG *) &leaf->TL_CRC;
*p = bswap (*p);
}
leaf->TL_Spec_Id = bswap (leaf->TL_Spec_Id);
leaf->TL_Language_Id = bswap (leaf->TL_Language_Id);
dprintf ("%sTL_CRC%s = x%x\n", Indent, postIndent, (ULONG) leaf->TL_CRC);
dprintf ("%sTL_Length%s = x%x\n", Indent, postIndent, (ULONG) leaf->TL_Length);
dprintf ("%sTL_Spec_Id%s = x%x\n", Indent, postIndent, leaf->TL_Spec_Id);
dprintf ("%sTL_Language_Id%s = x%x\n", Indent, postIndent, leaf->TL_Language_Id);
//
// Now read in the whole leaf (but not more than will fit in
// our stack buffer). Display only the first 50 chars
//
length = (ULONG) (leaf->TL_Length * sizeof (QUADLET)) +
sizeof (*leaf) - sizeof (leaf->TL_Data);
length = (length > sizeof (buf) ? sizeof (buf) : length);
if (!ReadMemory (p, buf, length, &bytesRead))
{
dprintf (" <Unable to read variable-length portion of leaf>\n");
return;
}
if (bytesRead < sizeof (*leaf))
{
dprintf(
" <Only read %d bytes of leaf, expected %d>\n",
bytesRead,
sizeof (buf)
);
return;
}
leaf->TL_Spec_Id = bswap (leaf->TL_Spec_Id);
if (leaf->TL_Spec_Id & 0x80000000) // unicode
{
dprintf ("%sTL_Data%s = %ws\n", Indent, postIndent, &leaf->TL_Data);
}
else // ascii
{
dprintf ("%sTL_Data%s = %s\n", Indent, postIndent, &leaf->TL_Data);
}
}
}
void
DisplayStatusFifoBlock(
char *Name,
PSTATUS_FIFO_BLOCK Block
)
{
if (!OrbFields)
{
return;
}
dprintf (Name);
dprintf (" AddressAndStatus = x%x%08x\n", Block->AddressAndStatus.u.HighQuad, Block->AddressAndStatus.u.LowQuad);
dprintf (" Contents[0] = x%x%08x\n", Block->Contents[0].u.HighQuad, Block->Contents[0].u.LowQuad);
dprintf (" Contents[1] = x%x%08x\n", Block->Contents[1].u.HighQuad, Block->Contents[1].u.LowQuad);
dprintf (" Contents[2] = x%x%08x\n", Block->Contents[2].u.HighQuad, Block->Contents[2].u.LowQuad);
}