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

📄 cdio.cpp

📁 这是运行在windows ce 4.2 版本下的关于硬盘加载的驱动程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    WriteSectorCount(0);
    
    WriteSectorNumber(0);


    // Set the byte tranfer count       
    if (wCount) {
        WriteLowCount((BYTE)(0xff & wCount));
        WriteHighCount((BYTE)(0xff & (wCount >> 8)));    
    } else {
        WriteLowCount(0xFE);
        WriteHighCount(0xFF);    
    }

    
    // 
    // Set PIO or DMA Mode as specified in bFlags. 0 = PIO, 1 = DMA
    //
    WriteFeature(fDMA ? 0x1 : 0x0);

    WaitForDisc( WAIT_TYPE_NOT_BUSY, 20);

    // Write ATAPI into  command register

    SelectDevice();
    
    WriteCommand(ATAPI_CMD_COMMAND); 

    WaitForDisc( WAIT_TYPE_NOT_BUSY, 20);
    //
    // Check how device is reporting CPU attention: DRQ or INTRQ?
    // INTRQ within 10 ms!!!
    //  
    if (m_fInterruptSupported && IsDRQTypeIRQ())
    {   
        //  ATA_INTR_CMD is expected
        //
        if (WaitForInterrupt(DISK_IO_TIME_OUT))
        {
            DEBUGMSG( ZONE_IO | ZONE_CDROM, (TEXT("ATAPI:AtapiSendCommand - Wait for ATA_INTR_CMD Interrupt (DevId %x) \r\n"), m_dwDeviceId));
            return FALSE;  
        }   
    }
    // 
    // Device will assert DRQ  within (50us or 3ms) if no interrupt id used
    // Wait for not BSY and DRQ
            

    if (!WaitForDRQ())
    {
        DEBUGMSG( ZONE_IO | ZONE_CDROM, (TEXT("ATAPIPCI:AtapiSendCommand 1 - ATAWaitForDisc failed with: %x (DevId %x)\r\n"), GetError(), m_dwDeviceId));
        return FALSE;
        
    }
        
    // Write the ATAPI Command Packet.

    WriteWordBuffer( (LPWORD)pCmdPkt,GetPacketSize()/sizeof(WORD));

    return TRUE;
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

