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

📄 diskmain.cpp

📁 WinCE5.0BSP for Renesas SH7770
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
//  Copyright(C) Renesas Technology Corp. 2005. All rights reserved.
//
// ATAPI(UDFS) driver for ITS-DS7
//
// FILE     : atamain.cpp
// CREATED  : 2005.02.10
// MODIFIED : 2005.04.14
// AUTHOR   : Renesas Technology Corp.
// HARDWARE : RENESAS ITS-DS7
// HISTORY  : 
//            2005.02.10
//            - Created release code.
//                (based on PUBLIC ATAPI driver for WCE5.0)
//            2005.04.14
//            - Modified ReadWriteDiskDMA.

//
// 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>

/*++

Module Name:
    diskmain.cpp

Abstract:
    Base ATA/ATAPI device abstraction.

Revision History:

--*/

static HANDLE g_hTestUnitReadyThread = NULL;

// ----------------------------------------------------------------------------
// Function: CDisk
//     Constructor
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

CDisk::CDisk(
    )
{
    // empty
}

// ----------------------------------------------------------------------------
// Function: CDisk
//     Constructor
//
// Parameters:
//     hKey -
// ----------------------------------------------------------------------------

CDisk::CDisk(
    HKEY hKey
    )
{
    m_dwDeviceFlags = 0;
    m_pNextDisk = NULL;
    m_pATAReg = NULL;
    m_pATARegAlt = NULL;
    m_dwDevice = 0;
    m_hDevKey = hKey;
    m_dwDeviceId = 0;
    m_dwPort = 0;
    m_f16Bit = FALSE;
    m_fAtapiDevice = FALSE;
    m_fInterruptSupported = FALSE;
    m_szDiskName = NULL;
    m_fDMAActive = FALSE;
    m_dwOpenCount = 0;
    m_dwUnitReadyTime = 0;
    m_dwStateFlag = 0;
    m_dwLastCheckTime = 0;
    m_dwStride = 1;
    m_pDiskPower = NULL;
    m_rgbDoubleBuffer = NULL;

    m_pPort = NULL;

	m_dwPioMode = 0;
	m_dwDmaMode = 0;
	m_dwUdmaMode = 0;

	m_dwBestPioMode = 0;
	m_dwBestDmaMode = 0;
	m_dwBestUdmaMode = 0;

	m_bTransferMode = 0;
	m_bDefaultTransferMode = 0;

    // init generic structures
    InitializeCriticalSection(&m_csDisk);
    memset(&m_Id, 0, sizeof(IDENTIFY_DATA));
    memset(&m_DiskInfo, 0, sizeof(DISK_INFO));
    memset(&m_InqData, 0, sizeof(INQUIRY_DATA));
}

// ----------------------------------------------------------------------------
// Function: ~CDisk
//     Destructor
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

CDisk::~CDisk(
    )
{
    if (m_hDevKey) {
        RegCloseKey(m_hDevKey);
    }

    if(m_pDiskPower != NULL) {
        delete m_pDiskPower;
    }

    DeleteCriticalSection(&m_csDisk);

    // deallocate double buffer, if present
    if (NULL != m_rgbDoubleBuffer) {
        LocalFree((HLOCAL)m_rgbDoubleBuffer);
    }
}

// ----------------------------------------------------------------------------
// Function: StallExecution
//     Stall execution for the specified period of time
//
// Parameters:
//     dwTime -
// ----------------------------------------------------------------------------

void
CDisk::StallExecution(
    DWORD dwTime
    )
{
    if ((dwTime >= 100) && (m_dwDeviceFlags & DFLAGS_DEVICE_CDROM)) {
        Sleep (dwTime / 100);
    }
    else {
        ::StallExecution(dwTime * 10);
    }
}

#define HELPER_

