mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 09:03:43 +00:00 
			
		
		
		
	git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3191 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			346 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			346 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
 | 
						|
Copyright (c) 2007, Intel Corporation
 | 
						|
All rights reserved. This program and the accompanying materials
 | 
						|
are licensed and made available under the terms and conditions of the BSD License
 | 
						|
which accompanies this distribution.  The full text of the license may be found at
 | 
						|
http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
Module Name:
 | 
						|
 | 
						|
    EhciDebug.c
 | 
						|
 | 
						|
Abstract:
 | 
						|
  This file provides the information dump support for EHCI when in debug mode.
 | 
						|
You can dynamically adjust the debug level by changing variable mEhcDebugLevel
 | 
						|
and mEhcErrorLevel.
 | 
						|
 | 
						|
Revision History
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
 | 
						|
#include "Ehci.h"
 | 
						|
 | 
						|
#ifdef EFI_DEBUG
 | 
						|
UINTN mEhcDebugMask   = USB_DEBUG_FORCE_OUTPUT;
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  EHCI's debug output function. It determines whether
 | 
						|
  to output by the mask and level
 | 
						|
 | 
						|
  @param  Level    The output level
 | 
						|
  @param  Format   The format parameters to the print
 | 
						|
  @param  ...      The variable length parameters after format
 | 
						|
 | 
						|
  @return None
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EhciDebugPrint (
 | 
						|
  IN  UINTN               Level,
 | 
						|
  IN  CHAR8               *Format,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
 | 
						|
  VA_LIST                 Marker;
 | 
						|
 | 
						|
  VA_START (Marker, Format);
 | 
						|
 | 
						|
  if (Level & mEhcDebugMask) {
 | 
						|
    if (mEhcDebugMask & USB_DEBUG_FORCE_OUTPUT) {
 | 
						|
      DebugVPrint (DEBUG_ERROR, Format, Marker);
 | 
						|
    } else {
 | 
						|
      DebugVPrint (DEBUG_INFO, Format, Marker);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  VA_END (Marker);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  EHCI's debug output function. It determines whether
 | 
						|
  to output by the mask and level
 | 
						|
 | 
						|
  @param  Format   The format parameters to the print
 | 
						|
  @param  ...      The variable length parameters after format
 | 
						|
 | 
						|
  @return None
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EhcDebug (
 | 
						|
  IN  CHAR8               *Format,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
  VA_LIST                 Marker;
 | 
						|
 | 
						|
  VA_START (Marker, Format);
 | 
						|
  DebugVPrint (DEBUG_INFO, Format, Marker);
 | 
						|
  VA_END (Marker);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  EHCI's error output function. It determines whether
 | 
						|
  to output by the mask and level
 | 
						|
 | 
						|
  @param  Format   The format parameters to the print
 | 
						|
  @param  ...      The variable length parameters after format
 | 
						|
 | 
						|
  @return None
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EhcError (
 | 
						|
  IN  CHAR8               *Format,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
 | 
						|
  VA_LIST                 Marker;
 | 
						|
 | 
						|
  VA_START (Marker, Format);
 | 
						|
  DebugVPrint (DEBUG_ERROR, Format, Marker);
 | 
						|
  VA_END (Marker);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Dump the status byte in QTD/QH to a more friendly
 | 
						|
  format
 | 
						|
 | 
						|
  @param  State    The state in the QTD/QH
 | 
						|
  @param  Level    The output level
 | 
						|
 | 
						|
  @return None
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
EhcDumpStatus (
 | 
						|
  IN UINT32               State,
 | 
						|
  IN UINTN                Level
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (EHC_BIT_IS_SET (State, QTD_STAT_DO_PING)) {
 | 
						|
    EhciDebugPrint (Level, "  Do_Ping");
 | 
						|
  } else {
 | 
						|
    EhciDebugPrint (Level, "  Do_Out");
 | 
						|
  }
 | 
						|
 | 
						|
  if (EHC_BIT_IS_SET (State, QTD_STAT_DO_CS)) {
 | 
						|
    EhciDebugPrint (Level, "  Do_CS");
 | 
						|
  } else {
 | 
						|
    EhciDebugPrint (Level, "  Do_SS");
 | 
						|
  }
 | 
						|
 | 
						|
  if (EHC_BIT_IS_SET (State, QTD_STAT_TRANS_ERR)) {
 | 
						|
    EhciDebugPrint (Level, "  Transfer_Error");
 | 
						|
  }
 | 
						|
 | 
						|
  if (EHC_BIT_IS_SET (State, QTD_STAT_BABBLE_ERR)) {
 | 
						|
    EhciDebugPrint (Level, "  Babble_Error");
 | 
						|
  }
 | 
						|
 | 
						|
  if (EHC_BIT_IS_SET (State, QTD_STAT_BUFF_ERR)) {
 | 
						|
    EhciDebugPrint (Level, "  Buffer_Error");
 | 
						|
  }
 | 
						|
 | 
						|
  if (EHC_BIT_IS_SET (State, QTD_STAT_HALTED)) {
 | 
						|
    EhciDebugPrint (Level, "  Halted");
 | 
						|
  }
 | 
						|
 | 
						|
  if (EHC_BIT_IS_SET (State, QTD_STAT_ACTIVE)) {
 | 
						|
    EhciDebugPrint (Level, "  Active");
 | 
						|
  }
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "\n");
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Dump the fields of a QTD
 | 
						|
 | 
						|
  @param  Qtd      The QTD to dump
 | 
						|
  @param  Msg      The message to print before the dump
 | 
						|
 | 
						|
  @return None
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EhcDumpQtd (
 | 
						|
  IN EHC_QTD              *Qtd,
 | 
						|
  IN UINT8                *Msg
 | 
						|
  )
 | 
						|
{
 | 
						|
  QTD_HW                  *QtdHw;
 | 
						|
  UINTN                   Index;
 | 
						|
  UINTN                   Level;
 | 
						|
 | 
						|
  Level = EHC_DEBUG_QTD;
 | 
						|
 | 
						|
  if (Msg != NULL) {
 | 
						|
    EhciDebugPrint (Level, Msg);
 | 
						|
  }
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "Queue TD @ 0x%x, data length %d\n", Qtd, Qtd->DataLen);
 | 
						|
 | 
						|
  QtdHw = &Qtd->QtdHw;
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "Next QTD     : %x\n", QtdHw->NextQtd);
 | 
						|
  EhciDebugPrint (Level, "AltNext QTD  : %x\n", QtdHw->AltNext);
 | 
						|
  EhciDebugPrint (Level, "Status       : %x\n", QtdHw->Status);
 | 
						|
  EhcDumpStatus (QtdHw->Status, Level);
 | 
						|
 | 
						|
  if (QtdHw->Pid == QTD_PID_SETUP) {
 | 
						|
    EhciDebugPrint (Level, "PID          : Setup\n");
 | 
						|
 | 
						|
  } else if (QtdHw->Pid == QTD_PID_INPUT) {
 | 
						|
    EhciDebugPrint (Level, "PID          : IN\n");
 | 
						|
 | 
						|
  } else if (QtdHw->Pid == QTD_PID_OUTPUT) {
 | 
						|
    EhciDebugPrint (Level, "PID          : OUT\n");
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "Error Count  : %d\n", QtdHw->ErrCnt);
 | 
						|
  EhciDebugPrint (Level, "Current Page : %d\n", QtdHw->CurPage);
 | 
						|
  EhciDebugPrint (Level, "IOC          : %d\n", QtdHw->IOC);
 | 
						|
  EhciDebugPrint (Level, "Total Bytes  : %d\n", QtdHw->TotalBytes);
 | 
						|
  EhciDebugPrint (Level, "Data Toggle  : %d\n", QtdHw->DataToggle);
 | 
						|
 | 
						|
  for (Index = 0; Index < 5; Index++) {
 | 
						|
    EhciDebugPrint (Level, "Page[%d]      : 0x%x\n", Index, QtdHw->Page[Index]);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Dump the queue head
 | 
						|
 | 
						|
  @param  Qh       The queue head to dump
 | 
						|
  @param  Msg      The message to print before the dump
 | 
						|
  @param  DumpBuf  Whether to dump the memory buffer of the associated QTD
 | 
						|
 | 
						|
  @return None
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EhcDumpQh (
 | 
						|
  IN EHC_QH               *Qh,
 | 
						|
  IN UINT8                *Msg,
 | 
						|
  IN BOOLEAN              DumpBuf
 | 
						|
  )
 | 
						|
{
 | 
						|
  EHC_QTD                 *Qtd;
 | 
						|
  QH_HW                   *QhHw;
 | 
						|
  LIST_ENTRY              *Entry;
 | 
						|
  UINTN                   Index;
 | 
						|
  UINTN                   Level;
 | 
						|
 | 
						|
  Level = EHC_DEBUG_QH;
 | 
						|
 | 
						|
  if (Msg != NULL) {
 | 
						|
    EhciDebugPrint (Level, Msg);
 | 
						|
  }
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "Queue head @ 0x%x, interval %d, next qh %x\n",
 | 
						|
                                Qh, Qh->Interval, Qh->NextQh);
 | 
						|
 | 
						|
  QhHw = &Qh->QhHw;
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "Hoziontal link: %x\n", QhHw->HorizonLink);
 | 
						|
  EhciDebugPrint (Level, "Device address: %d\n", QhHw->DeviceAddr);
 | 
						|
  EhciDebugPrint (Level, "Inactive      : %d\n", QhHw->Inactive);
 | 
						|
  EhciDebugPrint (Level, "EP number     : %d\n", QhHw->EpNum);
 | 
						|
  EhciDebugPrint (Level, "EP speed      : %d\n", QhHw->EpSpeed);
 | 
						|
  EhciDebugPrint (Level, "DT control    : %d\n", QhHw->DtCtrl);
 | 
						|
  EhciDebugPrint (Level, "Reclaim head  : %d\n", QhHw->ReclaimHead);
 | 
						|
  EhciDebugPrint (Level, "Max packet len: %d\n", QhHw->MaxPacketLen);
 | 
						|
  EhciDebugPrint (Level, "Ctrl EP       : %d\n", QhHw->CtrlEp);
 | 
						|
  EhciDebugPrint (Level, "Nak reload    : %d\n", QhHw->NakReload);
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "SMask         : %x\n", QhHw->SMask);
 | 
						|
  EhciDebugPrint (Level, "CMask         : %x\n", QhHw->CMask);
 | 
						|
  EhciDebugPrint (Level, "Hub address   : %d\n", QhHw->HubAddr);
 | 
						|
  EhciDebugPrint (Level, "Hub port      : %d\n", QhHw->PortNum);
 | 
						|
  EhciDebugPrint (Level, "Multiplier    : %d\n", QhHw->Multiplier);
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "Cur QTD       : %x\n", QhHw->CurQtd);
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "Next QTD      : %x\n", QhHw->NextQtd);
 | 
						|
  EhciDebugPrint (Level, "AltNext QTD   : %x\n", QhHw->AltQtd);
 | 
						|
  EhciDebugPrint (Level, "Status        : %x\n", QhHw->Status);
 | 
						|
  EhcDumpStatus (QhHw->Status, Level);
 | 
						|
 | 
						|
  if (QhHw->Pid == QTD_PID_SETUP) {
 | 
						|
    EhciDebugPrint (Level, "PID           : Setup\n");
 | 
						|
 | 
						|
  } else if (QhHw->Pid == QTD_PID_INPUT) {
 | 
						|
    EhciDebugPrint (Level, "PID           : IN\n");
 | 
						|
 | 
						|
  } else if (QhHw->Pid == QTD_PID_OUTPUT) {
 | 
						|
    EhciDebugPrint (Level, "PID           : OUT\n");
 | 
						|
  }
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "Error Count   : %d\n", QhHw->ErrCnt);
 | 
						|
  EhciDebugPrint (Level, "Current Page  : %d\n", QhHw->CurPage);
 | 
						|
  EhciDebugPrint (Level, "IOC           : %d\n", QhHw->IOC);
 | 
						|
  EhciDebugPrint (Level, "Total Bytes   : %d\n", QhHw->TotalBytes);
 | 
						|
  EhciDebugPrint (Level, "Data Toggle   : %d\n", QhHw->DataToggle);
 | 
						|
 | 
						|
  for (Index = 0; Index < 5; Index++) {
 | 
						|
    EhciDebugPrint (Level, "Page[%d]       : 0x%x\n", Index, QhHw->Page[Index]);
 | 
						|
  }
 | 
						|
 | 
						|
  EhciDebugPrint (Level, "\n");
 | 
						|
 | 
						|
  EFI_LIST_FOR_EACH (Entry, &Qh->Qtds) {
 | 
						|
    Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList);
 | 
						|
    EhcDumpQtd (Qtd, NULL);
 | 
						|
 | 
						|
    if (DumpBuf && (Qtd->DataLen != 0)) {
 | 
						|
      EhcDumpBuf (Qtd->Data, Qtd->DataLen);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Dump the buffer in the form of hex
 | 
						|
 | 
						|
  @param  Buf      The buffer to dump
 | 
						|
  @param  Len      The length of buffer
 | 
						|
 | 
						|
  @return None
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EhcDumpBuf (
 | 
						|
  IN UINT8                *Buf,
 | 
						|
  IN UINTN                Len
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                   Index;
 | 
						|
 | 
						|
  for (Index = 0; Index < Len; Index++) {
 | 
						|
    if (Index % 16 == 0) {
 | 
						|
      EhciDebugPrint (EHC_DEBUG_BUF, "\n");
 | 
						|
    }
 | 
						|
 | 
						|
    EhciDebugPrint (EHC_DEBUG_BUF, "%02x ", Buf[Index]);
 | 
						|
  }
 | 
						|
 | 
						|
  EhciDebugPrint (EHC_DEBUG_BUF, "\n");
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |