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

📄 ep931xide.cpp

📁 EP9315开发板的Wince6.0的BSP包文件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
void CEP931xDisk::WriteWord(WORD wData)
{
    ATAWriteRegister(CSDA_DATA_REG, (ULONG)wData);
}
//****************************************************************************
// CEP931xDisk::ReadWord
//****************************************************************************
// 
// 
//
WORD CEP931xDisk::ReadWord()
{
    return ((WORD)(ATAReadRegister(CSDA_DATA_REG) & 0xFFFF));
}
//****************************************************************************
// CEP931xDisk::WriteByte
//****************************************************************************
// 
// 
//
void CEP931xDisk::WriteByte(BYTE bData)
{
    ATAWriteRegister(CSDA_DATA_REG, (ULONG)bData);
}
//****************************************************************************
// CEP931xDisk::ReadByte
//****************************************************************************
// 
// 
//
WORD CEP931xDisk::ReadByte()
{
    return ((BYTE)(ATAReadRegister(CSDA_DATA_REG) & 0xFF));
}

//****************************************************************************
// CEP931xDisk::WaitForInterrupt
//****************************************************************************
// Waits for the IDE interrupt.  This is used for waiting in PIO mode.
//
// dwTimeOut - Time out in mS
// 
// Return      TRUE  - Success
//             FALSE - Failure
//          
BOOL CEP931xDisk::WaitForInterrupt(DWORD dwTimeOut)
{
    BYTE    bStatus;
    BOOL    fRet = TRUE;
    DWORD   dwRet;

    // 
    // Wait for the IDE interrupt.  If it doesn't occur, timeout.
    //
    dwRet = WaitForSingleObject( m_pPort->m_hIdeIntEvent, dwTimeOut);


    //
    // If we are currently using DMA, switch to PIO mode to read the
    // registers.
    //
    m_pPort->PIOMode();

    if (dwRet == WAIT_TIMEOUT ) 
    {
        fRet = FALSE;
    } 
    else if (dwRet != WAIT_OBJECT_0 && dwTimeOut >0) 
    {
        //
        // This case is for if we don't use the interrupt. 
        // Not applicable for us.
        //
        if (!WaitForDisc( WAIT_TYPE_DRQ,  dwTimeOut, 10)) 
        {
            fRet = FALSE;
        }   
    }

    //
    // Ack interrupt!!!!!
    //
    bStatus = GetBaseStatus();
    
    if (bStatus & ATA_STATUS_ERROR  ) 
    {
        DEBUGMSG( ZONE_WARNING, (TEXT("CEP931xDisk::WaitforInterrupt bStatus = 0x%02x\n"), (ULONG) bStatus));
        bStatus = GetError();
        fRet = FALSE;
    }    

    //
    // Clear the IDE interrupt.
    //
    InterruptDone(SYSINTR_IDE);        

    return fRet;
} 


//****************************************************************************
// WaitForDMARQCleared
//****************************************************************************
// Wait for DMARQ to be cleared.
// 
//
BOOL WaitForDMARQCleared(ULONG ulTime)
{
    BOOL            bRet = TRUE;
    LARGE_INTEGER   liStart, liCurrent;
    ULONG           ulIdeCtrl;

    QueryPerformanceCounter(&liStart);
    for(;;)
    {
        QueryPerformanceCounter(&liCurrent);
        ulIdeCtrl = *IDE_CTRL;
        if(!(ulIdeCtrl & IDE_CTRL_DMARQ))
        {
            break;
        }
        if(ULONG(liCurrent.QuadPart - liStart.QuadPart) > ulTime)
        {
            bRet = FALSE;
        }
    }
    return bRet;   
}

