⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atamx27.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Parameters:
//     fRead -
// ----------------------------------------------------------------------------
BOOL CMX27Disk::BeginDMA(BOOL fRead)
{
    UINT8 chan = fRead ? DmaChanATARx : DmaChanATATx;
    DEBUGMSG(ZONE_FUNC, (_T("CMX27Disk::BeginDMA+\n")));

    
    if (m_dwAlignedSgCount > 0)
    {
        CacheSync(CACHE_SYNC_DISCARD);
    }

    fDMAIntrEnable = TRUE;
    
    BYTE bTransferMode = (BYTE)m_pPort->m_pDskReg[m_dwDeviceId]->dwTransferMode;

    switch(bTransferMode)
    {
        case 0x20:  // MDMA_MODE:
        case 0x21:
        case 0x22:
             OUTREG32(&g_pVAtaReg->ATAControl, fRead ? 0xd8 : 0xea);  
             break;
        case 0x40:  // UDMA_MODE:
        case 0x41:
        case 0x42:
        case 0x43:
        case 0x44:
        case 0x45:
             OUTREG32(&g_pVAtaReg->ATAControl, fRead ? 0xdc : 0xee);
             break;
     }
     DEBUGMSG(ZONE_FUNC, (_T("CMX27Disk::BeginDMA-\n")));
   return TRUE;
}

// ----------------------------------------------------------------------------
// Function: EndDMA
//     End DMA transfer
//
// Parameters:
//     None
// ----------------------------------------------------------------------------
BOOL CMX27Disk::EndDMA()
{
    DEBUGMSG(ZONE_FUNC, (_T("CMX27Disk::EndDMA+\n")));

    DDKDmacDisableChannelIntr(m_DMAChan);
    DDKDmacStopChan(m_DMAChan);
    DDKDmacClearChannelIntr(m_DMAChan);

    // unlock any previous locked page ranges
    for(DWORD i = 0; i < m_dwAlignedSgCount; i++)
    {
        LPBYTE pBuffer = (LPBYTE)m_pDMASgBuf[i].sb_buf;        
        UnlockPages(pBuffer,m_pDMASgBuf[i].sb_len);
    }

    fDMAIntrEnable = FALSE;

    return TRUE;
}

// ----------------------------------------------------------------------------
// Function: AbortDMA
//     Abort DMA transfer
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

BOOL
CMX27Disk::AbortDMA(
    )
{
    DEBUGMSG(ZONE_FUNC, (_T("CMX27Disk::AbortDMA+\n")));
    fDMAIntrEnable = FALSE;
    
   return EndDMA();
}

// ----------------------------------------------------------------------------
// Function: MoveDMABuffer
//     Move data from s/g buffer to DMA buffer or vice versa
//
// Parameters:
//     fRead -
//     
// ----------------------------------------------------------------------------
DWORD CMX27Disk::MoveDMABuffer(PSG_BUF pSgBuf, DWORD dwSgIndex, DWORD dwSgCount, BOOL fRead)
{    
    DEBUGMSG(ZONE_FUNC, (_T("CMX27Disk::MoveDMABuffer(%d)+\n"), dwSgCount));
      
    DWORD dwOffset = 0;
    DWORD dwEnd = dwSectorsToTransfer * BYTES_PER_SECTOR - m_dwAlignedSgBytes;
        
    for ( ; dwSgIndex < dwSgCount; dwSgIndex++) 
    {     
		LPBYTE pBuffer = NULL;
        //WINCE500 Map address and check for security violation
        // pBuffer = (LPBYTE)MapCallerPtr((LPVOID)pSgBuf[dwSgIndex].sb_buf, pSgBuf[dwSgIndex].sb_len);
        // if (pSgBuf[dwSgIndex].sb_buf != NULL && pBuffer == NULL)

		//WINCE600 Map address and check for security violation
       	if (FAILED(CeOpenCallerBuffer((PVOID*)&pBuffer, pSgBuf[dwSgIndex].sb_buf, pSgBuf[dwSgIndex].sb_len, fRead ? ARG_O_PTR : ARG_I_PTR, FALSE)))
	    {
			DEBUGMSG(ZONE_ERROR, (TEXT("CMX27Disk::MoveDMABuffer> CeOpenCallerBuffer(pDestMarshalled=0x%08x,pSrcUnmarshalled=0x%08x) failed!\r\n"),pBuffer, pSgBuf[dwSgIndex].sb_buf));
            dwOffset = 0;
            goto cleanUp;
        }

		DWORD dwSize = pSgBuf[dwSgIndex].sb_len;

        if((dwSize + dwOffset) > dwEnd)
            dwSize = dwEnd - dwOffset;

        if (fRead)
        {
            memcpy(pBuffer, pVirtDMABufferAddr + dwOffset, dwSize);
            DEBUGMSG(ZONE_FUNC, (_T("MEMREAD %d\r\n"), dwSize));
        }
        else
        {
            memcpy(pVirtDMABufferAddr + dwOffset, pBuffer, dwSize);
            //DEBUGMSG(ZONE_FUNC, (_T("MEMWRITE %d\r\n"), dwSize));
        }

		if (FAILED(CeCloseCallerBuffer((PVOID)pBuffer, pSgBuf[dwSgIndex].sb_buf, pSgBuf[dwSgIndex].sb_len, fRead ? ARG_O_PTR : ARG_I_PTR)))
	    {
			DEBUGMSG(ZONE_ERROR, (TEXT("CMX27Disk::MoveDMABuffer> CeCloseCallerBuffer(pDestMarshalled=0x%08x,pSrcUnmarshalled=0x%08x) failed!\r\n"),pBuffer, pSgBuf[dwSgIndex].sb_buf));
 		}

        dwOffset += dwSize;
    }
               
cleanUp:
   return dwOffset;
}