// These functions should be inlined or converted to macros
void CDisk::TakeCS()                    { EnterCriticalSection(&m_csDisk); }
void CDisk::ReleaseCS()                 { LeaveCriticalSection(&m_csDisk); }
void CDisk::Open()                      { InterlockedIncrement((LONG *)&m_dwOpenCount); }
void CDisk::Close()                     { InterlockedDecrement((LONG *)&m_dwOpenCount); }
BOOL CDisk::IsAtapiDevice()             { return m_fAtapiDevice; }
BOOL CDisk::IsCDRomDevice()             { return (((m_Id.GeneralConfiguration >> 8) & 0x1f) == ATA_IDDEVICE_CDROM); }
BOOL CDisk::IsDVDROMDevice()            { return TRUE; }
BOOL CDisk::IsDiskDevice()              { return (((m_Id.GeneralConfiguration >> 8) & 0x1f) == ATA_IDDEVICE_DISK); }
BOOL CDisk::IsRemoveableDevice()        { return (m_Id.GeneralConfiguration & IDE_IDDATA_REMOVABLE); }
BOOL CDisk::IsDMASupported()            { return ((m_Id.Capabilities & IDENTIFY_CAPABILITIES_DMA_SUPPORTED) && m_fDMAActive); }
BOOL CDisk::IsDRQTypeIRQ()              { return ((m_Id.GeneralConfiguration >> 5) & 0x0003) == ATA_DRQTYPE_INTRQ; }
WORD CDisk::GetPacketSize()             { return m_Id.GeneralConfiguration & 0x0003 ? 16 : 12; }
BOOL CDisk::IsValidCommandSupportInfo() { return ((m_Id.CommandSetSupported2 & (1 << 14)) && !(m_Id.CommandSetSupported2 & (1 << 15))); }
BOOL CDisk::IsWriteCacheSupported()     { return ((m_Id.CommandSetSupported1 & COMMAND_SET_WRITE_CACHE_SUPPORTED) && IsValidCommandSupportInfo()); }
BOOL CDisk::IsPMSupported()             { return (m_Id.CommandSetSupported1 & COMMAND_SET_POWER_MANAGEMENT_SUPPORTED && IsValidCommandSupportInfo()); }
BOOL CDisk::IsPMEnabled()               { return (IsPMSupported() && (m_Id.CommandSetFeatureEnabled1 & COMMAND_SET_POWER_MANAGEMENT_ENABLED)); }

// These functions are called (1x) in atamain and should be inlined
void CDisk::SetActiveKey(TCHAR *szActiveKey)
{
    wcsncpy(m_szActiveKey, szActiveKey, MAX_PATH - 1);
    m_szActiveKey[MAX_PATH - 1] = 0;
}

void CDisk::SetDeviceKey(TCHAR *szDeviceKey)
{
    wcsncpy(m_szDeviceKey, szDeviceKey, MAX_PATH - 1);
    m_szDeviceKey[MAX_PATH - 1] = 0;
}

#define _HELPER

// ----------------------------------------------------------------------------
// Function: InitController
//     Reset the controller and determine whether a device is present on the
//     channel; if a device is present, then query and store its capabilities
//
// Parameters:
//     fForce -
// ----------------------------------------------------------------------------

BOOL
CDisk::InitController(
    BOOL fForce
    )
{
    BOOL bRet = TRUE;

    // if the controller has not already been reset, then perform a soft-reset
    // to enable the channel

    if (!(m_dwDeviceFlags & DFLAGS_DEVICE_INITIALIZED)) {

        // perform a soft-reset on the controller; if we don't do this, then
        // we won't be able to detect whether or not devices are present on the
        // channel

        bRet = ResetController(FALSE);
        if (!bRet) {
            goto exit;
        }

        // if interrupt is supported, enable interrupt

        if (m_fInterruptSupported) {
            SelectDevice();
            WriteAltDriveController(ATA_CTRL_ENABLE_INTR);
            EnableInterrupt();
        }
    }

    // issue IDENTIFY DEVICE and/or IDENTIFY PACKET DEVICE

    bRet = Identify();
    if (!bRet) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!CDisk::InitController> Device did not respond to identify\r\n"
            )));
        goto exit;
    }
    else {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!CDisk::InitController> Device responded to identify\r\n"
            )));
        m_dwDeviceFlags |= DFLAGS_DEVICE_INITIALIZED;
    }

exit:;
    return bRet;
}

// ----------------------------------------------------------------------------
// Function: ConfigureRegisterBlock
//     This function is called by DSK_Init before any other CDisk function to
//     set up the register block.
//
// Parameters:
//     dwStride -
// ----------------------------------------------------------------------------

VOID
CDisk::ConfigureRegisterBlock(
    DWORD dwStride
    )
{
    m_dwStride = dwStride;
    m_dwDataDrvCtrlOffset = ATA_REG_DATA * dwStride;
    m_dwFeatureErrorOffset = ATA_REG_FEATURE * dwStride;
    m_dwSectCntReasonOffset = ATA_REG_SECT_CNT * dwStride;
    m_dwSectNumOffset = ATA_REG_SECT_NUM * dwStride;
    m_dwDrvHeadOffset = ATA_REG_DRV_HEAD * dwStride;
    m_dwCommandStatusOffset = ATA_REG_COMMAND * dwStride;
    m_dwByteCountLowOffset = ATA_REG_BYTECOUNTLOW * dwStride;
    m_dwByteCountHighOffset = ATA_REG_BYTECOUNTHIGH * dwStride;
    m_dwAltStatusOffset = 14 * dwStride;
    m_dwAltDrvCtrl = 14 * dwStride;
}

