📄 atamx31.cpp
字号:
DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk::EndDMA+\n")));
DDKSdmaStopChan(m_DMAChan, TRUE);
// unlock any previous locked page ranges
for(DWORD i = 0; i < m_dwAlignedSgCount; i++)
{
LPBYTE pBuffer = (LPBYTE)MapCallerPtr((LPVOID)m_pDMASgBuf[i].sb_buf,m_pDMASgBuf[i].sb_len);
UnlockPages(pBuffer,m_pDMASgBuf[i].sb_len);
}
fSDMAIntrEnable = FALSE;
OUTREG8(&g_pVAtaReg->InterruptEnable, 0x08);
return TRUE;
}
// ----------------------------------------------------------------------------
// Function: AbortDMA
// Abort DMA transfer
//
// Parameters:
// None
// ----------------------------------------------------------------------------
BOOL
CMX31Disk::AbortDMA(
)
{
DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk::AbortDMA+\n")));
fSDMAIntrEnable = FALSE;
return EndDMA();
}
// ----------------------------------------------------------------------------
// Function: MoveDMABuffer
// Move data from s/g buffer to DMA buffer or vice versa
//
// Parameters:
// fRead -
//
// ----------------------------------------------------------------------------
DWORD CMX31Disk::MoveDMABuffer(PSG_BUF pSgBuf, DWORD dwSgIndex, DWORD dwSgCount, BOOL fRead)
{
DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk::MoveDMABuffer(%d)+\n"), dwSgCount));
DWORD dwOffset = 0;
DWORD dwEnd = m_dwTransferSize - m_dwAlignedSgBytes;
for ( ; dwSgIndex < dwSgCount; dwSgIndex++)
{
// Map address and check for security violation
LPBYTE pBuffer = (LPBYTE)MapCallerPtr((LPVOID)pSgBuf[dwSgIndex].sb_buf, pSgBuf[dwSgIndex].sb_len);
if (pSgBuf[dwSgIndex].sb_buf != NULL && pBuffer == NULL)
{
// security violation
DEBUGMSG(ZONE_ERROR, (TEXT(
"CMX31Disk::MoveDMABuffer> Failed to map pointer to caller\r\n"
)));
dwOffset = 0;
goto cleanUp;
}
DWORD dwSize = pSgBuf[dwSgIndex].sb_len;
if((dwSize + dwOffset) > dwEnd)
dwSize = dwEnd - dwOffset;
if (fRead)
{
memcpy(pBuffer, pVirtDMABufferAddr + dwOffset, dwSize);
//RETAILMSG(TRUE, (_T("MEMREAD %d\r\n"), dwSize));
}
else
{
memcpy(pVirtDMABufferAddr + dwOffset, pBuffer, dwSize);
//RETAILMSG(TRUE, (_T("MEMWRITE %d\r\n"), dwSize));
}
dwOffset += dwSize;
}
cleanUp:
return dwOffset;
}
// ----------------------------------------------------------------------------
// Function: CompleteDMA
// Complete DMA transfer
//
// Parameters:
// pSgBuf -
// dwSgCount -
// fRead -
// ----------------------------------------------------------------------------
BOOL
CMX31Disk::CompleteDMA(
PSG_BUF pSgBuf,
DWORD dwSgCount,
BOOL fRead
)
{
DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk::CompleteDMA+\n")));
fSDMAIntrEnable = FALSE;
if(fRead)
{
if (m_dwAlignedSgCount != dwSgCount)
{
DWORD dwSize = MoveDMABuffer(pSgBuf, m_dwAlignedSgCount, dwSgCount, fRead);
DEBUGCHK(dwSize == (m_dwTransferSize - m_dwAlignedSgBytes));
}
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: MapDMABuffers
//
// Allocate and map DMA buffer
//
// Parameters:
// pController[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL CMX31Disk::MapDMABuffers(void)
{
DMA_ADAPTER_OBJECT Adapter;
DEBUGMSG(ZONE_FUNC,(_T("CMX31Disk::MapDMABuffers+\r\n")));
pVirtDMABufferAddr = NULL;
memset(&Adapter, 0, sizeof(DMA_ADAPTER_OBJECT));
Adapter.InterfaceType = Internal;
Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
// Allocate a block of virtual memory (physically contiguous) for the DMA buffers.
pVirtDMABufferAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter, (ATA_SDMA_BUFFER_SIZE)
, &(PhysDMABufferAddr), FALSE);
if (pVirtDMABufferAddr == NULL)
{
DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX31:MapDMABuffers() - Failed to allocate DMA buffer.\r\n")));
return(FALSE);
}
DEBUGMSG(ZONE_FUNC,(_T("CMX31Disk::MapDMABuffers-\r\n")));
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: UnmapDMABuffers
//
// This function unmaps the DMA buffers previously mapped with the
// MapDMABuffers function.
//
// Parameters:
// pController[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL CMX31Disk::UnmapDMABuffers(void)
{
PHYSICAL_ADDRESS phyAddr;
DEBUGMSG(ZONE_FUNC,(_T("CMX31Disk::UnmapDMABuffers+\r\n")));
if(pVirtDMABufferAddr)
{
// Logical address parameter is ignored
phyAddr.QuadPart = 0;
HalFreeCommonBuffer(NULL, 0, phyAddr, (PVOID)pVirtDMABufferAddr, FALSE);
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: DeinitChannelDMA
//
// This function deinitializes the DMA channel for output.
//
// Parameters:
// pController[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL CMX31Disk::DeinitChannelDMA(void)
{
if (DmaChanATARx != 0)
{
DDKSdmaCloseChan(DmaChanATARx);
DmaChanATARx = 0;
}
if (DmaChanATATx != 0)
{
DDKSdmaCloseChan(DmaChanATATx);
DmaChanATATx = 0;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: InitChannelDMA
//
// This function initializes the DMA channel for output.
//
// Parameters:
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL CMX31Disk::InitChannelDMA(void)
{
BOOL rc = FALSE;
DEBUGMSG(ZONE_FUNC,(_T("CMX31Disk::InitChannelDMA+\r\n")));
// Check if DMA buffer has been allocated
if (!PhysDMABufferAddr.LowPart || !pVirtDMABufferAddr)
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA: Invalid DMA buffer physical address.\r\n")));
goto cleanUp;
}
// Open virtual DMA channels
DmaChanATARx = DDKSdmaOpenChan(DmaReqRx, ATA_CHANNEL_PRIORITY, NULL, m_pPort->m_dwIrq);
DEBUGMSG(ZONE_DMA,(_T("Channel Allocated(Rx) : %d\r\n"),DmaChanATARx));
if (!DmaChanATARx)
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Rx): SdmaOpenChan for input failed.\r\n")));
goto cleanUp;
}
// Allocate DMA chain buffer
if (!DDKSdmaAllocChain(DmaChanATARx, ATA_MAX_DESC_COUNT))
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Rx): DDKSdmaAllocChain for input failed.\r\n")));
goto cleanUp;
}
// Initialize the chain and set the watermark level
if (!DDKSdmaInitChain(DmaChanATARx, ATA_DMA_WATERMARK))
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Rx): DDKSdmaInitChain failed.\r\n")));
goto cleanUp;
}
// Open virtual DMA channels
DmaChanATATx = DDKSdmaOpenChan(DmaReqTx, ATA_CHANNEL_PRIORITY, NULL, m_pPort->m_dwIrq);
DEBUGMSG(ZONE_DMA,(_T("Channel Allocated(Tx) : %d\r\n"),DmaChanATATx));
if (!DmaChanATATx)
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Tx): SdmaOpenChan(Rx) for input failed.\r\n")));
goto cleanUp;
}
// Allocate DMA chain buffer
if (!DDKSdmaAllocChain(DmaChanATATx, ATA_MAX_DESC_COUNT))
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Tx): DDKSdmaAllocChain for input failed.\r\n")));
goto cleanUp;
}
// Initialize the chain and set the watermark level
if (!DDKSdmaInitChain(DmaChanATATx, ATA_DMA_WATERMARK))
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Tx): DDKSdmaInitChain failed.\r\n")));
goto cleanUp;
}
rc = TRUE;
cleanUp:
if (!rc)
{
DeinitChannelDMA();
}
DEBUGMSG(ZONE_DMA,(_T("CMX31Disk::InitChannelDMA-\r\n")));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: InitDMA
//
// Performs DMA channel intialization
//
// Parameters:
// pController[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL CMX31Disk::InitDMA(void)
{
volatile PBYTE m_pSPBAReg; // Base address of device control register set (MmMapped)
#define SPBA_PRR8 (m_pSPBAReg+0x20)
PHYSICAL_ADDRESS phyAddr;
DEBUGMSG(ZONE_FUNC, (TEXT("CMX31Disk::InitDMA+\r\n")));
phyAddr.QuadPart = CSP_BASE_REG_PA_SPBA;
m_pSPBAReg = (PBYTE) MmMapIoSpace(phyAddr, 0x3c, FALSE);
if (m_pSPBAReg == NULL)
{
DEBUGMSG(1, (TEXT("ATA: MmMapIoSpace failed!\r\n")));
}
// Allow access of SDMA to ATA via SPBA
// SETREG32(SPBA_PRR8, fRead?0x01:0x07); // 0x07 for write
SETREG32(SPBA_PRR8, 0x07); // 0x07 for write
DmaReqTx = DDK_DMA_REQ_ATA_TX ;
DmaReqRx = DDK_DMA_REQ_ATA_RX ;
// Map the DMA buffers into driver's virtual address space
if(!MapDMABuffers())
{
DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX31:InitDMA() - Failed to map DMA buffers.\r\n")));
return FALSE;
}
// Initialize the output DMA
if (!InitChannelDMA())
{
DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX31:InitDMA() - Failed to initialize output DMA.\r\n")));
return FALSE;
}
DEBUGMSG(ZONE_FUNC, (TEXT("CMX31Disk::InitDMA-\r\n")));
return TRUE ;
}
BOOL CMX31Disk::DeInitDMA(void)
{
if(!DeinitChannelDMA())
{
DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX31:DeinitChannelDMA() - Failed to deinitialize DMA.\r\n")));
return FALSE;
}
if(!UnmapDMABuffers())
{
DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX31:UnmapDMABuffers() - Failed to Unmap DMA buffers\r\n")));
return FALSE;
}
return TRUE ;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -