|
|
/*++
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, p; 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); dprintf("\t-------\n");
dprintf("\tHcRhDescriptorA: %08.8x\n" , hc.HcRhDescriptorA.ul); dprintf("\t\tNumberDownstreamPorts: %d\n" , hc.HcRhDescriptorA.s.NumberDownstreamPorts); dprintf("\t\tHubChars: %x\n" , hc.HcRhDescriptorA.s.HubChars); dprintf("\t\tPowerOnToPowerGoodTime: %d\n" , hc.HcRhDescriptorA.s.PowerOnToPowerGoodTime); dprintf("\tHcRhDescriptorB: %08.8x\n" , hc.HcRhDescriptorB.ul); dprintf("\tHcRhStatus: %08.8x\n" , hc.HcRhStatus); for (p=0; p< hc.HcRhDescriptorA.s.NumberDownstreamPorts; p++) { dprintf("\tHcRhPortStatus[%d]: %08.8x\n",p ,hc.HcRhPortStatus[p]); } }
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; }
|