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

📄 atapiromi.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//

/*++

Module Name:
    atapiRomi.cpp
        based on atapipci.cpp

Abstract:
    ATA/ATAPI for 6410 Ref Board.

Revision History:

--*/

#include <windows.h>
#include <types.h>
#include <ceddk.h>
#include <bsp_cfg.h>
#include "atapiRomi.h"

#define DirectMode 1
#define IndirectMode 0

LONG CRomiDisk::m_lDeviceCount = 0;

static TCHAR *g_szPCICDRomDisk = TEXT("CD-ROM");
static TCHAR *g_szPCIHardDisk = TEXT("Hard Disk");

// ----------------------------------------------------------------------------
// Function: CreateRomi
//     Spawn function called by IDE/ATA controller enumerator
//
// Parameters:
//     hDevKey -
// ----------------------------------------------------------------------------


EXTERN_C
CDisk *
CreateRomi(
    HKEY hDevKey
    )
{
    return new CRomiDisk(hDevKey);
}

// ----------------------------------------------------------------------------
// Function: CRomiDisk
//     Constructor
//
// Parameters:
//     hKey -
// ----------------------------------------------------------------------------

CRomiDisk::CRomiDisk(
    HKEY hKey
    ) : CDisk(hKey)
{
    m_pStartMemory = NULL;
    m_pPort = NULL;
    m_pPhysList = NULL;
    m_pSGCopy = NULL;
    m_pPFNs = NULL;
    m_pPRDPhys = 0;
    m_pPRD = NULL;
    m_dwPhysCount = 0;
    m_dwSGCount = 0;
    m_dwPRDSize = 0;
    m_pBMCommand = NULL;

    InterlockedIncrement(&m_lDeviceCount);

    DEBUGMSG(ZONE_INIT|ZONE_PCI, (_T(
        "Atapi!CRomiDisk::CRomiDisk> device count(%d)\r\n"
        ), m_lDeviceCount));
}

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

CRomiDisk::~CRomiDisk(
    )
{
    FreeDMABuffers();

    if ( m_vpSYSCONRegs)
    {
        MmUnmapIoSpace((PVOID)m_vpSYSCONRegs, sizeof(S3C6410_SYSCON_REG));
        m_vpSYSCONRegs= NULL;
    }

    if ( m_vpIOPORTRegs)
    {
        MmUnmapIoSpace((PVOID)m_vpIOPORTRegs, sizeof(S3C6410_GPIO_REG));
        m_vpIOPORTRegs= NULL;
    }

    if ( m_pDMAVirtualAddress )
    {
        PHYSICAL_ADDRESS PhysicalAddress;

        PhysicalAddress.LowPart = m_DMAPhyaddress.LowPart;
        HalFreeCommonBuffer(0, 0, PhysicalAddress, (PVOID)m_pDMAVirtualAddress, FALSE);
        m_pDMAVirtualAddress = NULL;
    }

    InterlockedDecrement(&m_lDeviceCount);

    DEBUGMSG(ZONE_INIT|ZONE_PCI, (_T(
        "Atapi!CRomiDisk::~CRomiDisk> device count(%d)\r\n"
        ), m_lDeviceCount));
}

// ----------------------------------------------------------------------------
// Function: FreeDMABuffers
//     Deallocate DMA buffers
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

void
CRomiDisk::FreeDMABuffers(
    )
{
    if (m_pPRD) {
        FreePhysMem(m_pPRD);
        m_pPRDPhys = NULL;
        m_pPRD = NULL;
    }

    if (m_pPhysList) {
        // free the fixed pages; the variable pages should already be free
        for (DWORD i = 0; i < MIN_PHYS_PAGES; i++) {
            FreePhysMem(m_pPhysList[i].pVirtualAddress);
        }
        VirtualFree(m_pPhysList, UserKInfo[KINX_PAGESIZE], MEM_DECOMMIT);
        m_pPhysList = NULL;
    }

    if (m_pSGCopy) {
        VirtualFree(m_pSGCopy, UserKInfo[KINX_PAGESIZE], MEM_DECOMMIT);
        m_pSGCopy = NULL;
    }

    if (m_pPFNs) {
        VirtualFree(m_pPFNs, UserKInfo[KINX_PAGESIZE], MEM_DECOMMIT);
        m_pSGCopy = NULL;
    }

    if (m_pStartMemory) {
        VirtualFree(m_pStartMemory, 0, MEM_RELEASE);
        m_pStartMemory = NULL;
    }
    
    m_dwPhysCount = 0;
    m_dwSGCount = 0;
}

// ----------------------------------------------------------------------------
// Function: CopyDiskInfoFromPort
//     This function is not used
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

void
CRomiDisk::CopyDiskInfoFromPort(
    )
{
    ASSERT(m_pPort->m_dwRegBase != 0);
    m_pATAReg = (PBYTE)m_pPort->m_dwRegBase;
    m_pATARegAlt = (PBYTE)m_pPort->m_dwRegAlt;

    ASSERT(m_pPort->m_dwBMR != 0);
    m_pBMCommand = (LPBYTE)m_pPort->m_dwBMR;
}

// ----------------------------------------------------------------------------
// Function: WaitForInterrupt
//     Wait for interrupt
//
// Parameters:
//     dwTimeOut -
// ----------------------------------------------------------------------------

