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

📄 diskmain.cpp

📁 3sc2443的CF卡IDE源代码,肯定好用.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// 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 <bsp_cfg.h>
/*++

Module Name:
    diskmain.cpp

Abstract:
    Base ATA/ATAPI device abstraction.

Revision History:

--*/

// 48-bit LBA support
#define  ATA_CMD_FLUSH_CACHE_EXT                0xEA
#define  ATA_CMD_READ_DMA_EXT                   0x25
#define  ATA_CMD_READ_DMA_QUEUED_EXT            0x26
#define  ATA_CMD_READ_LOG_EXT                   0x2F
#define  ATA_CMD_READ_MULTIPLE_EXT              0x29
#define  ATA_CMD_READ_NATIVE_MAX_ADDRESS_EXT    0x27
#define  ATA_CMD_READ_SECTOR_EXT                0x24
#define  ATA_CMD_READ_VERIFY_SECTOR             0x42
#define  ATA_CMD_SET_MAX_ADDRESS_EXT            0x37
#define  ATA_CMD_WRITE_DMA_EXT                  0x35
#define  ATA_CMD_DMA_QUEUED_EXT                 0x36
#define  ATA_CMD_WRITE_LOG_EXT                  0x3F
#define  ATA_CMD_WRITE_MULTIPLE_EXT             0x39
#define  ATA_CMD_WRITE_SECTOR_EXT               0x34

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_fUseLBA48 = 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;

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

	m_dwCurrentUDMAMode = 0;
 }

// ----------------------------------------------------------------------------
// 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);
    }

	if (m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA)
	{
		HalFreeCommonBuffer( NULL, 0, m_DMAPhyaddress, m_pDMAVirtualAddress, FALSE );	
	}
}

// ----------------------------------------------------------------------------
// 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 (TRUE || !(m_dwDeviceFlags & DFLAGS_DEVICE_INITIALIZED)) { // for Wakeup 070625 Hsjang

        // 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"
            )));
        RETAILMSG(1, (_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 = ATA_REG_ALT_STATUS_CS1 * dwStride;
    m_dwAltDrvCtrl = ATA_REG_DRV_CTRL_CS1 * 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;
    }

	if (m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA)
	{
		DMA_ADAPTER_OBJECT dmaAdapter;
        dmaAdapter.ObjectSize = sizeof(dmaAdapter);
        dmaAdapter.InterfaceType = Internal;
        dmaAdapter.BusNumber = 0;
		m_pDMAVirtualAddress= (PBYTE)HalAllocateCommonBuffer( &dmaAdapter, m_pPort->m_pDskReg[m_dwDeviceId]->dwDoubleBufferSize, &m_DMAPhyaddress, FALSE );
	}
	
    // set write cache mode, if write cache mode supported
		
	//SetPioMode(m_Id.AdvancedPIOxferreserved);

    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"
                    )));
                RETAILMSG(1, (_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"
                    )));
                RETAILMSG(1, (_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"
                )));
            RETAILMSG(1, (_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

⌨️ 快捷键说明

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