BOOL CDisk::AtapiReceiveData(PSGX_BUF pSgBuf, DWORD dwSgCount,LPDWORD pdwBytesRead)
{
    DWORD       dwSgLeft = dwSgCount;
    DWORD       dwTransferCount;
    PSGX_BUF     pCurrentSegment;
    DWORD       dwReadCount = 0;
    DWORD       dwThisCount;
    BYTE        *pCurrentBuffer = NULL;
    DWORD       dwLen;

    DEBUGMSG( ZONE_IO | ZONE_CDROM, (TEXT("ATAPI:AtapiReceiveData - Entered SgCount=%ld.\r\n"), dwSgCount));

    if (ERROR_SUCCESS != WaitForDisc( WAIT_TYPE_READY, 5000, 100)) 
        return FALSE;

    pCurrentSegment = pSgBuf;
    if (pCurrentSegment) {
        dwLen = pCurrentSegment->sb_len;
        pCurrentBuffer = (LPBYTE)MapPtrToProcess(pCurrentSegment->sb_buf, GetCallerProcess());
    }   
    

    m_wNextByte = 0xFFFF; // There is no byte left from the previous transaction.
    
    for(;;) {   
        if (m_fInterruptSupported) {   
            // 
            //  Waiting for ATA_INTR_READ or ATA_INTR_WRITE  or ATA_INTR_READY
            //
            if (!WaitForInterrupt(DISK_IO_TIME_OUT)) {
                DEBUGMSG( ZONE_CDROM | ZONE_ERROR, (TEXT("ATAPI:AtapiReceiveData - Wait for ATA_INTR_READ failed (DevId %x) \r\n"), m_dwDeviceId));
                return FALSE;
            }
            WORD wState = CheckIntrState();
            //
            // Return Error if not IO Interrupt
            //
            if ((wState ==  ATA_INTR_ERROR) || (GetAltStatus() & ATA_STATUS_ERROR))
            {   
                DEBUGMSG( ZONE_IO | ZONE_ERROR | ZONE_CDROM, (TEXT("ATAPI:AtapiReceiveData - Wait for ATA_INTR_READ failed (DevId %x) \r\n"), m_dwDeviceId));
                return FALSE;
            
            }
            if (wState ==  ATA_INTR_READY)
            {
                DEBUGMSG( ZONE_IO | ZONE_CDROM, (TEXT("ATAPI:AtapiReceiveData - Exiting with Interrupt Ready signal Device=%ld\r\n"), m_dwDeviceId));
                return TRUE;
            }
        
            
        };
        //
        // Wait until device is ready for  data transfer.
        //
        if (!WaitForDRQ()) 
        {
            DEBUGMSG( ZONE_IO | ZONE_ERROR | ZONE_CDROM, (TEXT("ATAPI:AtapiReceiveData Failed at WaitForDRQ Status=%02X Error=%02X Deivce=%ld\r\n"), GetAltStatus(), GetError(), m_dwDeviceId));
            return(FALSE);
        }
    
        //
        //  Read Transfer Counter set by Device.
        //
        dwTransferCount = GetCount();

        DEBUGMSG (ZONE_CDROM | ZONE_IO, (TEXT(">>>Read Transfer Count : %x  SG=%x \r\n"),dwTransferCount,dwSgLeft));

        while ((dwSgLeft>0) && (dwTransferCount>0))
        {   
            dwThisCount = min(dwTransferCount, dwLen);
            
            if (pCurrentBuffer) {
                ReadBuffer(pCurrentBuffer,dwThisCount);
                dwTransferCount -= dwThisCount;
                dwReadCount += dwThisCount;
            }
            pCurrentBuffer += dwThisCount;
            dwLen -= dwThisCount;

            if (dwLen == 0) {
                // Go to the next SG
                dwSgLeft--;           
                pCurrentSegment++;
                if (pCurrentSegment) {
                    dwLen = pCurrentSegment->sb_len;
                    pCurrentBuffer = (LPBYTE)MapPtrToProcess(pCurrentSegment->sb_buf, GetCallerProcess());
                }   
            }

        } // End of while loop
    
        // Discard the rest of data if left.

        while (dwTransferCount > 0) 
        {
            (void) ReadWord();
            dwTransferCount-=2 ;          
        }
        if (pdwBytesRead)
            *pdwBytesRead = dwReadCount;
        if (!dwSgLeft)
            break;
    }
    return TRUE;
} 

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
BOOL CDisk::AtapiSendData(PSGX_BUF pSgBuf, DWORD dwSgCount,LPDWORD pdwBytesWrite)
{
    DWORD       dwSgLeft = dwSgCount;
    DWORD       dwTransferCount;
    PSGX_BUF     pCurrentSegment;
    DWORD       dwWriteCount = 0;
    DWORD       dwThisCount;
    BYTE        *pCurrentBuffer=NULL;

    DEBUGMSG( ZONE_IO | ZONE_CDROM, (TEXT("ATAPI:AtapiReceiveData - Entered SgCount=%ld.\r\n"), dwSgCount));

    pCurrentSegment = pSgBuf;

    m_wNextByte = 0xFFFF; // There is no byte left from the previous transaction.
    
    for(;;) {   
        if (m_fInterruptSupported) {   
            // 
            //  Waiting for ATA_INTR_READ or ATA_INTR_WRITE  or ATA_INTR_READY
            //
            if (!WaitForInterrupt(DISK_IO_TIME_OUT)) {
                DEBUGMSG( ZONE_CDROM | ZONE_ERROR, (TEXT("ATAPI:AtapiReceiveData - Wait for ATA_INTR_READ failed (DevId %x) \r\n"), m_dwDeviceId));
                return FALSE;
            }
            WORD wState = CheckIntrState();
            //
            // Return Error if not IO Interrupt
            //
            if (wState ==  ATA_INTR_ERROR)
            {   
                DEBUGMSG( ZONE_IO | ZONE_ERROR | ZONE_CDROM, (TEXT("ATAPI:AtapiReceiveData - Wait for ATA_INTR_READ failed (DevId %x) \r\n"), m_dwDeviceId));
                return FALSE;
            
            }
            if (wState ==  ATA_INTR_READY)
            {
                DEBUGMSG( ZONE_IO | ZONE_CDROM, (TEXT("ATAPI:AtapiReceiveData - Exiting with Interrupt Ready signal Device=%ld\r\n"), m_dwDeviceId));
                return TRUE;
            }
        };
        //
        // Wait until device is ready for  data transfer.
        //
        if (!WaitForDRQ()) 
        {
            DEBUGMSG( ZONE_IO | ZONE_ERROR | ZONE_CDROM, (TEXT("ATAPI:AtapiReceiveData Failed at WaitForDRQ Status=%02X Error=%02X Deivce=%ld\r\n"), GetAltStatus(), GetError(), m_dwDeviceId));
            return(FALSE);
        }
    
        //
        //  Read Transfer Counter set by Device.
        //
        dwTransferCount = GetCount();

        DEBUGMSG (ZONE_CDROM | ZONE_IO, (TEXT(">>>Read Transfer Count : %x  SG=%x \r\n"),dwTransferCount,dwSgLeft));

        while ((dwSgLeft>0) && (dwTransferCount>0))
        {   
            dwThisCount = min(dwTransferCount, pCurrentSegment->sb_len);
            
            if (pCurrentSegment->sb_buf)
                pCurrentBuffer = (LPBYTE)MapPtrToProcess(pCurrentSegment->sb_buf, GetCallerProcess());
        
            if (pCurrentBuffer)
            {
                WriteBuffer(pCurrentBuffer,dwThisCount);
                dwTransferCount -= dwThisCount;
                dwWriteCount += dwThisCount;
            }
            pCurrentSegment->sb_len -=dwThisCount;
            pCurrentSegment->sb_buf +=dwThisCount;

            if (pCurrentSegment->sb_len == 0)
            {
                // Go to the next SG
                dwSgLeft--;           
                pCurrentSegment++;
            }

        } // End of while loop
    
        if (pdwBytesWrite)
            *pdwBytesWrite = dwWriteCount;
        if (!dwSgLeft)
            break;
    }
    return TRUE;
} 


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

BOOL CDisk::AtapiIsUnitReady(PIOREQ pIOReq)
{
    ATAPI_COMMAND_PACKET    CmdPkt;
    DWORD dwRet;
    BOOL fRet = TRUE;
    if (!IsRemoveableDevice())
        return(TRUE);
    memset(&CmdPkt, 0, sizeof(ATAPI_COMMAND_PACKET));
    CmdPkt.Opcode = ATAPI_PACKET_CMD_TEST_READY;
    if (AtapiSendCommand(&CmdPkt)) {
        if (!AtapiReceiveData( NULL, 0, &dwRet)) {
            fRet = FALSE;
        }
    } else {
         fRet = FALSE;
    }
    if ( pIOReq && pIOReq->pInBuf)
    {
        ((CDROM_TESTUNITREADY *)pIOReq->pInBuf)->bUnitReady = fRet;
    }    
    if ( pIOReq && pIOReq->pOutBuf)
    {
        ((CDROM_TESTUNITREADY *)pIOReq->pOutBuf)->bUnitReady = fRet;
    }    
    if (!fRet) {
        DEBUGMSG( ZONE_ERROR |ZONE_CDROM, (TEXT("ATAPI:AtapiIsUnitReady Status=%02X Error=%02X Reason=%02X\r\n"), GetAltStatus(), GetError(), GetReason()));
    }       

    return fRet;
}

//---------------------------------------------------------------------------
//
//      function: AtaGetSenseInfo
//
//      synopsis: Issue a request sense command to get additional error data
//
//              ENTRY
//
//              EXIT
//
//                      Failure
//                              Returns an extended error code.
//
//-----------------------------------------------------------------------------

