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

📄 ali.cpp

📁 这是运行在windows ce 4.2 版本下的关于硬盘加载的驱动程序
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

//
//
#include "atamain.h"
#include "atapipci.h"
#include "ali.h"
#include <ceddk.h>


BOOL CAli::Init(HKEY hActiveKey)
{
    BOOL bRet = CPCIDisk::Init(hActiveKey);
    SetTransferMode(0x20);
    GetBaseStatus();
    return bRet;
}

//--------------------------------------------------------------------------
BOOL CAli::EndDMA()
{
    BYTE bStatus = ReadBMStatus();
    if ((bStatus & BM_STATUS_INTR) && (bStatus & BM_STATUS_ACTIVE))
        DEBUGMSG( ZONE_DMA, (TEXT(" ATAPI:EndDMA This is an active state... status=%02x\n"), bStatus));
    else if ((bStatus & BM_STATUS_INTR)  && !(bStatus & BM_STATUS_ACTIVE))
    {
        DEBUGMSG( ZONE_DMA, (TEXT(" ATAPI:EndDMA This is an inactive state... status=%02x\n"), bStatus));
    }
    else if (!(bStatus & BM_STATUS_INTR)  || (bStatus & BM_STATUS_ACTIVE))
    {
        DEBUGMSG( ZONE_ERROR | ZONE_DMA, (TEXT(" ATAPI:EndDMA Interrupt Delayed... status=%02x\n"), bStatus));
        BOOL bCount = 0;
        while (TRUE) {
            StallExecution(100);
            bCount++;
            bStatus = ReadBMStatus();
            if ((bStatus & BM_STATUS_INTR) && !(bStatus & BM_STATUS_ACTIVE)) {
                DEBUGMSG( ZONE_DMA, (TEXT(" ATAPI:EndDMA DMA Done after wait... status=%02x\n"), bStatus));
                break;
            } else {
                DEBUGMSG( ZONE_ERROR | ZONE_DMA, (TEXT(" ATAPI:EndDMA Interrupt still delayed... status=%02x\n"), bStatus));
                if (bCount > 10) {
                    WriteBMCommand(0);
                    return FALSE;
                }
            }    
        }        
    }
    else
    {
        if (bStatus & BM_STATUS_ERROR) {    
            DEBUGMSG( ZONE_ERROR | ZONE_DMA, (TEXT(" ATAPI:EndDMA Error... status=%02x\n"), bStatus));
            ASSERT(0);
            return FALSE;
        }       
    }
    WriteBMCommand(0);
    return TRUE;
}


DWORD CAli::ReadCdRomDMA(DWORD dwLBAAddr, DWORD dwTransferLength, WORD wSectorSize, DWORD dwSgCount, SGX_BUF *pSgBuf)
{
    ATAPI_COMMAND_PACKET    CmdPkt;
    DWORD                   dwError=ERROR_SUCCESS;
    DWORD               dwSectorsToTransfer;
    SG_BUF              CurBuffer[MAX_SG_BUF];
    DWORD                   dwValue = 0;
    WORD                    wCount;
    DWORD                   dwRetry=0; 

    while(dwRetry++ < 5) {    

        if (m_fInterruptSupported)
            GetBaseStatus();
        WaitForInterrupt(0);

        WaitForDisc(WAIT_TYPE_NOT_BUSY, 50);
        WaitForDisc(WAIT_TYPE_NOT_DRQ, 50);
        if (ERROR_SUCCESS != WaitForDisc( WAIT_TYPE_NOT_BUSY, 1000)) {
        }
        if (ERROR_SUCCESS != WaitForDisc( WAIT_TYPE_NOT_DRQ, 1000)) {
        }

        DEBUGMSG( ZONE_IO | ZONE_CDROM, (TEXT("ATAPI:Ali:ReadCdRomDMA Address=%ld TransferLen=%02X SectorSize=%ld SgCount=%02X\r\n"), dwLBAAddr, dwTransferLength, wSectorSize, dwSgCount));

        DWORD dwStartBufferNum = 0, dwEndBufferNum = 0, dwEndBufferOffset = 0;
        DWORD dwNumSectors = dwTransferLength;
        DWORD dwStartSector = dwLBAAddr;

        // Process the SG buffers in blocks of MAX_CD_SECT_PER_COMMAND.  Each DMA request will have a new SG_BUF array 
        // which will be a subset of the original request, and may start/stop in the middle of the original buffer.
        while (dwNumSectors) {

            dwSectorsToTransfer = (dwNumSectors > MAX_CD_SECT_PER_COMMAND) ? MAX_CD_SECT_PER_COMMAND : dwNumSectors;
        
            DWORD dwBufferLeft = dwSectorsToTransfer * wSectorSize;
            DWORD dwNumSg = 0;

            while (dwBufferLeft) {
                DWORD dwCurBufferLen = pSgBuf[dwEndBufferNum].sb_len - dwEndBufferOffset;

                if (dwBufferLeft < dwCurBufferLen) {
                    // The buffer left for this block is less than the current SG buffer length
                    CurBuffer[dwEndBufferNum - dwStartBufferNum].sb_buf = pSgBuf[dwEndBufferNum].sb_buf + dwEndBufferOffset;
                    CurBuffer[dwEndBufferNum - dwStartBufferNum].sb_len = dwBufferLeft;
                    dwEndBufferOffset += dwBufferLeft;
                    dwBufferLeft = 0;
                } else {
                    // The buffer left for this block is greater than or equal to the current SG buffer length.  Move on to the next SG buffer.
                    CurBuffer[dwEndBufferNum - dwStartBufferNum].sb_buf = pSgBuf[dwEndBufferNum].sb_buf + dwEndBufferOffset;
                    CurBuffer[dwEndBufferNum - dwStartBufferNum].sb_len = dwCurBufferLen;
                    dwEndBufferOffset = 0;
                    dwEndBufferNum++;
                    dwBufferLeft -= dwCurBufferLen;
                }    
                dwNumSg++;
            }
         
            if (!SetupDMA(CurBuffer, dwNumSg, TRUE)) {
                dwError = ERROR_READ_FAULT;
                goto ExitFailure;
            }    
         
            SetupCdRomRead( wSectorSize == CDROM_RAW_SECTOR_SIZE ? TRUE : FALSE, dwStartSector, dwSectorsToTransfer, &CmdPkt);

            wCount = (SHORT)((dwSectorsToTransfer * wSectorSize) >> 1);

            if (AtapiSendCommand(&CmdPkt, wCount, IsDMASupported())) {
                if (GetAltStatus() & ATA_STATUS_ERROR) {
                    dwError = ERROR_GEN_FAILURE;
                    goto ExitFailure;
                }   
                BeginDMA(TRUE);
                if (m_fInterruptSupported) {
                    if (!WaitForInterrupt(DISK_IO_TIME_OUT)) {  
                        DEBUGMSG( ZONE_IO, (TEXT("ATAPI:Ali:ReadCdRom- WaitforInterrupt failed (DevId %x) \r\n"),m_dwDeviceId));
                        dwError = ERROR_READ_FAULT;
                        goto ExitFailure;
                    }
                    WaitForDisc(WAIT_TYPE_NOT_BUSY, 5000, 100);
                }    
                if (ERROR_SUCCESS != WaitForDisc(WAIT_TYPE_READY, 1000)) {
                }   
                if (EndDMA()) {
                    WaitOnBusy(FALSE);
                    CompleteDMA( (PSG_BUF)pSgBuf, dwSgCount, TRUE);
                } else {
                    dwError = ERROR_READ_FAULT;
                    goto ExitFailure;
                }    
            }


            dwStartSector += dwSectorsToTransfer;
            dwStartBufferNum = dwEndBufferNum;
            dwNumSectors -= dwSectorsToTransfer;        
        }    
        break;

    ExitFailure:
        if (dwError != ERROR_SUCCESS) {
            AbortDMA();
        } 
    }
    return dwError;
}


⌨️ 快捷键说明

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