// ----------------------------------------------------------------------------
// Function: CompleteDMA
//     Complete DMA transfer
//
// Parameters:
//     pSgBuf -
//     dwSgCount -
//     fRead -
// ----------------------------------------------------------------------------
BOOL CMX27Disk::CompleteDMA(PSG_BUF pSgBuf, DWORD dwSgCount, BOOL fRead)
{
    DEBUGMSG(ZONE_FUNC, (_T("CMX27Disk::CompleteDMA+\n")));
    fDMAIntrEnable = FALSE;
      
    if(fRead)
    {
        if (m_dwAlignedSgCount != dwSgCount)
        {
            DWORD dwSize = MoveDMABuffer(pSgBuf, m_dwAlignedSgCount, dwSgCount, fRead);
            
            DEBUGCHK(dwSize == (dwSectorsToTransfer * BYTES_PER_SECTOR - 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 CMX27Disk::MapDMABuffers(void)
{
   DMA_ADAPTER_OBJECT Adapter;

   DEBUGMSG(ZONE_FUNC,(_T("CMX27Disk::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_DMA_BUFFER_SIZE)
                                , &(PhysDMABufferAddr), FALSE);

   if (pVirtDMABufferAddr == NULL)
   {
            DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX27:MapDMABuffers() - Failed to allocate DMA buffer.\r\n")));
      return(FALSE);
   }

   DEBUGMSG(ZONE_FUNC,(_T("CMX27Disk::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 CMX27Disk::UnmapDMABuffers(void)
{
    PHYSICAL_ADDRESS phyAddr;
    DEBUGMSG(ZONE_FUNC,(_T("CMX27Disk::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 CMX27Disk::DeinitChannelDMA(void)
{    
   if (DmaChanATARx != 0)
   {
       DDKDmacReleaseChan(DmaChanATARx);
       DmaChanATARx = 0;
   }
   if (DmaChanATATx != 0)
   {
       DDKDmacReleaseChan(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 CMX27Disk::InitChannelDMA(void)
{
    DMAC_CHANNEL_CFG gDMAC_InputData;
    BOOL rc = FALSE;

    DEBUGMSG(ZONE_FUNC,(_T("CMX27Disk::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;
    }


    // 2.1. Request Channel for RX
    DEBUGMSG(ZONE_DMA, (TEXT("InitDMA: Request ATA RX DMA channel\r\n")));
    DmaChanATARx = DDKDmacRequestChan(DmaReqRx);

    // 2.2. Configure channel for RX
    DEBUGMSG(1, (TEXT("InitDMA: Bind ATA RX DMA channel\r\n")));
    gDMAC_InputData.SrcAddr         = (UINT32)(CSP_BASE_REG_PA_ATA + ATA_FIFO_DATA_16_OFFSET);
    gDMAC_InputData.DstAddr         = (UINT32)(PhysDMABufferAddr.QuadPart);
    gDMAC_InputData.DataSize               = ATA_DMA_BUFFER_SIZE;
    gDMAC_InputData.DstMode         = DMAC_TRANSFER_MODE_LINEAR_MEMORY;
    gDMAC_InputData.SrcMode         = DMAC_TRANSFER_MODE_FIFO ;
    gDMAC_InputData.MemDirIncrease  = TRUE ;
    gDMAC_InputData.SrcSize         = DMAC_TRANSFER_SIZE_16BIT ;
    gDMAC_InputData.DstSize         = DMAC_TRANSFER_SIZE_32BIT ;
    gDMAC_InputData.RepeatType      = DMAC_REPEAT_DISABLED;     
    gDMAC_InputData.ExtReqEnable    = TRUE ; 
    gDMAC_InputData.ReqSrc          = DMAC_REQUEST_ATA_RCV_FIFO ;
    gDMAC_InputData.ReqTimeout      = FALSE ;
    gDMAC_InputData.BurstLength     = 32;                   // 16 byte burst length
    
    if (DDKDmacConfigureChan(DmaChanATARx, &gDMAC_InputData) != DmaChanATARx) { 
        DEBUGMSG(ZONE_ERROR, (TEXT("Bind ATA RX DMA channel failed!\r\n")));
        goto cleanUp;
    }

    //
    // 3. Configure DMA for ATA TX
    //

    // 3.1. Request Channel for TX
    DEBUGMSG(1, (TEXT("InitDMA: Request ATA TX DMA channel\r\n")));
    DmaChanATATx = DDKDmacRequestChan(DmaReqTx);
   
    // 3.2. Configure DMA for TX
    DEBUGMSG(ZONE_DMA, (TEXT("InitDMA: Bind ATA TX DMA channel\r\n")));
    gDMAC_InputData.DstAddr         = (UINT32)(CSP_BASE_REG_PA_ATA + ATA_FIFO_DATA_16_OFFSET);
    gDMAC_InputData.SrcAddr         = (UINT32)(PhysDMABufferAddr.QuadPart);
    gDMAC_InputData.DataSize        = ATA_DMA_BUFFER_SIZE ;
    gDMAC_InputData.DstMode         = DMAC_TRANSFER_MODE_FIFO ;
    gDMAC_InputData.SrcMode         = DMAC_TRANSFER_MODE_LINEAR_MEMORY ;
    gDMAC_InputData.MemDirIncrease  = TRUE ;
    gDMAC_InputData.DstSize         = DMAC_TRANSFER_SIZE_16BIT ;
    gDMAC_InputData.SrcSize         = DMAC_TRANSFER_SIZE_32BIT ;
    gDMAC_InputData.RepeatType      = DMAC_REPEAT_DISABLED;     
    gDMAC_InputData.ExtReqEnable    = TRUE ; 
    gDMAC_InputData.ReqSrc          = DMAC_REQUEST_ATA_TX_FIFO ;
    gDMAC_InputData.ReqTimeout      = FALSE ;
    gDMAC_InputData.BurstLength     = 32;                   //16 byte burst length
    
    if (DDKDmacConfigureChan(DmaChanATATx, &gDMAC_InputData) != DmaChanATATx) { 
        DEBUGMSG(ZONE_ERROR, (TEXT("Bind ATA TX DMA channel failed!\r\n")));
        goto cleanUp;
    } 

    // Clear intr
    DDKDmacClearChannelIntr(DmaChanATATx);
    DDKDmacClearChannelIntr(DmaChanATARx);

    rc = TRUE;

cleanUp:
   if (!rc)
   {
      DeinitChannelDMA();
   }
   DEBUGMSG(ZONE_DMA,(_T("CMX27Disk::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 CMX27Disk::InitDMA(void) 
{ 
    DEBUGMSG(ZONE_FUNC, (TEXT("CMX27Disk::InitDMA+\r\n")));

    BSPATADMAChanAlloc(&DmaReqTx, &DmaReqRx);

    // Map the DMA buffers into driver's virtual address space
    if(!MapDMABuffers())
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX27:InitDMA() - Failed to map DMA buffers.\r\n")));
        return FALSE;
    }

    // Initialize the output DMA
    if (!InitChannelDMA())
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX27:InitDMA() - Failed to initialize output DMA.\r\n")));
        return FALSE;
    }
    
    DEBUGMSG(ZONE_FUNC, (TEXT("CMX27Disk::InitDMA-\r\n")));
    return TRUE ; 
}

BOOL CMX27Disk::DeInitDMA(void) 
{
    if(!DeinitChannelDMA())
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX27:DeinitChannelDMA() - Failed to deinitialize DMA.\r\n")));
        return FALSE;
    }
    if(!UnmapDMABuffers())
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("ATA_MX27:UnmapDMABuffers() - Failed to Unmap DMA buffers\r\n")));
        return FALSE;
    }
    
    return TRUE ; 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -