📄 cpipe.hpp
字号:
IN const UCHAR Endpoint,
IN const USHORT DataToggle,
IN const DWORD MaxLength,
IN const PUCHAR HW_vaBuffer,
IN const BOOL bShortPacketOk = FALSE);
void InitializeQH( OUT PUHCD_QH const pQH,
IN const PUHCD_QH vaPrevQH,
IN const QUEUE_HEAD_LINK_POINTER_PHYSICAL_ADDRESS HW_paHLink,
IN const PUHCD_QH vaNextQH );
// Return the index of the m_interruptQHTree that this frame should point to
inline UCHAR QHTreeEntry( IN const DWORD frame )
{
DEBUGCHK( frame >= 0 && frame < FRAME_LIST_LENGTH );
// return interval + (frame % interval)
DEBUGCHK( frame % UHCD_MAX_INTERRUPT_INTERVAL == (frame & (UHCD_MAX_INTERRUPT_INTERVAL - 1)) );
return UCHAR( UHCD_MAX_INTERRUPT_INTERVAL + (frame & (UHCD_MAX_INTERRUPT_INTERVAL - 1)) );
};
//----------------------------------------------------------------------------
class CUHCIFrame {
friend class CPipe;
friend class CIsochronousPipe;
friend class CQueuedPipe;
friend class CControlPipe;
friend class CInterruptPipe;
friend class CBulkPipe;
public:
CUHCIFrame(IN CPhysMem* const pCPhysMem );
~CUHCIFrame();
BOOL Initialize( CUhcd * m_pCUhcd );
void DeInitialize( void );
inline ULONG GetFrameListPhysAddr( void )
{
DEBUGCHK( m_vaFrameList != NULL );
DEBUGCHK( m_pCPhysMem->VaToPa( PUCHAR( m_vaFrameList ) ) % FRAME_LIST_SIZE_IN_BYTES == 0 );
return m_pCPhysMem->VaToPa( PUCHAR( m_vaFrameList ) );
};
inline ULONG GetQHPhysAddr( IN PUHCD_QH virtAddr ) {
DEBUGCHK( virtAddr != NULL &&
m_pCPhysMem->VaToPa( PUCHAR(virtAddr) ) % QH_ALIGNMENT_BOUNDARY == 0 );
return m_pCPhysMem->VaToPa( PUCHAR(virtAddr) );
}
inline ULONG GetTDPhysAddr( IN PUHCD_TD virtAddr ) {
DEBUGCHK( virtAddr != NULL &&
m_pCPhysMem->VaToPa( PUCHAR(virtAddr) ) % TD_ALIGNMENT_BOUNDARY == 0 );
return m_pCPhysMem->VaToPa( PUCHAR(virtAddr) );
}
void SignalCheckForDoneTransfers( void );
void HandleReclamationLoadChange( IN const BOOL fAddingTransfer );
private:
// ****************************************************
// Private Functions for CPipe
// ****************************************************
static ULONG CALLBACK CheckForDoneTransfersThreadStub( IN PVOID pContext);
ULONG CheckForDoneTransfersThread();
// ****************************************************
// Private Variables for CPipe
// ****************************************************
#ifdef DEBUG
BOOL m_debug_fInitializeAlreadyCalled;
#endif // DEBUG
// CheckForDoneTransfersThread related variables
BOOL m_fCheckTransferThreadClosing; // signals CheckForDoneTransfersThread to exit
HANDLE m_hCheckForDoneTransfersEvent; // event for CheckForDoneTransfersThread
HANDLE m_hCheckForDoneTransfersThread; // thread for handling done transfers
CRITICAL_SECTION m_csBusyPipeListLock;
PPIPE_LIST_ELEMENT m_pBusyPipeList;
#ifdef DEBUG
int m_debug_numItemsOnBusyPipeList;
#endif // DEBUG
UINT numReclamationTransfers;
public:
BOOL AddToBusyPipeList( IN CPipe* const pPipe,
IN const BOOL fHighPriority );
void RemoveFromBusyPipeList( IN CPipe* const pPipe );
void InsertIsochTDIntoFrameList( IN_OUT PUHCD_TD pTD,
IN const DWORD dwFrameIndex );
void RemoveIsochTDFromFrameList( IN_OUT PUHCD_TD pTD,
IN const DWORD dwFrameIndex );
CPhysMem * const m_pCPhysMem; // memory object for our TD/QH and Frame list alloc
// ****************************************************
// Protected Variables for CPipe
// ****************************************************
private:
CUhcd * m_pCUhcd;
// schedule related vars
CRITICAL_SECTION m_csFrameListLock; // critical section for frame list
PULONG m_vaFrameList; // virtual address of Frame List
CRITICAL_SECTION m_csQHScheduleLock; // crit sec for QH section of schedule
PUHCD_QH m_interruptQHTree[ 2 * UHCD_MAX_INTERRUPT_INTERVAL ];
// array to keep track of the binary tree containing
// the interrupt queue heads.
PUHCD_QH m_pFinalQH; // final QH in the schedule
PUHCD_TD m_pFrameSynchTD; // for keeping the software frame counter in sync
#ifdef DEBUG
int m_debug_TDMemoryAllocated;
int m_debug_QHMemoryAllocated;
int m_debug_BufferMemoryAllocated;
int m_debug_ControlExtraMemoryAllocated;
#endif // DEBUG
};
class CPipe : public CPipeAbs
{
friend class CUHCIFrame; // Declare a friend class
public:
// ****************************************************
// Public Functions for CPipe
// ****************************************************
CPipe( IN const LPCUSB_ENDPOINT_DESCRIPTOR lpEndpointDescriptor,
IN const BOOL fIsLowSpeed,
IN CUHCIFrame *const pUHCIFrame);
virtual ~CPipe();
virtual HCD_REQUEST_STATUS OpenPipe( void ) = 0;
virtual HCD_REQUEST_STATUS ClosePipe( void ) = 0;
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 );
virtual HCD_REQUEST_STATUS AbortTransfer(
IN const LPTRANSFER_NOTIFY_ROUTINE lpCancelAddress,
IN const LPVOID lpvNotifyParameter,
IN LPCVOID lpvCancelId ) = 0;
HCD_REQUEST_STATUS IsPipeHalted( OUT LPBOOL const lpbHalted );
void ClearHaltedFlag( void );
virtual void ResetToggle( void )=0;
#ifdef DEBUG
static void DumpTransfer( const STransfer *pTransfer );
#endif
// ****************************************************
// Public Variables for CPipe
// ****************************************************
UCHAR m_bEndpointAddress;
// UCHAR m_bEzhostPortNum; //sie number for ezhost
protected:
CUHCIFrame * const m_pUHCIFrame;
// ****************************************************
// Protected Functions for CPipe
// ****************************************************
#ifdef DEBUG
virtual const TCHAR* GetPipeType( void ) const = 0;
#endif // DEBUG
virtual USHORT GetNumTDsNeeded( const STransfer *pTransfer = NULL ) const = 0;
virtual BOOL AreTransferParametersValid( const STransfer *pTransfer = NULL ) const = 0;
virtual BOOL CheckForDoneTransfers( void ) = 0;
virtual DWORD GetMemoryAllocationFlags( void ) const;
virtual HCD_REQUEST_STATUS ScheduleTransfer( void ) = 0;
virtual HCD_REQUEST_STATUS AddTransfer( STransfer *pTransfer )
// The default defn simply disallows the queueing of multiple transfers.
{ /* compiler wants this referenced: */ (void) pTransfer;
return m_fTransferInProgress ? requestFailed : requestOK; };
void FreeTransferMemory( STransfer *pTransfer = NULL );
inline ULONG GetTDPhysAddr( IN PUHCD_TD virtAddr ) {
DEBUGCHK( virtAddr != NULL &&
m_pUHCIFrame->m_pCPhysMem->VaToPa( PUCHAR(virtAddr) ) % TD_ALIGNMENT_BOUNDARY == 0 );
return m_pUHCIFrame->m_pCPhysMem->VaToPa( PUCHAR(virtAddr) );
}
inline ULONG GetQHPhysAddr( IN PUHCD_QH virtAddr ) {
DEBUGCHK( virtAddr != NULL &&
m_pUHCIFrame->m_pCPhysMem->VaToPa( PUCHAR(virtAddr) ) % QH_ALIGNMENT_BOUNDARY == 0 );
return m_pUHCIFrame->m_pCPhysMem->VaToPa( PUCHAR(virtAddr) );
}
protected:
// pipe specific variables
CRITICAL_SECTION m_csPipeLock; // crit sec for this specific pipe's variables
USB_ENDPOINT_DESCRIPTOR m_usbEndpointDescriptor; // descriptor for this pipe's endpoint
BOOL m_fIsLowSpeed; // indicates speed of this pipe
BOOL m_fIsHalted; // indicates pipe is halted
BOOL m_fTransferInProgress; // indicates if this pipe is currently executing a transfer
// WARNING! These parameters are treated as a unit. They
// can all be wiped out at once, for example when a
// transfer is aborted.
STransfer m_transfer; // Parameters for transfer on pipe
STransfer * m_pLastTransfer; // ptr to last transfer in queue
};
class CQueuedPipe : public CPipe
{
public:
// ****************************************************
// Public Functions for CQueuedPipe
// ****************************************************
CQueuedPipe( IN const LPCUSB_ENDPOINT_DESCRIPTOR lpEndpointDescriptor,
IN const BOOL fIsLowSpeed,
IN CUhcd *const pCUhcd);
virtual ~CQueuedPipe();
HCD_REQUEST_STATUS ClosePipe( void );
HCD_REQUEST_STATUS AbortTransfer(
IN const LPTRANSFER_NOTIFY_ROUTINE lpCancelAddress,
IN const LPVOID lpvNotifyParameter,
IN LPCVOID lpvCancelId );
void ResetToggle( void ){m_dataToggleQ = 1; m_dataToggleC = 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -