📄 ep931xide.cpp
字号:
}
else
{
//
// Unlock the pages and free the Mapped pointer.
//
fLockRet = UnlockPages
(
m_pucDmaBuffer,
pSgBuf[0].sb_len
);
ASSERT(fLockRet);
}
}
}
else
{
m_fAligned = FALSE;
}
//
// If the pSgBuf are unaligned copy the entire buffer to our buffer.
//
if(!m_fAligned )
{
ulDmaCount = 0;
for (ulBuffer = 0; ulBuffer < dwSgCount; ulBuffer++)
{
if(!fRead)
{
pBuffer = (LPBYTE)MapPtrToProcess(pSgBuf[ulBuffer].sb_buf, GetCallerProcess());
memcpy(m_pucStaticBuffer + ulDmaCount, pBuffer, pSgBuf[ulBuffer].sb_len);
}
ulDmaCount+= pSgBuf[ulBuffer].sb_len;
}
m_ulDmaCount = ulDmaCount;
m_pucDmaBuffer = m_pucStaticBuffer;
m_ulDmaPhysBuff = m_ulStaticPhysBuff;
}
//
// Setup the DMA ctrl register.
//
if(fRead)
{
m_ulDmaCtrlReg = M2M_CTRL_SAH | M2M_CTRL_TM_HARDINITP2M;
}
else
{
m_ulDmaCtrlReg = M2M_CTRL_DAH | M2M_CTRL_TM_HARDINITM2P;
}
//
// Setup the source and destination with there proper values.
//
//
switch(m_ulCurrentMode)
{
case MWDMA_MODE0:
case MWDMA_MODE1:
case MWDMA_MODE2:
m_ulDmaCtrlReg |= (fRead?3:3)<<M2M_CTRL_PWSC_SHIFT;
ulIDESource = 0x800a001C;
ulIDEDest = 0x800a0018;
break;
case UDMA_MODE0:
case UDMA_MODE1:
case UDMA_MODE2:
case UDMA_MODE3:
case UDMA_MODE4:
m_ulDmaCtrlReg |= (fRead?1:2)<<M2M_CTRL_PWSC_SHIFT;
ulIDESource = 0x800a0024;
ulIDEDest = 0x800a0020;
break;
default:
DEBUGMSG
(
1,
(
TEXT("ATAPI:SetupDMA EP9312 unsupported dma mode.\r\n")
)
);
break;
}
//
// Setup the DMA control register.
//
m_pulDmaBase[M2M_CTRL>>2] = m_ulDmaCtrlReg |=
M2M_CTRL_DONEINTEN |
M2M_CTRL_BWC_FULLTRANS |
M2M_CTRL_PW_WORD |
M2M_CTRL_TM_SOFTINIT |
M2M_CTRL_ETDP_AHIGH_OUTPUT |
M2M_CTRL_DREQP_HIGHLEVEL |
M2M_CTRL_RSS_INTIDE |
M2M_CTRL_NO_HDSK;
//
// Clear the status register.
//
m_pulDmaBase[M2M_STATUS>>2] = 0;
//
// Bit definitions are the same for Udma and Mdma.
//
if(fRead)
{
m_pulDmaBase[M2M_SAR_BASE0>>2] = ulIDESource;
m_pulDmaBase[M2M_DAR_BASE0>>2] = m_ulDmaPhysBuff;
}
else
{
m_pulDmaBase[M2M_SAR_BASE0>>2] = m_ulDmaPhysBuff;
m_pulDmaBase[M2M_DAR_BASE0>>2] = ulIDEDest;
}
//
// Figure out the number of bytes to transfer. Round up.
//
//m_pulDmaBase[M2M_BCR0>>2] = (m_ulDmaCount + 3) & 0xFFFC;
//
// Copy four more words than is needed.
//
m_pulDmaBase[M2M_BCR0>>2] = m_ulDmaCount;
//
// The IDE controller is now using DMA.
//
m_bDMAState = TRUE;
return TRUE;
}
//****************************************************************************
// CEP931xPort::BeginDMA
//****************************************************************************
// Begins the DMA engine.
//
//
BOOL CEP931xPort::BeginDMA(BOOL fRead)
{
BOOL fRet;
BYTE bStatus;
ULONG ulIdeCtrl;
ULONG ulOP;
LARGE_INTEGER liStart, liCurrent;
DEBUGMSG
(
ZONE_DMA,
(
TEXT("ATAPI:BeginDMA\r\n")
)
);
//
// If the we are reading/writing directly to the memory buffers, we must
// flush the data cache.
//
//
if(m_fAligned)
{
#if (_WIN32_WCE>=420)
//
// If we are running on Windows CE 4.2 flush the only the
// portion of the cache that we need.
//
// If we are writing to the hard drive, have the cache write
// its contents to memory.
//
// If we are reading the hard drive, write to memory and
// discard the data in the cache.
//
CacheRangeFlush
(
m_pucDmaBuffer,
m_ulDmaCount,
fRead? CACHE_SYNC_DISCARD: CACHE_SYNC_WRITEBACK
);
#else
CacheSync(CACHE_SYNC_DISCARD);
#endif // 0
}
{
StallExecution(1);
}
//
// Wait for Busy to go away.
// According to the ATA specification, While Busy and DRQ are asserted, wait.
//
fRet = QueryPerformanceCounter(&liStart);
for(;;)
{
//bStatus = (BYTE)(ATAReadRegister(CSDA_STAT_REG) & 0xFF);
ulIdeCtrl = *IDE_CTRL;
//
// Exit the loop if Busy is 0 or if DMARQ is 1.
//
//if(!(bStatus & ATA_STATUS_BUSY ) || (ulIdeCtrl & IDE_CTRL_DMARQ))
//if((((bStatus & ATA_STATUS_DATA_REQ ) && !(bStatus & ATA_STATUS_BUSY )) ||
// (!(bStatus & ATA_STATUS_DATA_REQ ) && (bStatus & ATA_STATUS_BUSY ))) &&
if(ulIdeCtrl & IDE_CTRL_DMARQ)
{
break;
}
//
// Add a 1 Second timeout so that the thread does not get
// stuck.
//
fRet = QueryPerformanceCounter(&liCurrent);
if((liStart.QuadPart + 1000000) <liCurrent.QuadPart)
{
DEBUGMSG
(
1,
(
TEXT("ATAPI:BeginDMA A DMA error has occured.\r\n")
)
);
return FALSE;
}
}
//
// Need to switch the IDE interface to DMA
//
//
switch(m_ulCurrentMode)
{
case MWDMA_MODE0:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_MDMAEN | (0<<IDE_CFG_MODE_SHIFT);
*IDE_MDMAOP = (fRead? 0: IDE_MDMAOP_RWOP);
*IDE_MDMAOP |= IDE_MDMAOP_MEN ;
break;
case MWDMA_MODE1:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_MDMAEN | (1<<IDE_CFG_MODE_SHIFT);
*IDE_MDMAOP = (fRead? 0: IDE_MDMAOP_RWOP);
*IDE_MDMAOP |= IDE_MDMAOP_MEN ;
break;
case MWDMA_MODE2:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_MDMAEN | (2<<IDE_CFG_MODE_SHIFT);
*IDE_MDMAOP = ulOP =(fRead? 0: IDE_MDMAOP_RWOP);
*IDE_MDMAOP |= IDE_MDMAOP_MEN ;
break;
case UDMA_MODE0:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (0<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
case UDMA_MODE1:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (1<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
case UDMA_MODE2:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (2<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
case UDMA_MODE3:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (3<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
case UDMA_MODE4:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (4<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
default:
DEBUGMSG
(
1,
(
TEXT("ATAPI:BeginDMA EP9312 unsupported dma mode.\r\n")
)
);
break;
}
//
// Setup the DMA control register and clear the start bit.
//
m_pulDmaBase[M2M_CTRL>>2] = m_ulDmaCtrlReg |= M2M_CTRL_ENABLE;
return TRUE;
}
//****************************************************************************
// CEP931xPort::EndDMA
//****************************************************************************
// End the DMA
//
//
BOOL CEP931xPort::EndDMA()
{
DEBUGMSG
(
ZONE_DMA,
(
TEXT("ATAPI:EndDMA\r\n")
)
);
//
// Clear the interrupt register.
//
m_pulDmaBase[M2M_INT>>2] = 0;
//
// Disable the DMA channel.
//
m_pulDmaBase[M2M_CTRL>>2] = 0;
return TRUE;
}
//****************************************************************************
// CEP931xDisk::AbortDMA
//****************************************************************************
// Aborts the DMA after the DMA has started.
//
//
BOOL CEP931xPort::AbortDMA()
{
BOOL fRet;
DEBUGMSG
(
ZONE_DMA,
(
TEXT("ATAPI:AbortDMA\r\n")
)
);
//
// Clear the status register.
//
m_pulDmaBase[M2M_INT>>2] = 0;
//
// Unlock the Buffers and free the mapped pointers.
//
if(m_fAligned)
{
fRet = UnlockPages
(
m_pucDmaBuffer,
m_ulDmaCount
);
ASSERT(fRet);
}
//
// Disable the DMA channel.
//
m_pulDmaBase[M2M_CTRL>>2] = 0;
return TRUE;
}
//****************************************************************************
// CEP931xDisk::CompleteDMA
//****************************************************************************
// Completes the DMA and cleans up the buffers.
//
//
BOOL CEP931xPort::CompleteDMA(PSG_BUF pSgBuf, DWORD dwSgCount, BOOL fRead)
{
ULONG ulDmaCount;
ULONG ulBuffer;
LPBYTE pBuffer;
BOOL fRet = TRUE;
DEBUGMSG
(
ZONE_DMA,
(
TEXT("ATAPI:CompleteDMA\r\n")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -