?? sdhcdma.cpp
字號:
}
if(m_dwNumOfAvailabe!=0 && (m_pDmaBufferList[m_dwNumOfAvailabe-1].dwLength & (dwDCacheLineSize-1))!=0) {
m_EndBuffer.dwBufferOffset = 0 ;
m_EndBuffer.pSrcSize = m_pDmaBufferList[m_dwNumOfAvailabe-1].dwLength;
m_EndBuffer.pSrcVirtualAddr = m_pDmaBufferList[m_dwNumOfAvailabe-1].virtualAddress;
m_pDmaBufferList[m_dwNumOfAvailabe-1].physicalAddress = m_EndBuffer.physicalAddress;
//m_pDmaBufferList[m_dwNumOfAvailabe-1].virtualAddress = m_EndBuffer.pBufferedVirtualAddr;
}
}
}
else {
fReturn = FALSE;
if (m_fLocked) {
UnlockPages(m_lpvLockedAddress, m_dwLockedSize);
};
m_fLocked = FALSE;
}
if (fReturn && fToDevice) {
for (DWORD dwIndex = 0 ; dwIndex<m_dwNumOfAvailabe ; dwIndex++) {
CacheRangeFlush(m_pDmaBufferList[dwIndex].virtualAddress,m_pDmaBufferList[dwIndex].dwLength, CACHE_SYNC_WRITEBACK );
}
}
}
ASSERT(fReturn);
}
return fReturn;
}
BOOL CSDHCSlotBaseSDMA::ArmDMA(SD_BUS_REQUEST& Request,BOOL fToDevice )
{
BOOL fResult = GetDMABuffer(Request,fToDevice);//CSDHCSlotBaseDMA::ArmDMA(Request,fToDevice);
if (fResult) {
m_fDMAProcessing = TRUE;
m_dwDMACompletionCode = ERROR_IO_PENDING ;
m_dwCurDMAListPos = 0;
ASSERT(m_dwNumOfAvailabe!=0);
// Arm Buffer Bound
DWORD dwArmBit= 0;
m_dwNextOffset = GetDMALengthBit(m_pDmaBufferList[m_dwCurDMAListPos].physicalAddress.LowPart, m_pDmaBufferList[m_dwCurDMAListPos].dwLength);
ASSERT(m_dwNextOffset<= m_pDmaBufferList[m_dwCurDMAListPos].dwLength);
// Arm the first buffer.
m_SDHCSloteBase.WriteDword(SDHC_SYSTEMADDRESS_LO, m_pDmaBufferList[m_dwCurDMAListPos].physicalAddress.LowPart );
}
return fResult;
}
BOOL CSDHCSlotBaseSDMA::DMANotifyEvent(SD_BUS_REQUEST& Request, DMAEVENT dmaEvent)
{
switch (dmaEvent) {
case DMA_COMPLETE:
if (m_fDMAProcessing && m_pDmaBufferList && m_dwCurDMAListPos<m_dwNumOfAvailabe) {
if (m_dwNextOffset < m_pDmaBufferList[m_dwCurDMAListPos].dwLength) { // re-arm the same.
DWORD dwNewAddr = m_pDmaBufferList[m_dwCurDMAListPos].physicalAddress.LowPart + m_dwNextOffset;
DWORD dwLength = GetDMALengthBit(dwNewAddr, m_pDmaBufferList[m_dwCurDMAListPos].dwLength-m_dwNextOffset);
ASSERT(dwLength + m_dwNextOffset <= m_pDmaBufferList[m_dwCurDMAListPos].dwLength);
m_dwNextOffset += dwLength;
m_SDHCSloteBase.WriteDword(SDHC_SYSTEMADDRESS_LO,dwNewAddr);
}
else { // next entry,
// Update HCParam
Request.HCParam += m_pDmaBufferList[m_dwCurDMAListPos].dwLength;
m_dwNextOffset = 0;
m_dwCurDMAListPos++;
if (m_dwCurDMAListPos < m_dwNumOfAvailabe) { // Continue for next
m_dwNextOffset = GetDMALengthBit(m_pDmaBufferList[m_dwCurDMAListPos].physicalAddress.LowPart, m_pDmaBufferList[m_dwCurDMAListPos].dwLength);
ASSERT(m_dwNextOffset<= m_pDmaBufferList[m_dwCurDMAListPos].dwLength);
m_SDHCSloteBase.WriteDword(SDHC_SYSTEMADDRESS_LO, m_pDmaBufferList[m_dwCurDMAListPos].physicalAddress.LowPart);
}
else {
m_fDMAProcessing = FALSE;
ASSERT(FALSE); // DMA has been completed.
}
}
}
else {
ASSERT(m_dwNumOfAvailabe == m_dwCurDMAListPos);
m_fDMAProcessing = FALSE;
}
break;
case TRANSFER_COMPLETED:
ASSERT(m_dwCurDMAListPos <= m_dwNumOfAvailabe);
if (m_fDMAProcessing && m_pDmaBufferList && m_dwCurDMAListPos<m_dwNumOfAvailabe) {
Request.HCParam += m_pDmaBufferList[m_dwCurDMAListPos].dwLength ;
m_dwCurDMAListPos ++;
}
m_fDMAProcessing = FALSE;
break;
case DMA_ERROR_OCCOR:
default:
ASSERT(FALSE);
m_dwDMACompletionCode = ERROR_NOT_READY;
m_fDMAProcessing = FALSE;
break;
}
if (!m_fDMAProcessing && m_hDma) {
DMACloseBuffer(m_hDma);
m_hDma = NULL;
}
else if (!m_fDMAProcessing && m_fLocked) {
if (!TRANSFER_IS_WRITE(&Request)) {
for (DWORD dwIndex = 0 ; dwIndex<m_dwNumOfAvailabe ; dwIndex++)
{
CacheRangeFlush(m_pDmaBufferList[dwIndex].virtualAddress,m_pDmaBufferList[dwIndex].dwLength, CACHE_SYNC_DISCARD );
}
if (m_StartBuffer.pSrcVirtualAddr!=NULL && m_StartBuffer.pSrcSize!=0) {
CeSafeCopyMemory (m_StartBuffer.pSrcVirtualAddr,
(PBYTE)m_StartBuffer.pBufferedVirtualAddr+ m_StartBuffer.dwBufferOffset,
m_StartBuffer.pSrcSize);
}
if (m_EndBuffer.pSrcVirtualAddr!=NULL && m_EndBuffer.pSrcSize!=0) {
CeSafeCopyMemory (m_EndBuffer.pSrcVirtualAddr, m_EndBuffer.pBufferedVirtualAddr,m_EndBuffer.pSrcSize);
}
}
if (m_fLocked )
UnlockPages( m_lpvLockedAddress, m_dwLockedSize);
m_fLocked = FALSE;
}
return TRUE;
}
CSDHCSlotBase32BitADMA2::CSDHCSlotBase32BitADMA2(CSDHCSlotBase& SDHCSloteBase)
: CSDHCSlotBaseDMA(SDHCSloteBase)
{
DEBUGMSG(SDCARD_ZONE_INIT, (_T("CSDHCSlotBase32BitADMA2:Create DMA Object for SDMA\r\n")));
m_dwNumOfTables =0;
for (DWORD dwIndex=0; dwIndex < MAXIMUM_DESC_TABLES; dwIndex++) {
m_pDmaDescTables[dwIndex] = NULL;
m_dwDescTablePhysAddr[dwIndex] = 0 ;
}
};
CSDHCSlotBase32BitADMA2::~CSDHCSlotBase32BitADMA2()
{
for (DWORD dwIndex=0; dwIndex< m_dwNumOfTables; dwIndex++) {
ASSERT(m_pDmaDescTables[dwIndex]);
ASSERT(m_dwDescTablePhysAddr[dwIndex]);
PHYSICAL_ADDRESS LogicalAddress = {m_dwDescTablePhysAddr[dwIndex],0};
OALDMAFreeBuffer(&m_dmaAdapter,PAGE_SIZE,LogicalAddress,m_pDmaDescTables[dwIndex],FALSE);
}
}
BOOL CSDHCSlotBase32BitADMA2::Init()
{
if (CSDHCSlotBaseDMA::Init()) {
PHYSICAL_ADDRESS LogicalAddress;
ASSERT(m_dwNumOfTables==0);
if (m_dwNumOfTables<MAXIMUM_DESC_TABLES) {
m_pDmaDescTables[m_dwNumOfTables] = (PADMA2_32_DESC) OALDMAAllocBuffer(&m_dmaAdapter, PAGE_SIZE , &LogicalAddress, FALSE );
if (m_pDmaDescTables[m_dwNumOfTables]) {
m_dwDescTablePhysAddr[m_dwNumOfTables] = LogicalAddress.LowPart; // We are using 32 bit address.
m_dwNumOfTables++;
}
}
ASSERT(m_dwNumOfTables!=0);
return (m_dwNumOfTables!=0);
}
return FALSE;
}
BOOL CSDHCSlotBase32BitADMA2::ArmDMA(SD_BUS_REQUEST& Request,BOOL fToDevice )
{
BOOL fResult = FALSE ;
if (CSDHCSlotBaseDMA::ArmDMA(Request,fToDevice)
&& m_dwNumOfAvailabe
&& IsEnoughDescTable(m_dwNumOfAvailabe) ) {
DWORD dwCurTable = 0 ;
DWORD dwCurEntry = 0 ;
DWORD dwCurPhysicalPage = 0;
while (dwCurPhysicalPage < m_dwNumOfAvailabe) {
PADMA2_32_DESC pCurTable = m_pDmaDescTables[dwCurTable];
PADMA2_32_DESC pCurEntry = pCurTable + dwCurEntry;
// Setup Descriptor
pCurEntry->Valid = 1 ;
pCurEntry->End = 0 ;
pCurEntry->Int = 0 ;
pCurEntry->Act = 2 ; // Transfer.
pCurEntry->Length = m_pDmaBufferList[dwCurPhysicalPage].dwLength;
pCurEntry->Address = m_pDmaBufferList[dwCurPhysicalPage].physicalAddress.LowPart;
dwCurPhysicalPage++;
if (dwCurPhysicalPage < m_dwNumOfAvailabe) { // We have more
dwCurEntry++;
if (dwCurEntry>= DESC_ENTRY_PER_TABLE -1 ) { // We reserv last one for Link Descriptor.
pCurEntry = pCurTable+dwCurEntry;
// Setup link.
pCurEntry->Valid = 1 ;
pCurEntry->End = 0 ;
pCurEntry->Int = 0 ;
pCurEntry->Act = 3 ; // Link
pCurEntry->Length = 0;
pCurEntry->Address = m_dwDescTablePhysAddr[dwCurTable+1];
dwCurTable ++;
dwCurEntry = 0;
if (dwCurTable>=m_dwNumOfTables) { // For some reason we exceed.
ASSERT(FALSE);
break;
}
}
}
else { // We finished here.
// Change this link to end
pCurEntry->End = 1;
fResult = TRUE;
break;
}
}
// Arm the first buffer.
if (fResult) {
m_fDMAProcessing = TRUE;
m_SDHCSloteBase.WriteDword(SDHC_ADMA_SYSTEMADDRESS_LO, m_dwDescTablePhysAddr[0] ); // 32-bit address.
m_SDHCSloteBase.WriteDword(SDHC_ADMA_SYSTEMADDRESS_HI, 0 );
}
else {
ASSERT(FALSE);
}
}
return fResult;
}
BOOL CSDHCSlotBase32BitADMA2::IsEnoughDescTable(DWORD dwNumOfBlock)
{
DWORD dwNumOfEntryPerTable = DESC_ENTRY_PER_TABLE -1; // we reserv one for the link.
DWORD dwNumOfTable = (dwNumOfBlock+dwNumOfEntryPerTable-1)/dwNumOfEntryPerTable;
if (dwNumOfTable> MAXIMUM_DESC_TABLES){
return FALSE;
}
if (dwNumOfTable> m_dwNumOfTables) { // we need allocate more
for (DWORD dwIndex = m_dwNumOfTables; dwIndex< dwNumOfTable; dwIndex++) {
PHYSICAL_ADDRESS LogicalAddress;
m_pDmaDescTables[m_dwNumOfTables] = (PADMA2_32_DESC) OALDMAAllocBuffer(&m_dmaAdapter, PAGE_SIZE , &LogicalAddress, FALSE );
if (m_pDmaDescTables[m_dwNumOfTables]) {
m_dwDescTablePhysAddr[m_dwNumOfTables] = LogicalAddress.LowPart; // We are using 32 bit address.
m_dwNumOfTables++;
}
else
break;
}
if (dwNumOfTable!=m_dwNumOfTables) {
ASSERT(FALSE);
return FALSE;
}
}
return TRUE;
}
BOOL CSDHCSlotBase32BitADMA2::DMANotifyEvent(SD_BUS_REQUEST& Request, DMAEVENT dmaEvent)
{
switch (dmaEvent) {
ASSERT(FALSE);
break;
case TRANSFER_COMPLETED:
ASSERT(m_dwCurDMAListPos <= m_dwNumOfAvailabe);
if (m_fDMAProcessing && m_pDmaBufferList && m_dwCurDMAListPos<m_dwNumOfAvailabe) {
Request.HCParam = Request.BlockSize*Request.NumBlocks;
}
m_fDMAProcessing = FALSE;
break;
case DMA_ERROR_OCCOR:
m_fDMAProcessing = FALSE; {
m_dwDMACompletionCode = ERROR_NOT_READY;
BYTE ADMAErrorStatus = m_SDHCSloteBase.ReadByte(SDHC_ADMA_ERROR_STATUS);
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("ADMA Erorr Status 0x%x: Refer to 2.2.30"), ADMAErrorStatus));
}
break;
default:
case DMA_COMPLETE:
ASSERT(FALSE);
m_dwDMACompletionCode = ERROR_NOT_READY;
m_fDMAProcessing = FALSE;
break;
}
if (!m_fDMAProcessing && m_hDma) {
DMACloseBuffer(m_hDma);
m_hDma = NULL;
}
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -