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

📄 ep931xide.cpp

📁 EP9315开发板的Wince6.0的BSP包文件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            *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;
//EP931x rev E1 supports up to UDMA mode 3.
/*        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;
    }

    //
    // The IDE controller is now using DMA.
    //
    m_bDMAState = TRUE;

    //
    // Make sure that the Ide event has not fired.
    // For some reason this event is usually set.
    // 
    ResetEvent(m_hIstEvent[IDE_EVENT]);
    ResetEvent(m_hIstEvent[DMA_EVENT]);

    //
    // Tell the DMA thread to start waiting for the DMA event.
    //    
    PulseEvent(m_hThreadWaitEvent);


    return TRUE;
}


//****************************************************************************
// CEP931xPort::DmaIst
//****************************************************************************
// Allows us to signal the WaitforDMA when a DMA interrupt event
// occurs.
// 
//
DWORD CEP931xPort::DmaIst(LPVOID lpParameter)
{
    CEP931xPort *t = (CEP931xPort *)lpParameter;

    for(;;)
    {
        WaitForSingleObject(t->m_hThreadWaitEvent, INFINITE);

        if(t->m_bThreadExit)
            break;

        //
        // This enables the interrupt.
        //
        InterruptDone(SYSINTR_DMA_M2M0);
        QueryPerformanceCounter(&t->m_liDmaStart);

        WaitForSingleObject(t->m_hDmaIntEvent, INFINITE);
        QueryPerformanceCounter(&t->m_liDmaEnd);

        //
        // Signal the other thread that dma event has occured.
        //
        SetEvent(t->m_hIstEvent[DMA_EVENT]);
    }

    return 0;
}

//****************************************************************************
// CEP931xPort::WaitOnDMARQ
//****************************************************************************
// Waits for DMARQ to be Asserted
// 
//
BOOL CEP931xPort::WaitOnDMARQ(ULONG ulTime)
{
    LARGE_INTEGER liStart, liCurrent;
    BOOL    bRet = TRUE;
    ULONG   ulIdeCtrl;
    ULONG   ulMicroSec;
//    BYTE    bStatus;

    QueryPerformanceCounter(&liStart);

    // bStatus = BYTE(ATAReadRegister(CSDA_ALT_STAT_REG) & 0xFF);
    DELAY_100NS
    DELAY_100NS


    for(;;)
    {
        QueryPerformanceCounter(&liCurrent);

        ulIdeCtrl = *IDE_CTRL;
        if  (ulIdeCtrl & IDE_CTRL_DMARQ) 
        {
            break;
//            bStatus = BYTE(ATAReadRegister(CSDA_STAT_REG) & 0xFF);
//            if(((bStatus & (ATA_STATUS_BUSY| ATA_STATUS_DATA_REQ)) == ATA_STATUS_BUSY  )  || 
//               ((bStatus & (ATA_STATUS_BUSY| ATA_STATUS_DATA_REQ)) == ATA_STATUS_DATA_REQ))
//            if((bStatus & (ATA_STATUS_BUSY| ATA_STATUS_DATA_REQ)) == ATA_STATUS_DATA_REQ)
//            {
//            }
        }
        ulMicroSec = ULONG(liCurrent.QuadPart - liStart.QuadPart);
        if(ulMicroSec > ulTime)
        {
            bRet = FALSE;
            break;
        }
        else if(ulMicroSec > 50000)
        {
            Sleep(10);
        }
        else if(ulMicroSec > 5000)
        {
            Sleep(1);
        }
        else if(ulMicroSec > 500)
        {
            Sleep(0);
        }
    }


    return bRet;
}

//****************************************************************************
// CEP931xPort::WaitOnDMARQForCD
//****************************************************************************
// Waits for DMARQ to be Asserted the CD version.  
// CD may seek for up to a second while spinning up the drive.  Should 
// perform a sleep to not degrade system performance.
// 
// ulTime - Max Time to wait in Milliseconds.
//
BOOL CEP931xPort::WaitOnDMARQForCD(ULONG ulTime)
{
    BOOL    bRet = TRUE;
    ULONG   ulIdeCtrl;
    BYTE    bStatus;
    const   ULONG ulMaxSleepTime= 5;
    ULONG   ulSleepTime;
    ULONG   ulCount;


    bStatus = BYTE(ATAReadRegister(CSDA_ALT_STAT_REG) & 0xFF);

    ulCount = 0;
    ulSleepTime = 0;
    do
    {

        ulIdeCtrl = *IDE_CTRL;
        bStatus = BYTE(ATAReadRegister(CSDA_STAT_REG) & 0xFF);
        if  ( (ulIdeCtrl & IDE_CTRL_DMARQ)  &&
              (((bStatus & (ATA_STATUS_BUSY| ATA_STATUS_DATA_REQ)) == ATA_STATUS_BUSY  )  || 
               ((bStatus & (ATA_STATUS_BUSY| ATA_STATUS_DATA_REQ)) == ATA_STATUS_DATA_REQ))  )
        {
            break;
        }

        //
        // Sleep with increasing delay.  If the to wait is very short.
        // the sleep delay is small.  If the drive has to spin up
        // we can give the system more time to perform other tasks.
        //        
        Sleep(ulSleepTime);
        ulCount +=ulSleepTime;
        if(ulSleepTime< ulMaxSleepTime)
            ulSleepTime++;
    } while( ulCount <ulTime);


    return bRet;
}


//****************************************************************************
// CEP931xPort::IDEIst
//****************************************************************************
// Allows us to signal the WaitforDMA function when an IDE interrupt event 
// occurs.
// 
//
DWORD CEP931xPort::IdeIst(LPVOID lpParameter)
{
    CEP931xPort *t = (CEP931xPort *)lpParameter;

    for(;;)
    {
        WaitForSingleObject(t->m_hThreadWaitEvent, INFINITE);

        if(t->m_bThreadExit)
            break;

        //
        // This enables the interrupt.
        //
        InterruptDone(SYSINTR_IDE);
        QueryPerformanceCounter(&t->m_liIdeStart);

        WaitForSingleObject(t->m_hIdeIntEvent, INFINITE);
        QueryPerformanceCounter(&t->m_liIdeEnd);


        //
        // Signal the other thread that IDE event has occured.
        //
        SetEvent(t->m_hIstEvent[IDE_EVENT]);
    }

    return 0;
}

//****************************************************************************
// CEP931xPort::EndDMA
//****************************************************************************
// End the DMA
// 
//
BOOL CEP931xPort::EndDMA() 
{ 
    volatile BYTE            bStatus;

    DEBUGMSG
    ( 
        ZONE_DMA, 
        (
            TEXT("ATAPI:EndDMA\r\n")
        )
    );

    // Clear the IDE IRQ.
    bStatus = (BYTE)(ATAReadRegister(CSDA_STAT_REG) & 0xFF);



    //
    // Clear the M2M DMA interrupt register. 
    //
    m_pulDmaBase[M2M_INT>>2] = 0;


    //
    // Disable the DMA channel.
    //
    m_pulDmaBase[M2M_CTRL>>2] = 0;


    return TRUE;
}

//****************************************************************************
//  CEP931xPort::CleanUpDmaUDMAWrite
//****************************************************************************
// This routine sends bytes until the UDMA write transaction is finished.
// 
//
void CEP931xPort::CleanUpDmaUDMAWrite( void)
{
    LARGE_INTEGER liStart, liCurrent;
    ULONG   ulCount;
    ULONG ulIdeCtrl, ulIdeUdmaStatus;
    BOOL    b;


    //
    // Clear the status register.
    //
    m_pulDmaBase[M2M_INT>>2] = 0;
    
    //
    // Disable the DMA channel.
    //
    m_pulDmaBase[M2M_CTRL>>2] = 0;


    for(ulCount = 0 ; ulCount < 20 ; ulCount ++)
    {

        //
        // If we get an IDE interrupt we don't need to write any more data.
        //
        ulIdeCtrl = *IDE_CTRL;
        if(ulIdeCtrl & IDE_CTRL_INTRQ)
        {
            break;
        }

        //
        // Wait for a request from the IDE state machine.
        //
        b = QueryPerformanceCounter(&liStart);
        for(;;)
        {
            b = QueryPerformanceCounter(&liCurrent);

            ulIdeUdmaStatus = *IDE_UDMASTATUS;
            if(ulIdeUdmaStatus & UDMASTATUS_DMAIDE)
                break;
            if(ULONG(liCurrent.QuadPart - liStart.QuadPart) > 1000)
                break;
        }

        //
        // Send a byte out the IDE interface.
        //
        *IDE_UDMADATAOUT = 0x1234;
    }
}


//****************************************************************************
// CEP931xDisk::AbortDMA
//****************************************************************************
// Aborts the DMA after the DMA has started.
// 
//
BOOL CEP931xPort::AbortDMA() 
{ 
    volatile BYTE            bStatus;
    BOOL    fRet;
    DEBUGMSG
    ( 
        ZONE_DMA, 
        (
            TEXT("ATAPI:AbortDMA\r\n")
        )
    );

    //
    // Clear the IDE IRQ.
    //
    bStatus = (BYTE)(ATAReadRegister(CSDA_STAT_REG) & 0xFF);


    //
    // Clear the status register.
    //
    m_pulDmaBase[M2M_INT>>2] = 0;
    
    //
    // Disable the DMA channel.
    //
    m_pulDmaBase[M2M_CTRL>>2] = 0;

    //
    // Unlock the Buffers and free the mapped pointers.
    //
    if(m_fAligned)
    {
        fRet = UnlockPages
        ( 
            m_pucDmaBuffer,
            m_ulDmaCount
        );
        ASSERT(fRet);
    }



    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;
    // LARGE_INTEGER liStart, liCurrent, liEnd;

    DEBUGMSG
    ( 
        ZONE_DMA, 
        (
            TEXT("ATAPI:CompleteDMA\r\n")
        )
    );

    //
    // Unlock the Buffers and free the mapped pointers.
    //
    if(m_fAligned)
    {
        fRet = UnlockPages
        ( 
            m_pucDmaBuffer,
            m_ulDmaCount
        );
        ASSERT(fRet);
    }

    //
    // If the pSgBuf are unaligned, copy the entire buffer to our buffer.
    //
    else if(!m_fAligned && fRead)
    {
        ulDmaCount        = 0;
        for (ulBuffer = 0; ulBuffer < dwSgCount; ulBuffer++) 
        {
			pBuffer = pSgBuf[ulBuffer].sb_buf;//(LPBYTE)MapCallerPtr(pSgBuf[ulBuffer].sb_buf,  pSgBuf[ulBuffer].sb_len);
//            pBuffer = (LPBYTE)MapPtrToProcess(pSgBuf[ulBuffer].sb_buf, GetCallerProcess());


            if (pSgBuf[ulBuffer].sb_len >0x8000 || pSgBuf[ulBuffer].sb_len <=0 || pBuffer == NULL || m_pucDmaBuffer == NULL)
            {
                if (pSgBuf[ulBuffer].sb_len >0x8000 || pSgBuf[ulBuffer].sb_len <0)
                {
                    // DEBUGMSG( ZONE_DMA, (TEXT("CEP931xPort::CompleteDMA pSgBuf[ulBuffer].sb_len was %ld.\r\n"),pSgBuf[ulBuffer].sb_len));
                    pSgBuf[ulBuffer].sb_len = 0;
                }

                if (m_pucDmaBuffer == NULL)
                {
                    DEBUGMSG( ZONE_DMA, (TEXT("CEP931xPort::CompleteDMA m_pucDmaBuffer was NULL.\r\n")));
                }

                if (pBuffer == NULL)
                {
                    DEBUGMSG( ZONE_DMA, (TEXT("CEP931xPort::CompleteDMA pBuffer was NULL.\r\n")));
                }
            }
            else
            {
                // DEBUGMSG( ZONE_DMA, (TEXT("CEP931xPort::CompleteDMA About to check and possibly do memcopy.\r\n")));

⌨️ 快捷键说明

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