// ----------------------------------------------------------------------------
// Function: Init
//     This function is called by the IDE/ATA controller enumerator to trigger
//     the initialization of a device
//
// Parameters:
//     hActiveKey -
// ----------------------------------------------------------------------------

BOOL
CDisk::Init(
    HKEY hActiveKey
    )
{
    BOOL fRet = FALSE;

    // replicate CDisk::ReadRegistry

    m_dwWaitCheckIter = m_pPort->m_pController->m_pIdeReg->dwStatusPollCycles;
    m_dwWaitSampleTimes = m_pPort->m_pController->m_pIdeReg->dwStatusPollsPerCycle;
    m_dwWaitStallTime = m_pPort->m_pController->m_pIdeReg->dwStatusPollCyclePause;

    m_dwDiskIoTimeOut = DEFAULT_DISK_IO_TIME_OUT;

    // replicate CDisk::ReadSettings

    m_dwUnitReadyTime = DEFAULT_MEDIA_CHECK_TIME;

    // if DMA=2 and this is not an ATAPI device, then we'll set m_fDMAActive in Identify
    if (1 == m_pPort->m_pDskReg[m_dwDeviceId]->dwDMA) { // 0=PIO, 1=DMA, 2=ATA DMA only
        m_fDMAActive = TRUE;
    }
    m_dwDMAAlign = m_pPort->m_pController->m_pIdeReg->dwDMAAlignment;

    // m_dwDeviceFlags |= DFLAGS_DEVICE_ISDVD; this is ignored

    if (m_pPort->m_pDskReg[m_dwDeviceId]->dwInterruptDriven) {
        m_fInterruptSupported = TRUE;
    }

    // initialize controller

    if (!InitController(TRUE)) {
        DEBUGMSG(ZONE_INIT, (_T(
            "Atapi!CDisk::Init> Failed to initialize device\r\n"
            )));
        goto exit;
    }

    // set write cache mode, if write cache mode supported

    if (m_Id.CommandSetSupported1 & 0x20) {
        if (SetWriteCacheMode(m_pPort->m_pDskReg[m_dwDeviceId]->dwWriteCache)) {
            if (m_pPort->m_pDskReg[m_dwDeviceId]->dwWriteCache) {
                m_dwDeviceFlags |= DFLAGS_USE_WRITE_CACHE;
                DEBUGMSG(ZONE_INIT, (_T(
                    "Atapi!CDisk::Init> Enabled write cache\r\n"
                    )));
            }
            else {
                m_dwDeviceFlags &= ~DFLAGS_USE_WRITE_CACHE;
                DEBUGMSG(ZONE_INIT, (_T(
                    "Atapi!CDisk::Init> Disabled on device write cache\r\n"
                    )));
            }
        }
        else {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!CDisk::Init> Failed to set write cache mode\r\n"
                )));
        }
    }

    // set read look-ahead, if read look-ahead supported

    if ((m_Id.CommandSetSupported1 & 0x40) && m_pPort->m_pDskReg[m_dwDeviceId]->dwLookAhead) {
        if (SetLookAhead()) {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!CDisk::Init> Enabled read look-ahead\r\n"
                )));
        }
        else {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!CDisk::Init> Failed to enable read look-ahead\r\n"
                )));
        }
    }

    // set transfer mode, if a specific transfer mode was specified in the
    // device's instance key

    BYTE bTransferMode = (BYTE)m_pPort->m_pDskReg[m_dwDeviceId]->dwTransferMode;
    if (0xFF != bTransferMode) {
        if (0x00 == bTransferMode) {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!CDisk::Init> Selecting PIO default mode(0x%x)\r\n"
                ), bTransferMode));
        }
        else if (0x01 == bTransferMode) {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!CDisk::Init> Selecting PIO default mode(0x%x); disabled IORDY\r\n"
                ), bTransferMode));
        }
        else if ((bTransferMode & 0xF8) == 0x08) {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!CDisk::Init> Selecting PIO flow control mode %d (0x%x)\r\n"
                ), (bTransferMode & 0x08), bTransferMode));
        }
        else if ((bTransferMode & 0xF0) == 0x20) {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!CDisk::Init> Selecting Multi-word DMA mode %d (0x%x)\r\n"
                ), bTransferMode, bTransferMode));
        }
        else if ((bTransferMode & 0xF0) == 0x40) {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!CDisk::Init> Selecting Ultra DMA mode %d (0x%x)\r\n"
                ), bTransferMode, bTransferMode));
        }
        else {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!CDisk::Init> Unknown transfer mode(0x%x)\r\n"
                ), bTransferMode));
        }

⌨️ 快捷键说明

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