BOOL
CRomiDisk::WaitForInterrupt(
    DWORD dwTimeOut
    )
{
    BYTE bStatus;
    BOOL fRet = TRUE;
    DWORD dwRet;

    // wait for interrupt
    dwRet = WaitForSingleObject(m_pPort->m_hIRQEvent, dwTimeOut);
    if (dwRet == WAIT_TIMEOUT) {
        fRet = FALSE;
    }
    else {
        if (dwRet != WAIT_OBJECT_0) {
            if (!WaitForDisc(WAIT_TYPE_DRQ, dwTimeOut, 10)) {
                fRet = FALSE;
            }
        }
    }

    // read status; acknowledge interrupt
    bStatus = GetBaseStatus();
    if (bStatus & ATA_STATUS_ERROR) {
        bStatus = GetError();
        fRet = FALSE;
    }

    // signal interrupt done
    InterruptDone(m_pPort->m_dwSysIntr);

    return fRet;
}

// ----------------------------------------------------------------------------
// Function: EnableInterrupt
//     Enable channel interrupt
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

void
CRomiDisk::EnableInterrupt(
    )
{
    GetBaseStatus(); // acknowledge interrupt, if pending

    // signal interrupt done
    InterruptDone(m_pPort->m_dwSysIntr);
}

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

VOID
CRomiDisk::ConfigureRegisterBlock(
    DWORD dwStride
    )
{

    m_dwStride = dwStride;
    m_dwDataDrvCtrlOffset = ATA_PIO_DTR;//ATA_REG_DATA * dwStride;
    m_dwFeatureErrorOffset = ATA_PIO_FED;//ATA_REG_FEATURE * dwStride;
    m_dwSectCntReasonOffset = ATA_PIO_SCR;//ATA_REG_SECT_CNT * dwStride;
    m_dwSectNumOffset = ATA_PIO_LLR;//ATA_REG_SECT_NUM * dwStride;
    m_dwByteCountLowOffset = ATA_PIO_LMR;//ATA_REG_BYTECOUNTLOW * dwStride;
    m_dwByteCountHighOffset = ATA_PIO_LHR;//ATA_REG_BYTECOUNTHIGH * dwStride;
    m_dwDrvHeadOffset = ATA_PIO_DVR;//ATA_REG_DRV_HEAD * dwStride;
    m_dwCommandStatusOffset =ATA_PIO_CSD;// ATA_REG_COMMAND * dwStride;

    // PCI ATA implementations don't assign I/O resources for the first four
    // bytes, as they are unused

    m_dwAltStatusOffset = ATA_PIO_DAD;//8 * dwStride;//ATA_REG_ALT_STATUS * dwStride;
    m_dwAltDrvCtrl = ATA_PIO_DAD;//8 * dwStride;//ATA_REG_DRV_CTRL * dwStride;
}

// ----------------------------------------------------------------------------
// Function: Init
//     Initialize channel
//
// Parameters:
//     hActiveKey -
// ----------------------------------------------------------------------------

BOOL
CRomiDisk::Init(
    HKEY hActiveKey
    )
{
    BOOL bRet = FALSE;

    m_f16Bit = TRUE; // PCI is 16-bit

    // configure port
    if (!InitializePort()) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!CRomiDisk::Init> Failed to configure port; device(%u)\r\n"
            ), m_dwDeviceId));

        goto exit;
    }

    // assign the appropriate folder name
    m_szDiskName = (IsCDRomDevice() ? g_szPCICDRomDisk : g_szPCIHardDisk);

    // reserve memory for DMA buffers
    m_pStartMemory = (LPBYTE)VirtualAlloc(NULL, 0x10000, MEM_RESERVE, PAGE_READWRITE);
    if (!m_pStartMemory) {
        bRet = FALSE;
    }

    WriteReg(ATA_CONTROL, ReadReg(ATA_CONTROL) | 0x1);
    // finish intialization; i.e., initialize device
    bRet = CDisk::Init(hActiveKey);

    if ((m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA || m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA) && m_pDMAVirtualAddress == NULL)
    {
        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 );
    }

    if (m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA && ( m_Id.UltraDMASupport & 0x3f))
    {    
        for(int i=5;i>=0;i--) {
            if(m_Id.UltraDMASupport & (0x01<<i)) {
                m_dwCurrentUDMAMode = (i > 4) ? 4 : i;
                break; 
            }
        }     
        SetPioMode(PIO0);        
        SetUdmaMode();
        DEBUGMSG(ZONE_INIT, (_T("### ATA-Disk supports UDMA to 0x%x 0x%x\r\n"), m_Id.UltraDMASupport,m_dwCurrentUDMAMode));  
        m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA = FALSE;

    }
    else if (m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA)
    {
        SetPioMode(m_Id.AdvancedPIOxferreserved);
        m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA = FALSE;;    
        DEBUGMSG(ZONE_INIT, (_T("### ATA-Disk dose not support UDMA. It is running on PDMA\r\n")));  
    }
    else {
        SetPioMode(m_Id.AdvancedPIOxferreserved);
        m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA = FALSE;;        
        m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA = FALSE;;        
        DEBUGMSG(ZONE_INIT, (_T("### ATA-Disk is running on PIO MODE\r\n")));          
        DEBUGMSG(ZONE_INIT, (_T("Atapi!CDisk::Init> Disabled DMA\r\n")));
    }

    // associate interrupt event with IRQ
    if (!InterruptInitialize(
        m_pPort->m_dwSysIntr,
        m_pPort->m_hIRQEvent,
        NULL,
        0)
    ) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!CRomiDisk::ConfigPort> Failed to initialize interrupt(SysIntr(%d)) for device(%d)\r\n"
            ), m_pPort->m_dwSysIntr, m_dwDeviceId));
        bRet = FALSE;
    }

    if (!bRet) {
        goto exit;

⌨️ 快捷键说明

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