windows-nt/Source/XPSP1/NT/drivers/wdm/usb/hcd/kdexts/usbohci.c

734 lines
17 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
usbohci.c
Abstract:
WinDbg Extension Api
implements !_ohcitd
!_ohcied
!_ohciep
!_ohcitfer
Author:
jd
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#include "usb.h"
#include "usbhcdi.h"
#include "..\miniport\usbohci\openhci.h"
#include "..\miniport\usbohci\usbohci.h"
#include "usbhcdkd.h"
VOID
DumpOHCI_EpTransfers(
ULONG HeadP_MemLoc,
ULONG TailP_MemLoc
);
VOID
HwConditionCode(
ULONG cc
)
{
switch (cc) {
case HcCC_NoError:
dprintf("HcCC_NoError");
break;
case HcCC_CRC:
dprintf("HcCC_CRC ");
break;
case HcCC_BitStuffing:
dprintf("HcCC_BitStuffing");
break;
case HcCC_DataToggleMismatch:
dprintf("HcCC_DataToggleMismatch");
break;
case HcCC_Stall:
dprintf("HcCC_Stall ");
break;
case HcCC_DeviceNotResponding:
dprintf("HcCC_DeviceNotResponding");
break;
case HcCC_PIDCheckFailure:
dprintf("HcCC_PIDCheckFailure");
break;
case HcCC_UnexpectedPID:
dprintf("HcCC_UnexpectedPID");
break;
case HcCC_DataOverrun:
dprintf("HcCC_DataOverrun");
break;
case HcCC_DataUnderrun:
dprintf("HcCC_DataUnderrun");
break;
case HcCC_BufferOverrun:
dprintf("HcCC_BufferOverrun ");
break;
case HcCC_BufferUnderrun:
dprintf("HcCC_BufferUnderrun");
break;
case HcCC_NotAccessed:
dprintf("HcCC_NotAccessed");
break;
default:
dprintf("???");
break;
}
}
VOID
DumpOHCI_Td(
MEMLOC MemLoc
)
{
HCD_TRANSFER_DESCRIPTOR td;
ULONG cb;
ULONG i;
// tds are a fixed size of 64/32 platforms so
// we can just read it in
ReadMemory(MemLoc,
&td,
sizeof(td),
&cb);
PrintfMemLoc("*USBOHCI TD ", MemLoc, "\n");
dprintf("HwTD");
if (td.HwTD.Asy.Isochronous) {
// dump as iso
dprintf("\tIsochronous %x, \n", td.HwTD.Iso.Isochronous);
dprintf("\tStartingFrame: %x\n", td.HwTD.Iso.StartingFrame);
dprintf("\tFrameCount: %d (%d frames) \n", td.HwTD.Iso.FrameCount,
td.HwTD.Iso.FrameCount+1);
// dump the psw
dprintf("\tPSW:\n");
for (i=0; i< td.HwTD.Iso.FrameCount+2; i++) {
// input
dprintf("\t\tinput:[%d].Offset: x%x - %d\n", i,
td.HwTD.Packet[i].Offset,
td.HwTD.Packet[i].Offset);
dprintf("\t\tinput:[%d].Ones: x%x \n", i, td.HwTD.Packet[i].Ones);
dprintf("\t\toutput:[%d].Size: %d\n", i, td.HwTD.Packet[i].Size);
dprintf("\t\toutput:[%d].ConditionCode: %d\n", i, td.HwTD.Packet[i].ConditionCode);
}
} else {
// dump as async
dprintf("\tIsochronous %x, \n", td.HwTD.Asy.Isochronous);
dprintf("\tShortXferOk: %x\n", td.HwTD.Asy.ShortXferOk);
dprintf("\tDirection: %x\n", td.HwTD.Asy.Direction);
dprintf("\tToggle: %x", td.HwTD.Asy.Toggle);
dprintf("\tIntDelay: %x", td.HwTD.Asy.IntDelay);
dprintf("\tErrorCount: %x\n", td.HwTD.Asy.ErrorCount);
dprintf("\tConditionCode: x%x - ", td.HwTD.Asy.ConditionCode);
HwConditionCode(td.HwTD.Asy.ConditionCode);
dprintf("\n");
switch (td.HwTD.Asy.Toggle) {
case HcTDToggle_FromEd:
dprintf("HcTDToggle_FromEd\n");
break;
case HcTDToggle_Data0:
dprintf("HcTDToggle_Data0\n");
break;
case HcTDToggle_Data1:
dprintf("HcTDToggle_Data1\n");
break;
}
}
// these fields are common for iso & async
dprintf("\tCBP: ! %x\n", td.HwTD.CBP);
dprintf("\tBE: ! %x\n", td.HwTD.BE);
dprintf("\tNextTD: ! %x\n", td.HwTD.NextTD);
dprintf("PhysicalAddress: %08.8x\n", td.PhysicalAddress);
Sig(td.Sig, "");
dprintf("Flags: 0x%08.8x\n", td.Flags);
dprintf("EndpointData: %08.8x\n", td.EndpointData);
dprintf("TransferContext: %08.8x\n", td.TransferContext);
dprintf("TransferCount: 0x%08.8x\n", td.TransferCount);
dprintf("FrameIndex: %d\n", td.FrameIndex);
dprintf("NextHcdTD: %08.8x\n", td.NextHcdTD);
}
VOID
DumpOHCI_Ed(
ULONG MemLoc
)
{
HCD_ENDPOINT_DESCRIPTOR ed;
ULONG result;
if (!ReadMemory (MemLoc, &ed, sizeof(ed), &result)) {
BadMemLoc(MemLoc);
return;
}
dprintf("*USBOHCI ED %08.8x\n", MemLoc);
dprintf("HwED");
dprintf("\tFunctionAddress: 0x%x\n", ed.HwED.FunctionAddress);
dprintf("\tEndpointNumber: %x\n", ed.HwED.EndpointNumber);
dprintf("\tDirection: %x\n", ed.HwED.Direction);
dprintf("\tLowSpeed: %x\n", ed.HwED.LowSpeed);
dprintf("\tsKip: %x\n", ed.HwED.sKip);
dprintf("\tIsochronous: %x\n", ed.HwED.Isochronous);
dprintf("\tMaxPacket: 0x%x\n", ed.HwED.MaxPacket);
dprintf("\tTailP: ! %x\n", ed.HwED.TailP);
dprintf("\tHeadP: ! %x", ed.HwED.HeadP);
if (ed.HwED.HeadP & HcEDHeadP_HALT) {
dprintf(" (halted)");
}
dprintf("\n");
dprintf("\tNextED: %x\n", ed.HwED.NextED);
dprintf("PhysicalAddress: %08.8x\n", ed.PhysicalAddress);
Sig(ed.Sig, "");
dprintf("EdFlags: 0x%08.8x\n", ed.EdFlags);
dprintf("EndpointData: %08.8x\n", ed.EndpointData);
dprintf("SwLink.List.Flink: %08.8x\n", ed.SwLink.List.Flink);
dprintf("SwLink.List.Blink: %08.8x\n", ed.SwLink.List.Blink);
}
VOID
DumpOHCI_EndpointData(
MEMLOC MemLoc
)
{
UCHAR cs[] = "usbohci!_ENDPOINT_DATA";
PrintfMemLoc("*USBOHCI ENDPOINT_DATA ", MemLoc, "\n");
Sig(UsbReadFieldUlong(MemLoc, cs, "Sig"), "");
// dprintf("MaxPendingTransfers: 0x%08.8x\n", epData.MaxPendingTransfers);
dprintf("PendingTransfers: 0x%08.8x\n",
UsbReadFieldUlong(MemLoc, cs, "PendingTransfers"));
PrintfMemLoc("StaticEd: ",
UsbReadFieldPtr(MemLoc, cs, "StaticEd"),
"\n");
PrintfMemLoc("TdList: ",
UsbReadFieldPtr(MemLoc, cs, "TdList"),
"\n");
PrintfMemLoc("HcdEd: ",
UsbReadFieldPtr(MemLoc, cs, "HcdEd"),
"\n");
dprintf("TdCount: 0x%08.8x\n",
UsbReadFieldUlong(MemLoc, cs, "TdCount"));
PrintfMemLoc("HcdTailP: ",
UsbReadFieldPtr(MemLoc, cs, "HcdTailP"),
"\n");
PrintfMemLoc("HcdHeadP: ",
UsbReadFieldPtr(MemLoc, cs, "HcdHeadP"),
"\n");
// DumpOHCI_Ed(epData.HcdEd);
// DumpOHCI_EpTransfers((ULONG) epData.HcdHeadP, (ULONG) epData.HcdTailP);
}
VOID
DumpOHCI_TransferContext(
ULONG MemLoc
)
{
TRANSFER_CONTEXT tc;
ULONG result;
SIG s;
if (!ReadMemory (MemLoc, &tc, sizeof(tc), &result)) {
BadMemLoc(MemLoc);
return;
}
dprintf("*USBOHCI TRANSFER_CONTEXT %08.8x\n", MemLoc);
Sig(tc.Sig, "");
dprintf("BytesTransferred: 0x%08.8x\n", tc.BytesTransferred);
dprintf("TransferParameters: %x\n",
tc.TransferParameters);
dprintf("PendingTds: %d\n", tc.PendingTds);
dprintf("Flags: %08.8x\n", tc.TcFlags);
dprintf("UsbdStatus: 0x%08.8x\n", tc.UsbdStatus);
dprintf("NextXferTd: %08.8x\n", tc.NextXferTd);
dprintf("StatusTd: %08.8x\n", tc.StatusTd);
dprintf("EndpointData: %08.8x\n", tc.EndpointData);
}
VOID
DumpOHCI_EpTransfers(
ULONG HeadP_MemLoc,
ULONG TailP_MemLoc
)
{
#if 0
HCD_TRANSFER_DESCRIPTOR td;
ULONG memLoc, result;
// start at headp and walk to tail
dprintf("\t TRANSFERS: HeadP\n");
memLoc = HeadP_MemLoc;
do {
if (!ReadMemory (memLoc, &td, sizeof(td), &result)) {
break;
}
dprintf("\t> TD %8.8x(! %8.8x) - Transfer %8.8x Next-> ! %8.8x\n",
memLoc, td.PhysicalAddress, td.TransferContext.Pointer,
td.HwTD.NextTD);
if (memLoc == TailP_MemLoc) {
break;
}
memLoc = (ULONG) td.NextHcdTD.Pointer;
} while (1);
#endif
}
VOID
DumpOHCI_DeviceData(
MEMLOC MemLoc,
BOOLEAN Verbose
)
{
UCHAR cs[] = "usbohci!_DEVICE_DATA";
ULONG f, i;
UCHAR fld[40], fld1[40], fld2[40], fld3[40], fld4[40];
STRUC_ENTRY t[] = {
"Sig", FT_SIG,
"HC", FT_PTR,
"BIOS_Interval", FT_ULONG,
"SofModifyValue", FT_ULONG,
"FrameHighPart", FT_ULONG,
"HcHCCA", FT_PTR,
"HcHCCAPhys", FT_ULONG,
"HydraLsHsHackEd", FT_PTR,
"StaticEDs", FT_PTR,
"StaticEDsPhys", FT_ULONG,
"ControllerFlavor", FT_ULONG,
};
ULONG period[] = {1, 2, 2, 4, 4, 4, 4, 8,
8, 8, 8, 8, 8, 8, 8,16,
16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,32,
32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,
0, 0};
// FLAG_TABLE ddFlags[] = {
// "EHCI_DD_FLAG_NOCHIRP", EHCI_DD_FLAG_NOCHIRP,
// "EHCI_DD_FLAG_SOFT_ERROR_RETRY", EHCI_DD_FLAG_SOFT_ERROR_RETRY
// };
PrintfMemLoc("*USBOHCI DEVICE DATA ", MemLoc, "\n");
UsbDumpStruc(MemLoc, cs,
&t[0], sizeof(t)/sizeof(STRUC_ENTRY));
if (Verbose) {
for (i= 0; i< NO_ED_LISTS; i++) {
dprintf("\t[%02.2d] (%2.2dms): ", i, period[i]);
sprintf(fld , "StaticEDList[%d]", i);
sprintf(fld1, "StaticEDList[%d].HwED", i);
sprintf(fld2, "StaticEDList[%d].HwEDPhys", i);
PrintfMemLoc("StaticED @ ",
MemLoc + UsbFieldOffset(cs, fld),
" ");
PrintfMemLoc("HwED ",
UsbReadFieldPtr(MemLoc, cs, fld1),
" ");
dprintf("(!%08.8x)\n",
UsbReadFieldUlong(MemLoc, cs, fld2));
sprintf(fld1, "StaticEDList[%d].NextIdx", i);
sprintf(fld2, "StaticEDList[%d].EdFlags", i);
sprintf(fld3, "StaticEDList[%d].HccaOffset", i);
sprintf(fld4, "StaticEDList[%d].PhysicalHead", i);
dprintf("\t\tNextIdx(%03.3d) EdFlags %08.8x Hcca Offset %d ",
UsbReadFieldUlong(MemLoc, cs, fld1),
UsbReadFieldUlong(MemLoc, cs, fld2),
UsbReadFieldUlong(MemLoc, cs, fld3));
PrintfMemLoc("PhysicalHead ",
MemLoc + UsbFieldOffset(cs, fld4),
"\n");
sprintf(fld1, "StaticEDList[%d].TransferEdList.Flink", i);
PrintfMemLoc("\t\tTransferEdList.Flink ",
UsbReadFieldPtr(MemLoc, cs, fld1),
"\n");
sprintf(fld1, "StaticEDList[%d].TransferEdList.Blink", i);
PrintfMemLoc("\t\tTransferEdList.Blink ",
UsbReadFieldPtr(MemLoc, cs, fld1),
"\n");
}
}
}
VOID
DumpOHCI_Ints(
ULONG i
)
{
if (i & HcInt_SchedulingOverrun) {
dprintf("\t HcInt_SchedulingOverrun \n");
}
if (i & HcInt_WritebackDoneHead) {
dprintf("\t HcInt_WritebackDoneHead \n");
}
if (i & HcInt_StartOfFrame) {
dprintf("\t HcInt_StartOfFrame \n");
}
if (i & HcInt_ResumeDetected) {
dprintf("\t HcInt_ResumeDetected \n");
}
if (i & HcInt_UnrecoverableError) {
dprintf("\t HcInt_UnrecoverableError \n");
}
if (i & HcInt_RootHubStatusChange) {
dprintf("\t HcInt_RootHubStatusChange \n");
}
if (i & HcInt_OwnershipChange) {
dprintf("\t HcInt_OwnershipChange \n");
}
if (i & HcInt_MasterInterruptEnable) {
dprintf("\t HcInt_MasterInterruptEnable \n");
}
if (i & HcInt_FrameNumberOverflow) {
dprintf("\t HcInt_FrameNumberOverflow \n");
}
dprintf("\n");
}
VOID
DumpOHCI_OpRegs(
MEMLOC MemLoc
)
{
HC_OPERATIONAL_REGISTER hc;
HC_CONTROL cmd;
HC_COMMAND_STATUS sts;
ULONG l, i;
ULONG cb;
ReadMemory(MemLoc,
&hc,
sizeof(HC_OPERATIONAL_REGISTER),
&cb);
PrintfMemLoc("*(ohci)HC_OPERATIONAL_REGISTER ", MemLoc, "\n");
cmd = hc.HcControl;
dprintf("\tHC_CONTROL %08.8x\n" , cmd.ul);
dprintf("\t.ControlBulkServiceRatio: %d\n", cmd.ControlBulkServiceRatio);
dprintf("\t.IsochronousEnable: %d\n", cmd.IsochronousEnable);
dprintf("\t.ControlListEnable: %d\n", cmd.ControlListEnable);
dprintf("\t.BulkListEnable: %d\n", cmd.BulkListEnable);
dprintf("\t.HostControllerFunctionalState: %d\n", cmd.HostControllerFunctionalState);
dprintf("Reset=0 Resume=1 Operational=2 Suspend=3\n");
dprintf("\t.InterruptRouting: %d\n", cmd.InterruptRouting);
dprintf("\t.RemoteWakeupConnected: %d\n", cmd.RemoteWakeupConnected);
dprintf("\t.RemoteWakeupEnable: %d\n", cmd.RemoteWakeupEnable);
dprintf("\n");
sts = hc.HcCommandStatus;
dprintf("\tHC_COMMAND_STATUS %08.8x\n" , sts.ul);
dprintf("\t.HostControllerReset: %d\n", sts.HostControllerReset);
dprintf("\t.ControlListFilled: %d\n", sts.ControlListFilled);
dprintf("\t.BulkListFilled: %d\n", sts.BulkListFilled);
dprintf("\t.OwnershipChangeRequest: %d\n", sts.OwnershipChangeRequest);
dprintf("\t.SchedulingOverrunCount: %d\n", sts.SchedulingOverrunCount);
dprintf("\n");
dprintf("\tHcInterruptStatus: %08.8x\n" , hc.HcInterruptStatus);
DumpOHCI_Ints(hc.HcInterruptStatus);
dprintf("\tHcInterruptEnable: %08.8x\n" , hc.HcInterruptEnable);
DumpOHCI_Ints(hc.HcInterruptEnable);
dprintf("\tHcInterruptDisable: %08.8x\n" , hc.HcInterruptDisable);
DumpOHCI_Ints(hc.HcInterruptDisable);
dprintf("\tHcHCCA: %08.8x\n" , hc.HcHCCA);
dprintf("\tHcPeriodCurrentED: %08.8x\n" , hc.HcPeriodCurrentED);
dprintf("\tHcControlHeadED: %08.8x\n" , hc.HcControlHeadED);
dprintf("\tHcControlCurrentED: %08.8x\n" , hc.HcControlCurrentED);
dprintf("\tHcBulkHeadED: %08.8x\n" , hc.HcBulkHeadED);
dprintf("\tHcBulkCurrentED: %08.8x\n" , hc.HcBulkCurrentED);
dprintf("\tHcDoneHead: %08.8x\n" , hc.HcDoneHead);
dprintf("\tHcFmInterval: %08.8x\n" , hc.HcFmInterval.ul);
dprintf("\tHcFmRemaining: %08.8x\n" , hc.HcFmRemaining.ul);
dprintf("\tHcFmNumber: %08.8x\n" , hc.HcFmNumber);
dprintf("\tHcPeriodicStart: %08.8x\n" , hc.HcPeriodicStart);
dprintf("\tHcLSThreshold: %08.8x\n" , hc.HcLSThreshold);
dprintf("\t-------\n");
dprintf("\tCurrent Frame Index = %d\n", hc.HcFmNumber & 0x0000001f);
}
DECLARE_API( _ohcitd )
/*++
Routine Description:
dumps the extension
Arguments:
args - Address flags
Return Value:
None
--*/
{
MEMLOC addr;
// fetch the list head
addr = GetExpression(args);
DumpOHCI_Td (addr);
return S_OK;
}
DECLARE_API( _ohcied )
/*++
Routine Description:
dumps the extension
Arguments:
args - Address flags
Return Value:
None
--*/
{
ULONG memLoc;
UCHAR buffer[256];
ULONG len = 30;
ULONG result;
//UNREFERENCED_PARAMETER (dwProcessor);
//UNREFERENCED_PARAMETER (dwCurrentPc);
//UNREFERENCED_PARAMETER (hCurrentThread);
//UNREFERENCED_PARAMETER (hCurrentProcess);
buffer[0] = '\0';
sscanf(args, "%lx, %s", &memLoc, buffer);
if ('\0' != buffer[0]) {
sscanf(buffer, "%d", &len);
}
DumpOHCI_Ed (memLoc);
return S_OK;
}
DECLARE_API( _ohciep )
/*++
Routine Description:
dumps the extension
Arguments:
args - Address flags
Return Value:
None
--*/
{
MEMLOC addr;
// fetch the list head
addr = GetExpression(args);
DumpOHCI_EndpointData (addr);
return S_OK;
}
DECLARE_API( _ohcitfer )
/*++
Routine Description:
dumps TRANSFER_CONTEXT
Arguments:
args - Address flags
Return Value:
None
--*/
{
ULONG memLoc;
UCHAR buffer[256];
ULONG len = 30;
ULONG result;
//UNREFERENCED_PARAMETER (dwProcessor);
//UNREFERENCED_PARAMETER (dwCurrentPc);
//UNREFERENCED_PARAMETER (hCurrentThread);
//UNREFERENCED_PARAMETER (hCurrentProcess);
buffer[0] = '\0';
sscanf(args, "%lx, %s", &memLoc, buffer);
if ('\0' != buffer[0]) {
sscanf(buffer, "%d", &len);
}
DumpOHCI_TransferContext (memLoc);
return S_OK;
}
DECLARE_API( _ohciregs )
/*++
Routine Description:
dumps the extension
Arguments:
args - Address flags
Return Value:
None
--*/
{
MEMLOC addr;
// fetch the list head
addr = GetExpression(args);
DumpOHCI_OpRegs(addr);
return S_OK;
}
DECLARE_API( _ohcidd )
/*++
Routine Description:
dumps the extension
Arguments:
args - Address flags
Return Value:
None
--*/
{
MEMLOC addr;
PCSTR s;
UCHAR parm[32];
GetExpressionEx( args, &addr, &s );
sscanf(s, ",%s", &parm);
dprintf("%s\n", parm);
DumpOHCI_DeviceData(addr, parm[0] == 'v');
return S_OK;
}