📄 ctd.cpp
字号:
//
// 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:
// CTd.cpp
//
// Abstract: Provides interface to UHCI host controller
//
// Notes:
//
#include <windows.h>
#include "ctd.h"
#include "trans.h"
#include "cpipe.h"
void * CNextLinkPointer::operator new(size_t stSize, CPhysMem * const pCPhysMem)
{
PVOID pVirtAddr=0;
PVOID pReturnLink=NULL;
if (stSize<sizeof(PVOID))
stSize = sizeof(PVOID);
if (pCPhysMem && stSize ) {
while (pVirtAddr==NULL) {
if (!pCPhysMem->AllocateMemory( DEBUG_PARAM( TEXT("CNextLinkPointer")) stSize, (PUCHAR *)&pVirtAddr,CPHYSMEM_FLAG_HIGHPRIORITY | CPHYSMEM_FLAG_NOBLOCK)) {
pVirtAddr=NULL;
break;
}
else {
// Structure can not span 4k Page bound. refer EHCI 3. Note.
DWORD dwPhysAddr = pCPhysMem->VaToPa((PUCHAR)pVirtAddr);
if ((dwPhysAddr & 0xfffff000)!= ((dwPhysAddr + stSize-1) & 0xfffff000)) {
// Cross Page bound. trash it.
pVirtAddr= NULL;
};
}
}
}
return pVirtAddr;
}
void CNextLinkPointer::operator delete(void * /*pointer*/)
{
ASSERT(FALSE); // Can not use this operator.
}
CITD::CITD(CITransfer * pIsochTransfer)
: m_pTrans(pIsochTransfer)
, m_CheckFlag(CITD_CHECK_FLAG_VALUE)
{
ASSERT( (&(nextLinkPointer.dwLinkPointer))+ 15 == (&(iTD_BufferPagePointer[6].dwITD_BufferPagePointer)));// Check for Data Intergraty.
// m_pNext=NULL;
for (DWORD dwCount=0;dwCount<MAX_PHYSICAL_BLOCK;dwCount++)
iTD_BufferPagePointer[dwCount].dwITD_BufferPagePointer = 0;
for (dwCount=0; dwCount<MAX_TRNAS_PER_ITD; dwCount++)
iTD_StatusControl[dwCount].dwITD_StatusControl=0;
m_dwPhys = (m_pTrans?(m_pTrans->m_pCPipe->GetCPhysMem())-> VaToPa((PBYTE)this):0);
}
void CITD::ReInit(CITransfer * pIsochTransfer)
{
nextLinkPointer.dwLinkPointer=1;
m_pTrans =pIsochTransfer ;
for (DWORD dwCount=0;dwCount<MAX_PHYSICAL_BLOCK;dwCount++)
iTD_BufferPagePointer[dwCount].dwITD_BufferPagePointer = 0;
for (dwCount=0; dwCount<MAX_TRNAS_PER_ITD; dwCount++)
iTD_StatusControl[dwCount].dwITD_StatusControl=0;
m_dwPhys = (m_pTrans?(m_pTrans->m_pCPipe->GetCPhysMem())-> VaToPa((PBYTE)this):0);
}
void CITD::SetIOC(BOOL bSet)
{
CheckStructure ();
if (bSet) {
for (int iCount = MAX_TRNAS_PER_ITD-1;iCount>0;iCount--)
if (iTD_StatusControl[iCount].iTD_SCContext.TransactionLength!=0) {
iTD_StatusControl[iCount].iTD_SCContext.InterruptOnComplete=1;
break;
}
}
else {
for (int iCount =0;iCount< MAX_TRNAS_PER_ITD;iCount++)
if (iTD_StatusControl[iCount].iTD_SCContext.TransactionLength!=0)
iTD_StatusControl[iCount].iTD_SCContext.InterruptOnComplete=0;
}
}
DWORD CITD::IssueTransfer(DWORD dwNumOfTrans,PDWORD pdwTransLenArray, PDWORD pdwFrameAddrArray,BOOL bIoc,BOOL bIn)
{
CheckStructure ();
if (dwNumOfTrans ==NULL || dwNumOfTrans>MAX_TRNAS_PER_ITD ||pdwTransLenArray==NULL || pdwFrameAddrArray==NULL) {
ASSERT(FALSE);
return 0;
}
// Initial Buffer Pointer.
for (DWORD dwCount=0;dwCount<MAX_PHYSICAL_BLOCK;dwCount++)
iTD_BufferPagePointer[dwCount].dwITD_BufferPagePointer = 0;
DWORD dwCurBufferPtr=0;
DWORD dwCurValidPage = ((DWORD)-1) & EHCI_PAGE_ADDR_MASK;
for (dwCount=0;dwCount<MAX_TRNAS_PER_ITD +1 && dwCount < dwNumOfTrans +1 && dwCurBufferPtr < MAX_PHYSICAL_BLOCK ;dwCount++) {
if (dwCurValidPage != (*(pdwFrameAddrArray+dwCount)&EHCI_PAGE_ADDR_MASK) ) {
dwCurValidPage = iTD_BufferPagePointer[dwCurBufferPtr].dwITD_BufferPagePointer
= (*(pdwFrameAddrArray+dwCount) ) & EHCI_PAGE_ADDR_MASK;
if (*(pdwTransLenArray +dwCount)==0) { // Endof Transfer
break;
}
dwCurBufferPtr ++;
}
}
USB_ENDPOINT_DESCRIPTOR endptDesc = m_pTrans->m_pCPipe->GetEndptDescriptor();
iTD_BufferPagePointer[0].iTD_BPPContext1.DeviceAddress= m_pTrans->m_pCPipe->GetDeviceAddress();
iTD_BufferPagePointer[0].iTD_BPPContext1.EndPointNumber=endptDesc.bEndpointAddress;
iTD_BufferPagePointer[1].iTD_BPPContext2.MaxPacketSize=endptDesc.wMaxPacketSize & 0x7ff;
iTD_BufferPagePointer[1].iTD_BPPContext2.Direction=(bIn?1:0);
iTD_BufferPagePointer[2].iTD_BPPContext3.Multi=((endptDesc.wMaxPacketSize>>11) & 3)+1;
ASSERT(((endptDesc.wMaxPacketSize>>11)&3)!=3);
// Initial Transaction
dwCurValidPage = (*pdwFrameAddrArray) & EHCI_PAGE_ADDR_MASK;
dwCurBufferPtr=0;
for (dwCount=0; dwCount<MAX_TRNAS_PER_ITD; dwCount++) {
iTD_StatusControl[dwCount].dwITD_StatusControl=0;
if (dwCount < dwNumOfTrans) {
if (dwCurValidPage != (*(pdwFrameAddrArray+dwCount)&EHCI_PAGE_ADDR_MASK)) {
dwCurValidPage = *(pdwFrameAddrArray+dwCount);
dwCurBufferPtr ++;
}
iTD_StatusControl[dwCount].iTD_SCContext.TransactionLength = *(pdwTransLenArray+dwCount);
iTD_StatusControl[dwCount].iTD_SCContext.TransationOffset = (*(pdwFrameAddrArray+dwCount) & EHCI_PAGE_OFFSET_MASK);
iTD_StatusControl[dwCount].iTD_SCContext.PageSelect = dwCurBufferPtr;
iTD_StatusControl[dwCount].iTD_SCContext.Active = 1;
if (dwCount == dwNumOfTrans -1 && bIoc ) { // if thiere is last one and interrupt on completion. do it.
iTD_StatusControl[dwCount].iTD_SCContext.InterruptOnComplete=1;
}
}
}
return (dwNumOfTrans<MAX_TRNAS_PER_ITD?dwNumOfTrans:MAX_TRNAS_PER_ITD);
};
CSITD::CSITD(CSITransfer * pTransfer,CSITD * pPrev)
: m_pTrans(pTransfer)
, m_CheckFlag(CSITD_CHECK_FLAG_VALUE)
{
ASSERT((&(nextLinkPointer.dwLinkPointer))+ 6 == &(backPointer.dwLinkPointer)); // Check for Data Intergraty.
sITD_CapChar.dwSITD_CapChar=0;
microFrameSchCtrl.dwMicroFrameSchCtrl=0;
sITD_TransferState.dwSITD_TransferState=0;
sITD_BPPage[0].dwSITD_BPPage=0;
sITD_BPPage[1].dwSITD_BPPage=0;
backPointer.dwLinkPointer=1; // Invalid Back Link
UCHAR S_Mask = (m_pTrans?m_pTrans->m_pCPipe->GetSMask():1);
ASSERT(S_Mask!=0);
if (S_Mask==0) // Start Mask has to be present
S_Mask=1;
microFrameSchCtrl.sITD_MFSCContext.SplitStartMask=S_Mask;
microFrameSchCtrl.sITD_MFSCContext.SplitCompletionMask=(m_pTrans?m_pTrans->m_pCPipe->GetCMask():0);
m_pPrev=pPrev;
m_dwPhys =(m_pTrans?(m_pTrans->m_pCPipe->GetCPhysMem())-> VaToPa((PBYTE)this):0);
}
void CSITD::ReInit(CSITransfer * pTransfer,CSITD * pPrev)
{
ASSERT( pTransfer!=NULL);
nextLinkPointer.dwLinkPointer=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -