📄 chw.h
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Module Name:
// chw.h
//
// Abstract: Provides interface to UHCI host controller
//
// Notes:
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2005-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
#ifndef __CHW_H__
#define __CHW_H__
#include <usb200.h>
#include <sync.hpp>
#include <CRegEdit.h>
#include <hcd.hpp>
#include "cpipe.h"
#include <csp.h>
#define EHCI_REG_IntThreshCtrl TEXT("IntThreshCtrl")
#define EHCI_REG_IntThreshCtrl_DEFAULT 8
class CHW;
class CEhcd;
typedef struct _PERIOD_TABLE {
UCHAR Period;
UCHAR qhIdx;
UCHAR InterruptScheduleMask;
} PERIOD_TABLE, *PPERIOD_TABLE;
//-----------------------------------Dummy Queue Head for static QHEad ---------------
class CDummyPipe : public CPipe
{
public:
// ****************************************************
// Public Functions for CQueuedPipe
// ****************************************************
CDummyPipe(IN CPhysMem * const pCPhysMem);
virtual ~CDummyPipe() {;};
// inline const int GetTdSize( void ) const { return sizeof(TD); };
HCD_REQUEST_STATUS IssueTransfer(
IN const UCHAR /*address*/,
IN LPTRANSFER_NOTIFY_ROUTINE const /*lpfnCallback*/,
IN LPVOID const /*lpvCallbackParameter*/,
IN const DWORD /*dwFlags*/,
IN LPCVOID const /*lpvControlHeader*/,
IN const DWORD /*dwStartingFrame*/,
IN const DWORD /*dwFrames*/,
IN LPCDWORD const /*aLengths*/,
IN const DWORD /*dwBufferSize*/,
IN_OUT LPVOID const /*lpvBuffer*/,
IN const ULONG /*paBuffer*/,
IN LPCVOID const /*lpvCancelId*/,
OUT LPDWORD const /*adwIsochErrors*/,
OUT LPDWORD const /*adwIsochLengths*/,
OUT LPBOOL const /*lpfComplete*/,
OUT LPDWORD const /*lpdwBytesTransferred*/,
OUT LPDWORD const /*lpdwError*/ )
{ return requestFailed;};
virtual HCD_REQUEST_STATUS OpenPipe( void )
{ return requestFailed;};
virtual HCD_REQUEST_STATUS ClosePipe( void )
{ return requestFailed;};
virtual HCD_REQUEST_STATUS IsPipeHalted( OUT LPBOOL const /*lpbHalted*/ )
{
ASSERT(FALSE);
return requestFailed;
};
virtual void ClearHaltedFlag( void ) {;};
void StopTransfers(void) { return;};
HCD_REQUEST_STATUS AbortTransfer(
IN const LPTRANSFER_NOTIFY_ROUTINE /*lpCancelAddress*/,
IN const LPVOID /*lpvNotifyParameter*/,
IN LPCVOID /*lpvCancelId*/ )
{return requestFailed;};
// ****************************************************
// Public Variables for CQueuedPipe
// ****************************************************
virtual CPhysMem * GetCPhysMem() {return m_pCPhysMem;};
private:
// ****************************************************
// Private Functions for CQueuedPipe
// ****************************************************
void AbortQueue( void ) { ; };
HCD_REQUEST_STATUS ScheduleTransfer( void ) { return requestFailed;};
// ****************************************************
// Private Variables for CQueuedPipe
// ****************************************************
IN CPhysMem * const m_pCPhysMem;
protected:
// ****************************************************
// Protected Functions for CQueuedPipe
// ****************************************************
//#ifdef DEBUG
const TCHAR* GetPipeType( void ) const
{
static const TCHAR* cszPipeType = TEXT("Dummy");
return cszPipeType;
}
//#endif // DEBUG
virtual BOOL AreTransferParametersValid( const STransfer * /*pTransfer = NULL*/ ) const { return FALSE;};
BOOL CheckForDoneTransfers( void ) { return FALSE; };
};
class CPeriodicMgr : public LockObject {
public:
CPeriodicMgr(IN CPhysMem * const pCPhysMem, DWORD dwFlameSize);
~CPeriodicMgr();
BOOL Init();
void DeInit() ;
DWORD GetFrameSize() { return m_dwFrameSize; };
private:
CPhysMem * const m_pCPhysMem;
//Frame;
CDummyPipe * const m_pCDumpPipe;
public:
DWORD GetFrameListPhysAddr() { return m_pFramePhysAddr; };
private:
const DWORD m_dwFrameSize;
// Isoch Periodic List.
DWORD m_pFramePhysAddr;
DWORD m_dwFrameMask;
volatile DWORD * m_pFrameList; // point to dword (physical address)
// Periodic For Interrupt.
#define PERIOD_TABLE_SIZE 32
CQH * m_pStaticQHArray[2*PERIOD_TABLE_SIZE];
PBYTE m_pStaticQH;
// Interrupt Endpoint Span
public:
// ITD Service.
BOOL QueueITD(CITD * piTD,DWORD FrameIndex);
BOOL QueueSITD(CSITD * psiTD,DWORD FrameIndex);
BOOL DeQueueTD(DWORD dwPhysAddr,DWORD FrameIndex);
// Pseriodic Qhead Service
CQH * QueueQHead(CQH * pQh,UCHAR uInterval,UCHAR offset,BOOL bHighSpeed);
BOOL DequeueQHead( CQH * pQh);
private:
static PERIOD_TABLE periodTable[64];
};
class CAsyncMgr: public LockObject {
public:
CAsyncMgr(IN CPhysMem * const pCPhysMem);
~CAsyncMgr();
BOOL Init();
void DeInit() ;
private:
CPhysMem * const m_pCPhysMem;
//Frame;
CDummyPipe * const m_pCDumpPipe;
CQH * m_pStaticQHead;
public:
DWORD GetPhysAddr() { return (m_pStaticQHead?m_pStaticQHead->GetPhysAddr():0); };
public:
// Service.
CQH * QueueQH(CQH * pQHead);
BOOL DequeueQHead( CQH * pQh);
};
typedef struct _PIPE_LIST_ELEMENT {
CPipe* pPipe;
struct _PIPE_LIST_ELEMENT * pNext;
} PIPE_LIST_ELEMENT, *PPIPE_LIST_ELEMENT;
class CBusyPipeList : public LockObject {
public:
CBusyPipeList(DWORD dwFrameSize) { m_FrameListSize=dwFrameSize;};
~CBusyPipeList() {DeInit();};
BOOL Init();
void DeInit();
BOOL AddToBusyPipeList( IN CPipe * const pPipe, IN const BOOL fHighPriority );
void RemoveFromBusyPipeList( IN CPipe * const pPipe );
void SignalCheckForDoneTransfers( void );
private:
// ****************************************************
// Private Functions for CPipe
// ****************************************************
static ULONG CALLBACK CheckForDoneTransfersThreadStub( IN PVOID pContext);
ULONG CheckForDoneTransfersThread();
private:
DWORD m_FrameListSize ;
// ****************************************************
// Private Variables for CPipe
// ****************************************************
// CheckForDoneTransfersThread related variables
BOOL m_fCheckTransferThreadClosing; // signals CheckForDoneTransfersThread to exit
HANDLE m_hCheckForDoneTransfersEvent; // event for CheckForDoneTransfersThread
HANDLE m_hCheckForDoneTransfersThread; // thread for handling done transfers
PPIPE_LIST_ELEMENT m_pBusyPipeList;
#ifdef DEBUG
int m_debug_numItemsOnBusyPipeList;
#endif // DEBUG
};
// this class is an encapsulation of UHCI hardware registers.
class CHW : public CHcd {
public:
// ****************************************************
// public Functions
// ****************************************************
//
// Hardware Init/Deinit routines
//
CHW( IN const REGISTER portBase,
IN const DWORD dwSysIntr,
IN CPhysMem * const pCPhysMem,
//IN CUhcd * const pHcd,
IN LPVOID pvUhcdPddObject,
IN LPCTSTR lpDeviceRegistry);
~CHW();
virtual BOOL Initialize();
virtual void DeInitialize( void );
virtual void SignalCheckForDoneTransfers( void ) {
m_cBusyPipeList.SignalCheckForDoneTransfers();
};
void EnterOperationalState(void);
void StopHostController(void);
void RunStopUSBController(BOOL fRun);
//
// Functions to Query frame values
//
BOOL GetFrameNumber( OUT LPDWORD lpdwFrameNumber );
BOOL GetFrameLength( OUT LPUSHORT lpuFrameLength );
BOOL SetFrameLength( IN HANDLE hEvent,
IN USHORT uFrameLength );
BOOL StopAdjustingFrame( void );
BOOL WaitOneFrame( void );
//
// Root Hub Queries
//
BOOL DidPortStatusChange( IN const UCHAR port );
BOOL GetPortStatus( IN const UCHAR port,
OUT USB_HUB_AND_PORT_STATUS& rStatus,
OUT PDWORD pdwForceDetach);
BOOL RootHubFeature( IN const UCHAR port,
IN const UCHAR setOrClearFeature,
IN const USHORT feature );
BOOL ResetAndEnablePort( IN const UCHAR port );
void DisablePort( IN const UCHAR port );
BOOL IsOTGHostDevice(void); // 0 - A device, 1 - B device
virtual BOOL WaitForPortStatusChange (HANDLE m_hHubChanged);
//
// Miscellaneous bits
//
PULONG GetFrameListAddr( ) { return m_pFrameList; };
// PowerCallback
VOID PowerMgmtCallback( IN BOOL fOff );
// iMx31 - non EHCI standard
// 00 - Full Speed, 01 - Low Speed, 10 - High Speed, 11 - Unknown
USHORT GetPortSpeed (IN const USHORT port);
BOOL EnableAsyncSchedule();
BOOL DisableAsyncSchedule();
BOOL PowerOnAllPorts();
BOOL ConfigureHS();
void WriteAsyncListAddr(IN const DWORD addr);
void StartHostController(void);
DWORD GetForceReAttach() { return m_dwForceReAttach; };
void SetForceReAttach(IN const DWORD dwForceReAttach) { m_dwForceReAttach = dwForceReAttach;};
BOOL StopUSBClock(void);
BOOL StartUSBClock(void);
void WakeUpSysIntr(void);
CRegistryEdit m_deviceReg;
private:
// ****************************************************
// private Functions
// ****************************************************
static DWORD CALLBACK CeResumeThreadStub( IN PVOID context );
DWORD CeResumeThread();
static DWORD CALLBACK UsbInterruptThreadStub( IN PVOID context );
DWORD UsbInterruptThread();
static DWORD CALLBACK UsbAdjustFrameLengthThreadStub( IN PVOID context );
DWORD UsbAdjustFrameLengthThread();
void UpdateFrameCounter( void );
VOID SuspendHostController();
VOID ResumeHostController();
#ifdef DEBUG
// Query Host Controller for registers, and prints contents
void DumpUSBCMD(void);
void DumpUSBSTS(void);
void DumpUSBINTR(void);
void DumpFRNUM(void);
void DumpFLBASEADD(void);
void DumpSOFMOD(void);
void DumpAllRegisters(void);
void DumpPORTSC( IN const USHORT port );
#endif
//
// EHCI USB I/O registers (See UHCI spec, section 2)
//
// EHCI Spec - Section 2.3.1
// USB Command Register (USBCMD)
typedef struct {
DWORD RunStop:1; // Run/Stop
DWORD HCReset:1; //Controller Reset
DWORD FrameListSize:2;
DWORD PSchedEnable:1;
DWORD ASchedEnable:1;
DWORD IntOnAADoorbell:1;
DWORD LHCReset:1;
DWORD ASchedPMCount:2;
DWORD Reserved:1;
DWORD ASchedPMEnable:1;
DWORD Reserved2:4;
DWORD IntThreshCtrl:8;
DWORD Reserved3:8;
} USBCMD_Bit;
typedef union {
volatile USBCMD_Bit bit;
volatile DWORD ul;
} USBCMD;
inline USBCMD Read_USBCMD( void )
{
DEBUGCHK( m_portBase != 0 );
USBCMD usbcmd;
usbcmd.ul=READ_REGISTER_ULONG( ((PULONG) m_portBase) );
return usbcmd;
}
inline void Write_USBCMD( IN const USBCMD data )
{
DEBUGCHK( m_portBase != 0 );
#ifdef DEBUG // added this after accidentally writing to USBCMD instead of USBSTS
if (data.bit.RunStop && data.bit.HCReset && data.bit.LHCReset) {
DEBUGMSG( ZONE_WARNING, (TEXT("!!!Warning!!! Setting resume/suspend/reset bits of USBCMD\n")));
}
#endif // DEBUG
WRITE_REGISTER_ULONG( ((PULONG)m_portBase), data.ul );
}
// EHCI Spec - Section 2.3.2
// USB Status Register (USBSTS)
typedef struct {
DWORD USBINT:1;
DWORD USBERRINT:1;
DWORD PortChanged:1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -