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

📄 cdio.cpp

📁 CIRRUS 93XX系列windows mobile 6.0 BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    return TRUE;
}


//****************************************************************************
// CDisk::AtapiReceiveData
//****************************************************************************
// 
// 
//

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 =pCurrentSegment->sb_buf;
//        pCurrentBuffer = (LPBYTE)MapCallerPtr(pCurrentSegment->sb_buf, 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 =pCurrentSegment->sb_buf;
//                    pCurrentBuffer = (LPBYTE)MapCallerPtr(pCurrentSegment->sb_buf,  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 =pCurrentSegment->sb_buf;
                    //pCurrentBuffer = (LPBYTE)MapCallerPtr(pCurrentSegment->sb_buf,  pCurrentSegment->sb_len);
//                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(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(SENSE_DATA);
    
    SgBuf.sb_len = sizeof(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;
 }


//---------------------------------------------------------------------------   
//
//  Function: AtapiLoadMedia
//
//  synopsis: Process a IOCTL_CDROM_LOAD_MEDIA/IOCTL_CDROM_EJECT_MEDIA request

⌨️ 快捷键说明

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