Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

965 lines
20 KiB

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
dbg.c
Abstract:
Debug functions and services
Environment:
kernel mode only
Notes:
Revision History:
6-20-99 : created
--*/
#include "stdarg.h"
#include "stdio.h"
#include "common.h"
// paged functions
#ifdef ALLOC_PRAGMA
#endif
// non paged functions
//USBPORT_GetGlobalDebugRegistryParameters
//USBPORT_AssertFailure
//USBPORT_KdPrintX
//
ULONG USBPORT_LogMask = (LOG_MINIPORT |
LOG_XFERS |
LOG_PNP |
LOG_MEM |
LOG_POWER |
LOG_RH |
LOG_URB |
LOG_MISC |
LOG_IRPS |
LOG_ISO);
//ULONG USBPORT_LogMask = (
// LOG_IRPS |
// LOG_URB);
ULONG USBPORT_DebugLogEnable =
#if DBG
1;
#else
1;
#endif
ULONG USBPORT_CatcTrapEnable = 0;
#if DBG
/******
DEBUG
******/
#define DEFAULT_DEBUG_LEVEL 0
#ifdef DEBUG1
#undef DEFAULT_DEBUG_LEVEL
#define DEFAULT_DEBUG_LEVEL 1
#endif
#ifdef DEBUG2
#undef DEFAULT_DEBUG_LEVEL
#define DEFAULT_DEBUG_LEVEL 2
#endif
ULONG USBPORT_TestPath = 0;
ULONG USBPORT_W98_Debug_Trace = 0;
ULONG USBPORT_Debug_Trace_Level = DEFAULT_DEBUG_LEVEL;
ULONG USBPORT_Client_Debug = 0;
ULONG USBPORT_BreakOn = 0;
VOID
USB2LIB_DbgPrint(
PCH Format,
int Arg0,
int Arg1,
int Arg2,
int Arg3,
int Arg4,
int Arg5
)
{
if (USBPORT_Debug_Trace_Level) {
DbgPrint(Format, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5);
}
}
VOID
USB2LIB_DbgBreak(
VOID
)
{
DbgPrint("<Break in USB2LIB>\n");
DbgBreakPoint();
}
VOID
USBPORTSVC_DbgPrint(
PDEVICE_DATA DeviceData,
ULONG Level,
PCH Format,
int Arg0,
int Arg1,
int Arg2,
int Arg3,
int Arg4,
int Arg5
)
{
if (USBPORT_Debug_Trace_Level >= Level) {
if (Level <= 1) {
// dump line to debugger
if (USBPORT_W98_Debug_Trace) {
DbgPrint("xMP.SYS: ");
*Format = ' ';
} else {
DbgPrint("'xMP.SYS: ");
}
} else {
// dump line to NTKERN buffer
DbgPrint("'xMP.SYS: ");
if (USBPORT_W98_Debug_Trace) {
*Format = 0x27;
}
}
DbgPrint(Format, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5);
}
}
VOID
USBPORTSVC_TestDebugBreak(
PDEVICE_DATA DeviceData
)
{
DEBUG_BREAK();
}
VOID
USBPORTSVC_AssertFailure(
PDEVICE_DATA DeviceData,
PVOID FailedAssertion,
PVOID FileName,
ULONG LineNumber,
PCHAR Message
)
{
USBPORT_AssertFailure(
FailedAssertion,
FileName,
LineNumber,
Message);
}
NTSTATUS
USBPORT_GetGlobalDebugRegistryParameters(
VOID
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
#define MAX_KEYS 8
NTSTATUS ntStatus;
RTL_QUERY_REGISTRY_TABLE QueryTable[MAX_KEYS];
PWCHAR usb = L"usb";
ULONG k = 0;
PAGED_CODE();
//
// Set up QueryTable to do the following:
//
// spew level - 0
QueryTable[k].QueryRoutine = USBPORT_GetConfigValue;
QueryTable[k].Flags = 0;
QueryTable[k].Name = DEBUG_LEVEL_KEY;
QueryTable[k].EntryContext = &USBPORT_Debug_Trace_Level;
QueryTable[k].DefaultType = REG_DWORD;
QueryTable[k].DefaultData = &USBPORT_Debug_Trace_Level;
QueryTable[k].DefaultLength = sizeof(USBPORT_Debug_Trace_Level);
k++;
USBPORT_ASSERT(k < MAX_KEYS);
// use ntkern trace buffer - 1
QueryTable[k].QueryRoutine = USBPORT_GetConfigValue;
QueryTable[k].Flags = 0;
QueryTable[k].Name = DEBUG_WIN9X_KEY;
QueryTable[k].EntryContext = &USBPORT_W98_Debug_Trace;
QueryTable[k].DefaultType = REG_DWORD;
QueryTable[k].DefaultData = &USBPORT_W98_Debug_Trace;
QueryTable[k].DefaultLength = sizeof(USBPORT_W98_Debug_Trace);
k++;
USBPORT_ASSERT(k < MAX_KEYS);
// break on start - 2
QueryTable[k].QueryRoutine = USBPORT_GetConfigValue;
QueryTable[k].Flags = 0;
QueryTable[k].Name = DEBUG_BREAK_ON;
QueryTable[k].EntryContext = &USBPORT_BreakOn;
QueryTable[k].DefaultType = REG_DWORD;
QueryTable[k].DefaultData = &USBPORT_BreakOn;
QueryTable[k].DefaultLength = sizeof(USBPORT_BreakOn);
k++;
USBPORT_ASSERT(k < MAX_KEYS);
// log mask - 3
QueryTable[k].QueryRoutine = USBPORT_GetConfigValue;
QueryTable[k].Flags = 0;
QueryTable[k].Name = DEBUG_LOG_MASK;
QueryTable[k].EntryContext = &USBPORT_LogMask;
QueryTable[k].DefaultType = REG_DWORD;
QueryTable[k].DefaultData = &USBPORT_LogMask;
QueryTable[k].DefaultLength = sizeof(USBPORT_LogMask);
k++;
USBPORT_ASSERT(k < MAX_KEYS);
// log mask - 4
QueryTable[k].QueryRoutine = USBPORT_GetConfigValue;
QueryTable[k].Flags = 0;
QueryTable[k].Name = DEBUG_CLIENTS;
QueryTable[k].EntryContext = &USBPORT_Client_Debug;
QueryTable[k].DefaultType = REG_DWORD;
QueryTable[k].DefaultData = &USBPORT_Client_Debug;
QueryTable[k].DefaultLength = sizeof(USBPORT_LogMask);
k++;
USBPORT_ASSERT(k < MAX_KEYS);
// log enable - 5
QueryTable[k].QueryRoutine = USBPORT_GetConfigValue;
QueryTable[k].Flags = 0;
QueryTable[k].Name = DEBUG_LOG_ENABLE;
QueryTable[k].EntryContext = &USBPORT_DebugLogEnable;
QueryTable[k].DefaultType = REG_DWORD;
QueryTable[k].DefaultData = &USBPORT_DebugLogEnable;
QueryTable[k].DefaultLength = sizeof(USBPORT_DebugLogEnable);
k++;
USBPORT_ASSERT(k < MAX_KEYS);
// catc trap enable - 6
QueryTable[k].QueryRoutine = USBPORT_GetConfigValue;
QueryTable[k].Flags = 0;
QueryTable[k].Name = DEBUG_CATC_ENABLE;
QueryTable[k].EntryContext = &USBPORT_CatcTrapEnable;
QueryTable[k].DefaultType = REG_DWORD;
QueryTable[k].DefaultData = &USBPORT_CatcTrapEnable;
QueryTable[k].DefaultLength = sizeof(USBPORT_CatcTrapEnable);
k++;
USBPORT_ASSERT(k < MAX_KEYS);
//
// Stop
//
QueryTable[k].QueryRoutine = NULL;
QueryTable[k].Flags = 0;
QueryTable[k].Name = NULL;
ntStatus = RtlQueryRegistryValues(
RTL_REGISTRY_SERVICES,
usb,
QueryTable, // QueryTable
NULL, // Context
NULL); // Environment
if (NT_SUCCESS(ntStatus)) {
USBPORT_KdPrint((1, "'Debug Trace Level Set: (%d)\n", USBPORT_Debug_Trace_Level));
if (USBPORT_W98_Debug_Trace) {
USBPORT_KdPrint((1, "'NTKERN Trace is ON\n"));
} else {
USBPORT_KdPrint((1, "'NTKERN Trace is OFF\n"));
}
if (USBPORT_DebugLogEnable) {
USBPORT_KdPrint((1, "'DEBUG-LOG is ON\n"));
} else {
USBPORT_KdPrint((1, "'DEBUG-LOG is OFF\n"));
}
if (USBPORT_BreakOn) {
USBPORT_KdPrint((1, "'DEBUG BREAK is ON\n"));
}
USBPORT_KdPrint((1, "'DEBUG Log Mask is 0x%08.8x\n", USBPORT_LogMask));
if (USBPORT_Debug_Trace_Level > 0) {
ULONG USBPORT_Debug_Asserts = 1;
}
if (USBPORT_Client_Debug) {
USBPORT_KdPrint((1, "'DEBUG CLIENTS (verifier) is ON\n"));
}
if (USBPORT_CatcTrapEnable) {
USBPORT_KdPrint((0, "'DEBUG ANALYZER TRIGGER is ON\n"));
}
}
if ( STATUS_OBJECT_NAME_NOT_FOUND == ntStatus ) {
ntStatus = STATUS_SUCCESS;
}
return ntStatus;
}
VOID
USBPORT_AssertTransferUrb(
PTRANSFER_URB Urb
)
{
PDEVICE_OBJECT fdoDeviceObject;
PHCD_TRANSFER_CONTEXT transfer;
PHCD_ENDPOINT endpoint;
transfer = Urb->pd.HcdTransferContext;
ASSERT_TRANSFER(transfer);
USBPORT_ASSERT(transfer->Urb == Urb);
endpoint = transfer->Endpoint;
ASSERT_ENDPOINT(endpoint);
fdoDeviceObject = endpoint->FdoDeviceObject;
LOGENTRY(NULL, fdoDeviceObject, LOG_URB, 'Aurb', Urb, transfer, 0);
USBPORT_ASSERT(Urb->pd.UrbSig == URB_SIG);
}
VOID
USBPORT_AssertFailure(
PVOID FailedAssertion,
PVOID FileName,
ULONG LineNumber,
PCHAR Message
)
/*++
Routine Description:
Debug Assert function.
on NT the debugger does this for us but on win9x it does not.
so we have to do it ourselves.
Arguments:
Return Value:
--*/
{
// this makes the compiler generate a ret
ULONG stop = 0;
assert_loop:
// just call the NT assert function and stop
// in the debugger.
RtlAssert( FailedAssertion, FileName, LineNumber, Message );
// loop here to prevent users from going past
// are assert before we can look at it
DbgBreakPoint();
if (stop) {
goto assert_loop;
}
return;
}
ULONG
_cdecl
USBPORT_DebugClientX(
PCH Format,
...
)
/*++
Routine Description:
Special debug print function for debugging client USB drivers.
if the client debug mode is set then this function will print a
message and break in the debugger. This is the embedded USBPORT
equivalent of Verifier.
Arguments:
Return Value:
--*/
{
va_list list;
int i;
int arg[6];
if (USBPORT_Debug_Trace_Level > 1 ||
USBPORT_Client_Debug) {
DbgPrint(" *** USBPORT(VERIFIER) - CLIENT DRIVER BUG:\n");
DbgPrint(" * ");
va_start(list, Format);
for (i=0; i<6; i++)
arg[i] = va_arg(list, int);
DbgPrint(Format, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
DbgPrint(" ***\n ");
DbgBreakPoint();
}
return 0;
}
ULONG
_cdecl
USBPORT_KdPrintX(
ULONG l,
PCH Format,
...
)
/*++
Routine Description:
Debug Print function.
Prints based on the value of the USBPORT_DEBUG_TRACE_LEVEL
Also if USBPORT_W98_Debug_Trace is set then all debug messages
with a level greater than one are modified to go in to the
ntkern trace buffer.
It is only valid to set USBPORT_W98_Debug_Trace on Win9x
becuse the static data segments for drivers are marked read-only
by the NT OS.
Arguments:
Return Value:
--*/
{
va_list list;
int i;
int arg[6];
if (USBPORT_Debug_Trace_Level >= l) {
if (l <= 1) {
// dump line to debugger
if (USBPORT_W98_Debug_Trace) {
DbgPrint("USBPORT.SYS: ");
*Format = ' ';
} else {
DbgPrint("'USBPORT.SYS: ");
}
} else {
// dump line to NTKERN buffer
DbgPrint("'USBPORT.SYS: ");
if (USBPORT_W98_Debug_Trace) {
*Format = 0x27;
}
}
va_start(list, Format);
for (i=0; i<6; i++)
arg[i] = va_arg(list, int);
DbgPrint(Format, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
}
return 0;
}
VOID
USBPORT_DebugTransfer_LogEntry(
PDEVICE_OBJECT FdoDeviceObject,
PHCD_ENDPOINT Endpoint,
PHCD_TRANSFER_CONTEXT Transfer,
PTRANSFER_URB Urb,
PIRP Irp,
NTSTATUS IrpStatus
)
/*++
Routine Description:
Adds an entry to transfer log.
Arguments:
Return Value:
None.
--*/
{
KIRQL irql;
PDEVICE_EXTENSION devExt;
GET_DEVICE_EXT(devExt, FdoDeviceObject);
ASSERT_FDOEXT(devExt);
if (devExt->TransferLog.LogStart == 0) {
return;
}
USBPORT_AddLogEntry(
&devExt->TransferLog,
0xFFFFFFFF,
'1rfx',
(ULONG_PTR) Endpoint,
(ULONG_PTR) Irp,
(ULONG_PTR) Urb,
FALSE);
// decode some info about the transfer and log it as well
USBPORT_AddLogEntry(
&devExt->TransferLog,
0xFFFFFFFF,
'2rfx',
(ULONG_PTR) Urb->Hdr.Function,
IrpStatus,
(ULONG_PTR) Urb->TransferBufferLength,
FALSE);
}
#else
/********
RETAIL
********/
VOID
USB2LIB_DbgPrint(
PCH Format,
int Arg0,
int Arg1,
int Arg2,
int Arg3,
int Arg4,
int Arg5
)
{
// nop
}
VOID
USB2LIB_DbgBreak(
VOID
)
{
// nop
}
VOID
USBPORTSVC_DbgPrint(
PDEVICE_DATA DeviceData,
ULONG Level,
PCH Format,
int Arg0,
int Arg1,
int Arg2,
int Arg3,
int Arg4,
int Arg5
)
{
// nop
}
VOID
USBPORTSVC_AssertFailure(
PDEVICE_DATA DeviceData,
PVOID FailedAssertion,
PVOID FileName,
ULONG LineNumber,
PCHAR Message
)
{
// nop
}
VOID
USBPORTSVC_TestDebugBreak(
PDEVICE_DATA DeviceData
)
{
// nop
}
#endif /* DBG */
/********
LOG CODE
enabled in both retail and debug builds
*********/
VOID
USBPORTSVC_LogEntry(
PDEVICE_DATA DeviceData,
ULONG Mask,
ULONG Sig,
ULONG_PTR Info1,
ULONG_PTR Info2,
ULONG_PTR Info3
)
/*++
Routine Description:
Service for miniport to add log entries.
Arguments:
Return Value:
None.
--*/
{
PDEVICE_EXTENSION devExt;
PDEBUG_LOG l;
extern ULONG USBPORT_DebugLogEnable;\
extern ULONG USBPORT_LogMask;\
DEVEXT_FROM_DEVDATA(devExt, DeviceData);
ASSERT_FDOEXT(devExt);
if (USBPORT_DebugLogEnable &&
devExt->Log.LogStart != NULL &&
(LOG_MINIPORT & USBPORT_LogMask)) {
l = &devExt->Log;
USBPORT_AddLogEntry(l, LOG_MINIPORT, Sig, Info1, Info2, Info3, TRUE);
}
}
VOID
USBPORT_LogAlloc(
PDEBUG_LOG Log,
ULONG Pages
)
/*++
Routine Description:
Init the debug log -
remember interesting information in a circular buffer
Arguments:
Return Value:
None.
--*/
{
ULONG logSize = 4096*Pages;
if (USBPORT_DebugLogEnable) {
// we won't track the mem we alloc for the log
// we will let the verifier do that
ALLOC_POOL_Z(Log->LogStart,
NonPagedPool,
logSize);
if (Log->LogStart) {
Log->LogIdx = 0;
Log->LogSizeMask = (logSize/sizeof(LOG_ENTRY));
Log->LogSizeMask-=1;
// Point the end (and first entry) 1 entry from the end
// of the segment
Log->LogEnd = Log->LogStart +
(logSize / sizeof(struct LOG_ENTRY)) - 1;
} else {
DEBUG_BREAK();
}
}
return;
}
VOID
USBPORT_LogFree(
PDEVICE_OBJECT FdoDeviceObject,
PDEBUG_LOG Log
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
if (Log->LogStart != NULL) {
// log the free of the log in order to debug
// verifier bugs
FREE_POOL(FdoDeviceObject, Log->LogStart);
// this will indicate that we have freed the
// log, other log pointers will remain intact
Log->LogStart = NULL;
}
return;
}
/*
Transmit the analyzer trigger packet
*/
VOID
USBPORT_BeginTransmitTriggerPacket(
PDEVICE_OBJECT FdoDeviceObject
)
/*++
Routine Description:
Arguments:
DeviceObject - Fdo for USB HC
Return Value:
none.
--*/
{
PDEVICE_EXTENSION devExt;
USB_MINIPORT_STATUS mpStatus;
HW_32BIT_PHYSICAL_ADDRESS phys;
PUCHAR va, mpData;
ULONG length, mpDataLength;
MP_PACKET_PARAMETERS mpPacket;
USBD_STATUS usbdStatus;
USB_USER_ERROR_CODE usbUserStatus;
UCHAR data[4];
USBPORT_KdPrint((1, "'USBPORT_TransmitTriggerPacket\n"));
ASSERT_PASSIVE();
GET_DEVICE_EXT(devExt, FdoDeviceObject);
ASSERT_FDOEXT(devExt);
LOGENTRY(NULL, FdoDeviceObject, LOG_MISC, 'TRIG', &mpPacket, 0,
0);
// build up request for miniport
length = devExt->Fdo.ScratchCommonBuffer->MiniportLength;
va = devExt->Fdo.ScratchCommonBuffer->MiniportVa;
phys = devExt->Fdo.ScratchCommonBuffer->MiniportPhys;
mpPacket.DeviceAddress = 127;
mpPacket.EndpointAddress = 8;
mpPacket.MaximumPacketSize = 64;
mpPacket.Type = ss_Out;
mpPacket.Speed = ss_Full;
mpPacket.Toggle = ss_Toggle0;
data[0] = 'G';
data[1] = 'O';
data[2] = 'A';
data[3] = 'T';
mpData = &data[0];
mpDataLength = sizeof(data);
MP_StartSendOnePacket(devExt,
&mpPacket,
mpData,
&mpDataLength,
va,
phys,
length,
&usbdStatus,
mpStatus);
}
VOID
USBPORT_EndTransmitTriggerPacket(
PDEVICE_OBJECT FdoDeviceObject
)
/*++
Routine Description:
Arguments:
DeviceObject - Fdo for USB HC
Return Value:
none.
--*/
{
PDEVICE_EXTENSION devExt;
USB_MINIPORT_STATUS mpStatus;
HW_32BIT_PHYSICAL_ADDRESS phys;
PUCHAR va, mpData;
ULONG length, mpDataLength;
MP_PACKET_PARAMETERS mpPacket;
USBD_STATUS usbdStatus;
UCHAR data[4];
USBPORT_KdPrint((1, "'USBPORT_TransmitTriggerPacket\n"));
ASSERT_PASSIVE();
GET_DEVICE_EXT(devExt, FdoDeviceObject);
ASSERT_FDOEXT(devExt);
mpData = &data[0];
mpDataLength = sizeof(data);
length = devExt->Fdo.ScratchCommonBuffer->MiniportLength;
va = devExt->Fdo.ScratchCommonBuffer->MiniportVa;
phys = devExt->Fdo.ScratchCommonBuffer->MiniportPhys;
USBPORT_Wait(FdoDeviceObject, 10);
MP_EndSendOnePacket(devExt,
&mpPacket,
mpData,
&mpDataLength,
va,
phys,
length,
&usbdStatus,
mpStatus);
USBPORT_KdPrint((1, "'<ANALYZER TRIGER FIRED>\n"));
DbgBreakPoint();
}
VOID
USBPORT_CatcTrap(
PDEVICE_OBJECT FdoDeviceObject
)
/*++
Routine Description:
Arguments:
Return Value:
none.
--*/
{
PDEVICE_EXTENSION devExt;
GET_DEVICE_EXT(devExt, FdoDeviceObject);
ASSERT_FDOEXT(devExt);
if (KeGetCurrentIrql() > PASSIVE_LEVEL) {
USBPORT_BeginTransmitTriggerPacket(FdoDeviceObject);
SET_FDO_FLAG(devExt, USBPORT_FDOFLAG_CATC_TRAP);
} else {
TEST_TRAP();
USBPORT_BeginTransmitTriggerPacket(FdoDeviceObject);
USBPORT_EndTransmitTriggerPacket(FdoDeviceObject);
}
}
VOID
USBPORT_EnumLogEntry(
PDEVICE_OBJECT FdoDeviceObject,
ULONG DriverTag,
ULONG EnumTag,
ULONG P1,
ULONG P2
)
/*++
Routine Description:
Enumeration Log, this is where any USB device driver may log a failure
to track failure causes
Arguments:
Return Value:
None.
--*/
{
KIRQL irql;
PDEVICE_EXTENSION devExt;
GET_DEVICE_EXT(devExt, FdoDeviceObject);
ASSERT_FDOEXT(devExt);
if (devExt->EnumLog.LogStart == 0) {
return;
}
USBPORT_AddLogEntry(
&devExt->EnumLog,
0xFFFFFFFF,
EnumTag,
(ULONG_PTR) DriverTag,
(ULONG_PTR) P1,
(ULONG_PTR) P2,
FALSE);
}