BOOL CDisk::AtapiGetSenseInfo(CD_SENSE_DATA *pSenseData)
{
    ATAPI_COMMAND_PACKET    CmdPkt;
    SGX_BUF SgBuf;
    DWORD dwRet;
    
    memset(&CmdPkt, 0, sizeof(ATAPI_COMMAND_PACKET));
    CmdPkt.Opcode = ATAPI_PACKET_CMD_REQUEST_SENSE;
    CmdPkt.Byte_4 = (BYTE)sizeof(CD_SENSE_DATA);
    
    SgBuf.sb_len = sizeof(CD_SENSE_DATA);
    SgBuf.sb_buf = (PBYTE) pSenseData;
    
    if (AtapiSendCommand(&CmdPkt)) {
        if (!AtapiReceiveData(&SgBuf, 1, &dwRet)) {
            DEBUGMSG( ZONE_ERROR|ZONE_CDROM, (TEXT("AtaGetSenseInfo Failed!!!\r\n")));
            return FALSE;
        }
    } else {
         return FALSE;
    }
    // Issue the request sense command
        
    DEBUGMSG( ZONE_CDROM | ZONE_IO, (TEXT("Sense Info\r\n")));
    DEBUGMSG( ZONE_CDROM | ZONE_IO, (TEXT("   Error Code = 0x%2.2X, Segment Number = %d, Sense Key = 0x%2.2X\r\n"), pSenseData->sd_ErrCode, pSenseData->sd_SegNum, pSenseData->sd_ILI_Key));
    DEBUGMSG( ZONE_CDROM | ZONE_IO, (TEXT("   Information = 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X\r\n"), pSenseData->sd_Info[0], pSenseData->sd_Info[1], pSenseData->sd_Info[2], pSenseData->sd_Info[3]));
    DEBUGMSG( ZONE_CDROM | ZONE_IO, (TEXT("   Additional Sense Length = %d\r\n"), pSenseData->sd_Length));
    DEBUGMSG( ZONE_CDROM | ZONE_IO, (TEXT("   Command Specific Information = 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X\r\n"),pSenseData->sd_CmdInfo[0], pSenseData->sd_CmdInfo[1], pSenseData->sd_CmdInfo[2], pSenseData->sd_CmdInfo[3]));
    DEBUGMSG( ZONE_CDROM | ZONE_IO, (TEXT("   ASC = 0x%2.2X, ASCQ = 0x%2.2X, FRUC = 0x%2.2X\r\n"), pSenseData->sd_SenseCode, pSenseData->sd_Qualifier, pSenseData->sd_UnitCode));
    DEBUGMSG( ZONE_CDROM | ZONE_IO, (TEXT("   Sense Key Specfic = 0x%2.2X 0x%2.2X 0x%2.2X\r\n"), pSenseData->sd_Key1, pSenseData->sd_Key2, pSenseData->sd_Key3));
    
    return TRUE;
}


//
//  This function send INQUIRY command to Atapi Device and  
//  process reply  corresponding reply.
//

BOOL CDisk::AtapiIssueInquiry(INQUIRY_DATA *pInqData)
{
    ATAPI_COMMAND_PACKET    CmdPkt;
    SGX_BUF SgBuf;
    DWORD dwRet;

    memset((void *)&CmdPkt, 0, sizeof(CmdPkt));
    CmdPkt.Opcode = ATAPI_PACKET_CMD_INQUIRY;                     
    CmdPkt.Byte_4 = sizeof(INQUIRY_DATA);
    
    SgBuf.sb_len = sizeof(INQUIRY_DATA);
    SgBuf.sb_buf = (PBYTE) pInqData;

    if (AtapiSendCommand(&CmdPkt)) {
        if (!AtapiReceiveData(&SgBuf, 1, &dwRet)) {
            DEBUGMSG( ZONE_ERROR|ZONE_CDROM, (TEXT("AtapiIssueInquriy Failed\r\n")));
            return FALSE;
        }
    } else {
       return FALSE;
    }    
    return TRUE;

⌨️ 快捷键说明

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