//****************************************************************************
// CEP931xPort::WaitForDmaInterrupt
//****************************************************************************
// Waits for the IDE interrupt.  This is used for waiting in PIO mode.
//
// dwTimeOut - Time out in mS
// 
// Return      TRUE  - Success
//             FALSE - Failure
//          
ULONG CEP931xPort::WaitForDmaInterrupt(DWORD dwTimeOut)
{
    BYTE    bStatus;
    BYTE    bError;
    BOOL    fRet = TRUE;
    DWORD   dwWaitRet;
    ULONG   ulRet = DMAWAIT_NOERROR;
    ULONG   ulMicroSec;
    ULONG   ulTime = 10000 * 1000;

    LARGE_INTEGER liCurrent, liStart;    
    // LARGE_INTEGER   liStart, liCurrent;
    // volatile register ULONG           ulIdeCtrl;
    // volatile register ULONG           ulDmaM2MInt;
    BOOL    b;


    b = QueryPerformanceCounter(&m_liTotalStart);

    // 
    // Wait for the IDE interrupt.  If it doesn't occur, timeout.
    //
    dwWaitRet = WaitForMultipleObjects( 2, m_hIstEvent, FALSE, dwTimeOut);
    b = QueryPerformanceCounter(&m_liTotalEnd);

    //
    // Both IDE and DMA interrupts never occured, report an error.
    //
    if (dwWaitRet == (WAIT_OBJECT_0 + DMA_EVENT))
    {
        #if 0
        if(m_bWaitForDMARQCleared)
        {
            dwWaitRet = WaitForDMARQCleared(10000)?WAIT_OBJECT_0:WAIT_TIMEOUT;
        }
        else
        {
            dwWaitRet = WaitForSingleObject(m_hIstEvent[IDE_EVENT], 100);

            //
            // If DMARQ is cleared the transfer occured successfully but
            // the interrupt never asserted.  Use DMARQ from now on.
            //
            ulIdeCtrl = *IDE_CTRL;
            if(!(ulIdeCtrl & IDE_CTRL_DMARQ))
            {
                m_bWaitForDMARQCleared = 1;
                dwWaitRet = WAIT_OBJECT_0;
            }

        }
        #endif // 0

        dwWaitRet = WaitForSingleObject(m_hIstEvent[IDE_EVENT], UDMA_IDE_TIMEOUT);
        
        if(dwWaitRet == WAIT_TIMEOUT)
        {
            //
            // The IDE interface is asking for more data.
            //
            
            DEBUGMSG
            ( 
                ZONE_DMA, 
                (TEXT("CEP931xPort::WaitForDmaInterrupt DMA transfer completed but IDE interface is requesting to recieve more data.\r\n"))
            );

            if(!m_fDMARead)
            {

                //
                // DMA Hardware Write bug #1
                //
                CleanUpDmaUDMAWrite();
                ulRet = DMAWAIT_ERROR_WRITE_1;
                DEBUGMSG
                ( 
                    ZONE_DMA, 
                    (TEXT("CEP931xPort::WaitForDmaInterrupt Hit DMA Write Bug #1.\r\n"))
                );
                RETAILMSG
                ( 
                    1, 
                    (TEXT("CEP931xPort::WaitForDmaInterrupt Hit DMA Write Bug #1.\r\n"))
                );
            }
            else
            {
                ulRet = DMAWAIT_ERROR;
            }
        }

    }
    else if (dwWaitRet == (WAIT_OBJECT_0 + IDE_EVENT))
    {
        dwWaitRet = WaitForSingleObject(m_hIstEvent[DMA_EVENT], UDMA_DMA_TIMEOUT);
        if(dwWaitRet == WAIT_TIMEOUT)
        {
            //
            // The DMA interface is asking for more data.
            //
            DEBUGMSG
            ( 
                ZONE_DMA, 
                (TEXT("CEP931xPort::WaitForDmaInterrupt IDE transfer completed but DMA is requesting to send more data.\r\n"))
            );

            if(!m_fDMARead)
            {
                // RETAILMSG
                // ( 
                //     1, 
                //     (TEXT("CEP931xPort::WaitForDmaInterrupt Hit DMA Write Bug #2.\r\n"))
                // );

                DEBUGMSG
                ( 
                    ZONE_DMA, 
                    (TEXT("CEP931xPort::WaitForDmaInterrupt Hit DMA Write Bug #2.\r\n"))
                );

                //
                // If we ever hit write bug #2 use pio mode since we cannot detect
                // write bug #2 all of the time.
                //
                // m_bForcePIO = TRUE;
                ulRet = DMAWAIT_ERROR_WRITE_2;

                // DumpDmaState();
                // DumpIDEState();
            }
            else
            {
                //RETAILMSG
                //( 
                //    1, 
                //    (TEXT("CEP931xPort::WaitForDmaInterrupt Hit DMA Read Bug #1.\r\n"))
                //);

                DEBUGMSG
                ( 
                    ZONE_DMA, 
                    (TEXT("CEP931xPort::WaitForDmaInterrupt Hit DMA Read Bug #1.\r\n"))
                );
                ulRet = DMAWAIT_ERROR_READ_1;
            }
        }
    }
    else

    {
        RETAILMSG
        ( 
            1, 
            (TEXT("CEP931xPort::WaitForDmaInterrupt Both IDE and DMA interrupts did not occur.\r\n"))
        );
        // DEBUGMSG
        //( 
        //    ZONE_DMA, 
        //    (TEXT("CEP931xPort::WaitForDmaInterrupt Both IDE and DMA interrupts did not occur.\r\n"))
        //);
        ulRet = DMAWAIT_ERROR;
    }
  

    //
    // Switch to PIO mode.
    // 
    PIOMode();

    DEBUGMSG
    ( 
        ZONE_DMA, 
        (
            TEXT("CEP931xPort::WaitForDmaInterrupt  Event = %d, IDE= %d DMA = %d.\r\n"),
            ULONG(m_liTotalEnd.QuadPart - m_liTotalStart.QuadPart),
            ULONG(m_liIdeEnd.QuadPart   - m_liIdeStart.QuadPart),
            ULONG(m_liDmaEnd.QuadPart   - m_liDmaStart.QuadPart)
        )            
    );    

    

    //
    // Ack interrupt!!!!!
    //
    QueryPerformanceCounter(&liStart);

    if(ulRet == DMAWAIT_NOERROR)
    {
        for(;;)
        {
            QueryPerformanceCounter(&liCurrent);

            bStatus = (BYTE) ATAReadRegister(CSDA_STAT_REG) & 0xFF;
            if( !(bStatus & (ATA_STATUS_BUSY | ATA_STATUS_DATA_REQ) ))
            {
                break;
            }
            ulMicroSec = ULONG(liCurrent.QuadPart - liStart.QuadPart);
            if(ulMicroSec > ulTime)
            {
                ulRet = DMAWAIT_ERROR_BUSY;
                break;
            }
            else if(ulMicroSec > 50000)
            {
                Sleep(10);
            }
            else if(ulMicroSec > 5000)
            {
                Sleep(1);
            }
            else if(ulMicroSec > 500)
            {
                Sleep(0);
            }
        }


    }
    else
    {
        bStatus = (BYTE) ATAReadRegister(CSDA_STAT_REG) & 0xFF;
    }

    //*************************************************************************
    // Seagate St340014A has DRQ asserted after the transfer has been completed
    // also DMARQ goes high after this read?
    //*************************************************************************
    //if ((bStatus & ATA_STATUS_ERROR) /* || (bStatus & ATA_STATUS_DATA_REQ ) */ ) 
    if ((bStatus & ATA_STATUS_ERROR)  && (ulRet == DMAWAIT_NOERROR) ) 
    {
        DEBUGMSG
        (
            ZONE_WARNING,
            (
                TEXT("CEP931xPort::WaitForDmaInterrupt bStatus = 0x%04x\n"), 
                (ULONG) bStatus
            )
        );
        // bStatus = GetError();
        bError = (BYTE)ATAReadRegister(CSDA_ERROR_REG);
        RETAILMSG
        (
            1,
            (
                TEXT("CEP931xPort::WaitForDmaInterrupt bError = 0x%04x\n"), 
                (ULONG) bStatus
            )
        );

        if(bError & 0x80)
        {
            ulRet = DMAWAIT_ERROR_CRC;
        }
        else        
        {
            ulRet = DMAWAIT_ERROR_STATUS;
        }
    }    
    


    return ulRet;
}
//****************************************************************************
// CEP931xDisk::WaitForDmaInterrupt
//****************************************************************************
// Waits for the IDE interrupt.  This is used for waiting in PIO mode.
//
// dwTimeOut - Time out in mS
// 
// Return      TRUE  - Success
//             FALSE - Failure
//          
ULONG CEP931xDisk::WaitForDmaInterrupt(DWORD dwTimeOut)
{
    ULONG   ulRet;
    ulRet = m_pPort->WaitForDmaInterrupt(dwTimeOut);


    if(m_pPort->m_fDMARead)
    {
        m_DmaStatistics.ulDmaTotalRead++;
    }
    else
    {
        m_DmaStatistics.ulDmaTotalWrite++;
    }


    switch(ulRet)
    {
        case DMAWAIT_NOERROR:
            m_DmaStatistics.ulDmaNoError++;
            break;
        case DMAWAIT_ERROR_BUSY:
            m_DmaStatistics.ulDmaBusyError++;
            break;
        case DMAWAIT_ERROR:
            m_DmaStatistics.ulDmaOtherError++;
            break;
        case DMAWAIT_ERROR_WRITE_1:
            m_DmaStatistics.ulDmaWriteBug1++;
            break;

        case DMAWAIT_ERROR_WRITE_2:
            m_DmaStatistics.ulDmaWriteBug2++;
            break;

        case DMAWAIT_ERROR_RE

⌨️ 快捷键说明

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