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

📄 bul_ohci.cpp

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  
    Bul_ohci.cpp
    
Abstract:  
    Bulverde Chip dependant part of the USB Open Host Controller Driver (OHCD).

Notes: 
--*/
#include <windows.h>
#include <ceddk.h>
#include <hcdddsi.h>
#include <bulverde.h>
#include <bulverde_usbohci.h>
// Constant
static const DWORD gcTotalAvailablePhysicalMemory = 65536; // 64K
static const DWORD gcHighPriorityPhysicalMemory = 0x4000; // 16K

LPVOID CreateBulverdeHcdObject(LPVOID lpvHcdPddObject,
        LPVOID lpvMemoryObject, LPCWSTR szRegKey, PUCHAR ioPortBase,
        DWORD dwSysIntr) ;

SOhcdPdd::SOhcdPdd (LPCTSTR lpActiveRegistry)
:   CMiniThread( 0, TRUE )
,   CRegistryEdit(HKEY_LOCAL_MACHINE, lpActiveRegistry )
{
    m_pDCCLKReg = NULL;
    m_pDCUSBOHCIReg = NULL;
    m_lpvMemoryObject = NULL;
    m_pvDmaVirtualAddress = NULL;             // DMA buffers as seen by the CPU
    m_dwDamBufferSize = 0;
    m_dwSysIntr = MAXDWORD;
    m_IsrHandle = NULL;
    m_bIsBuiltInDma = TRUE;
    m_pobMem = NULL;
    m_pobOhcd = NULL;
    m_hParentBusHandle =  CreateBusAccessHandle((LPCWSTR)g_dwContext);
    m_lpDriverReg = NULL;
    if (lpActiveRegistry) {
        DWORD dwLen = _tcslen(lpActiveRegistry);
        m_lpDriverReg = new TCHAR [ dwLen +1 ];
        if (m_lpDriverReg) {
            _tcscpy(m_lpDriverReg,lpActiveRegistry);
            m_lpDriverReg [ dwLen ] =0;
        }
    }
}
SOhcdPdd::~SOhcdPdd ()
{
    m_bTerminated=TRUE;
    ThreadStart();
    // Signal IST.
    ThreadStart();
    DisablePddInterrupts();
    ThreadTerminated(1000);
    //
    if (m_IsrHandle) {
        FreeIntChainHandler(m_IsrHandle);
    }
    
    if ( m_pobOhcd )
        HcdMdd_DestroyHcdObject( m_pobOhcd );
    if (m_pobMem)
        HcdMdd_DestroyMemoryObject(m_pobMem);
    
    if (m_pvDmaVirtualAddress) {        
        if (m_bIsBuiltInDma) {
            MmUnmapIoSpace(m_pvDmaVirtualAddress,0);
        }
        else {
            HalFreeCommonBuffer(&m_AdapterObject, m_dwDamBufferSize, m_DmaPhysicalAddr, m_pvDmaVirtualAddress, FALSE);
        }
    }
    if (m_lpDriverReg)
        delete m_lpDriverReg;
    if (m_pDCCLKReg)
        MmUnmapIoSpace((PVOID)m_pDCCLKReg,0);
    if (m_pDCUSBOHCIReg)
        MmUnmapIoSpace((PVOID)m_pDCUSBOHCIReg,0);
    if (m_pvDmaVirtualAddress)
        MmUnmapIoSpace(m_pvDmaVirtualAddress,0);
    if (m_hParentBusHandle)
        CloseBusAccessHandle(m_hParentBusHandle);

}
BOOL SOhcdPdd::Init()
{
    {
        PHYSICAL_ADDRESS ioPhysicalBase = { BULVERDE_BASE_REG_PA_CLKMGR, 0};
        m_pDCCLKReg = (PBULVERDE_CLKMGR_REG)MmMapIoSpace(ioPhysicalBase, sizeof(BULVERDE_CLKMGR_REG),FALSE);
    }
    {
        PHYSICAL_ADDRESS ioPhysicalBase = { BULVERDE_BASE_REG_PA_USBH, 0};
        m_pDCUSBOHCIReg = (PBULVERDE_USBOHCI_REG)MmMapIoSpace(ioPhysicalBase, sizeof(BULVERDE_USBOHCI_REG),FALSE);
    }
    if (m_pDCCLKReg && m_pDCUSBOHCIReg && IsKeyOpened()) {
        TurnOnUSBHostClocks();
        // Port 1
        SetupUSBHostPWR(1);
        SetupUSBHostPEN(1);
        // Port 2
        SetupUSBHostPWR(2);
        SetupUSBHostPEN(2);
        return (InitPddInterrupts() && OHCI_Reset() && InitializeOHCI());
    }
    return FALSE;
}
BOOL SOhcdPdd::InitializeOHCI()
{
    PUCHAR ioPortBase = NULL;
    DWORD dwAddrLen;
    DWORD dwIOSpace;
    BOOL InstallIsr = FALSE;
    BOOL fResult = FALSE;
    LPVOID pobMem = NULL;
    LPVOID pobOhcd = NULL;
    DWORD PhysAddr;
    HKEY hKey=NULL;

    DDKWINDOWINFO dwi;
    DDKISRINFO dii;

    // Setup Memory Windows For OHCI MDD code.
    dwi.cbSize=sizeof(dwi);
    PhysAddr = dwi.memWindows[0].dwBase = BULVERDE_BASE_REG_PA_USBH;
    dwAddrLen= dwi.memWindows[0].dwLen = 0x1000;
    dwi.dwInterfaceType = Internal;
    dwi.dwBusNumber = 0;
    dwi.dwNumMemWindows =1;
    dwIOSpace = 0;
        
    dii.cbSize=sizeof(dii);
    if (GetIsrInfo(&dii)  != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR,(TEXT("InitializeOHCI:DDKReg_GetWindowInfo or  DDKReg_GetWindowInfo failed\r\n")));
        return FALSE;
    }
    // Overwrite the item we know.
    dii.dwIrq = IRQ_USBOHCI;
    m_dwSysIntr = dii.dwSysintr;
    DEBUGMSG(ZONE_INIT,(TEXT("OHCD: Read config from registry: Base Address: 0x%X, Length: 0x%X, I/O Port: %s, SysIntr: 0x%X, Interface Type: %u, Bus Number: %u\r\n"),
                    PhysAddr, dwAddrLen, dwIOSpace ? L"YES" : L"NO", dii.dwSysintr, dwi.dwInterfaceType, dwi.dwBusNumber));
    
    ioPortBase = (PBYTE) PhysAddr;
    
    if (dii.szIsrDll[0] != 0 && dii.szIsrHandler[0]!=0 && dii.dwIrq<0xff && dii.dwIrq>0 ) {
        // Install ISR handler
        m_IsrHandle = LoadIntChainHandler(dii.szIsrDll, dii.szIsrHandler, (BYTE)dii.dwIrq);

        if (!m_IsrHandle) {
            DEBUGMSG(ZONE_ERROR, (L"OHCD: Couldn't install ISR handler\r\n"));
        } else {
            GIISR_INFO Info;
            PHYSICAL_ADDRESS PortAddress = {PhysAddr, 0};
            
            DEBUGMSG(ZONE_INIT, (L"OHCD: Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d\r\n",
                dii.szIsrDll, dii.szIsrHandler, dii.dwIrq));
            
            if (!BusTransBusAddrToStatic(m_hParentBusHandle,(INTERFACE_TYPE)dwi.dwInterfaceType, dwi.dwBusNumber, PortAddress, dwAddrLen, &dwIOSpace, (PVOID *)&PhysAddr)) {
                DEBUGMSG(ZONE_ERROR, (L"OHCD: Failed TransBusAddrToStatic\r\n"));
                return FALSE;
            }
        
            // Set up ISR handler
            Info.SysIntr = dii.dwSysintr;
            Info.CheckPort = TRUE;
            Info.PortIsIO = (dwIOSpace) ? TRUE : FALSE;
            Info.UseMaskReg = TRUE;
            Info.PortAddr = PhysAddr + 0x0C;
            Info.PortSize = sizeof(DWORD);
            Info.MaskAddr = PhysAddr + 0x10;
            
            if (!KernelLibIoControl(m_IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL)) {
                DEBUGMSG(ZONE_ERROR, (L"OHCD: KernelLibIoControl call failed.\r\n"));
            }
        }
    }
    DWORD dwDmaBase = 0;
    DWORD dwHPPhysicalMemSize = 0;
    if (!GetRegValue(BULVERDE_REG_DMA_BUFFER_PH_ADDR_VAL_NAME, (PBYTE)&dwDmaBase,BULVERDE_REG_DMA_BUFFER_PH_ADDR_VAL_LEN)) {
        DEBUGMSG(ZONE_INIT, (TEXT("SOhcdPdd::Init - Cann't get \"%s\" registry value.\r\n"),BULVERDE_REG_DMA_BUFFER_PH_ADDR_VAL_NAME));
        dwDmaBase = 0;
    }
    if (!GetRegValue(BULVERDE_REG_DMA_BUFFER_LENGTH_VAL_NAME, (PBYTE)&m_dwDamBufferSize,BULVERDE_REG_DMA_BUFFER_LENGTH_VAL_LEN)) {
        DEBUGMSG(ZONE_INIT, (TEXT("SOhcdPdd::Init - Cann't get \"%s\" registry value.\r\n"),BULVERDE_REG_DMA_BUFFER_LENGTH_VAL_NAME));
        m_dwDamBufferSize = 0;
    }
    if (dwDmaBase && m_dwDamBufferSize) {
        m_DmaPhysicalAddr.LowPart = dwDmaBase;
        m_DmaPhysicalAddr.HighPart = 0;
        m_pvDmaVirtualAddress = MmMapIoSpace(m_DmaPhysicalAddr,m_dwDamBufferSize, FALSE);
        dwHPPhysicalMemSize = m_dwDamBufferSize / 4  ; 
        m_bIsBuiltInDma = TRUE;
    }
    else { // we locate DMA buffer from public pool
        // The PDD can supply a buffer of contiguous physical memory here, or can let the 
        // MDD try to allocate the memory from system RAM.  We will use the HalAllocateCommonBuffer()
        // API to allocate the memory and bus controller physical addresses and pass this information
        // into the MDD.
        if (GetRegValue(REG_PHYSICAL_PAGE_SIZE, (PBYTE)&m_dwDamBufferSize, REG_PHYSICAL_PAGE_SIZE_LEN)) {
            dwHPPhysicalMemSize = m_dwDamBufferSize/4;
            m_dwDamBufferSize = (m_dwDamBufferSize+ PAGE_SIZE -1) & ~(PAGE_SIZE -1);
            // Align with page size.        
            dwHPPhysicalMemSize = ((dwHPPhysicalMemSize +  PAGE_SIZE -1) & ~(PAGE_SIZE -1));
        }
        else 
            m_dwDamBufferSize=0;
        
        if (m_dwDamBufferSize<gcTotalAvailablePhysicalMemory) { // Setup Minimun requirement.
            m_dwDamBufferSize = gcTotalAvailablePhysicalMemory;
            dwHPPhysicalMemSize = gcHighPriorityPhysicalMemory;
        }

        m_AdapterObject.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
        m_AdapterObject.InterfaceType = Internal;
        m_AdapterObject.BusNumber = 0 ;
        if ((m_pvDmaVirtualAddress = HalAllocateCommonBuffer(&m_AdapterObject, m_dwDamBufferSize, &m_DmaPhysicalAddr, FALSE)) == NULL) {
            DEBUGMSG(ZONE_INIT, (TEXT("SOhcdPdd::InitializeOHCI() - HalAllocateCommonBuffer return FALSE!!!\r\n.\r\n")));
            return FALSE;
        }
        m_bIsBuiltInDma = FALSE;
    }
    if (m_pvDmaVirtualAddress == NULL || 
            !(m_pobMem = HcdMdd_CreateMemoryObject(m_dwDamBufferSize, dwHPPhysicalMemSize, (PUCHAR) m_pvDmaVirtualAddress, (PUCHAR) m_DmaPhysicalAddr.LowPart))) {
        DEBUGMSG(ZONE_INIT, (TEXT("SOhcdPdd::InitializeOHCI() - Cann't CreateMemoryObject!!!\r\n.\r\n")));
        return FALSE;
    }

    if (!( m_pobOhcd  = CreateBulverdeHcdObject(this, m_pobMem, m_lpDriverReg, (PUCHAR)m_pDCUSBOHCIReg, m_dwSysIntr))) {
        DEBUGMSG(ZONE_INIT, (TEXT("SOhcdPdd::InitializeOHCI() - Cann't CreateHcdObject!!!\r\n.\r\n")));
        return FALSE;
    }

    return TRUE;
}
BOOL SOhcdPdd::InitPddInterrupts()
{
    DEBUGMSG(ZONE_INIT, (TEXT("SOhcdPdd::InitPddInterrupts() - Initial UHCHIE = 0x%x\r\n"),m_pDCUSBOHCIReg->uhchie));
    m_pDCUSBOHCIReg->uhchie = 0 ; // Mask All PDD interrupt.
    return TRUE;
}

BOOL SOhcdPdd::OHCI_Reset()
{
   DEBUGMSG(ZONE_INIT,(TEXT("OHCI_Reset: Resetting Bulverde OHCI.\r\n")));

   // Do the reset for the Bulverde part.
   // Two levels of reset need to be initiated:
   //	The OHCI core needs to be reset via the FHR bit,
   //	then the OHCI system bus interface needs to be reset via the FSBIR bit.

    // reset the OHC core and all OHC blocks driven by the 12 MHz clock, eg. write fifo, etc.
    m_pDCUSBOHCIReg->uhchr |=  XLLP_USBOHCI_UHCHR_FHR;
    Sleep(1);
    m_pDCUSBOHCIReg->uhchr &= ~XLLP_USBOHCI_UHCHR_FHR;

    // reset the OHC system bus interface, eg. SBI, DMA blocks, fifos, etc.
    m_pDCUSBOHCIReg->uhchr |=  XLLP_USBOHCI_UHCHR_FSBIR;
    while( m_pDCUSBOHCIReg->uhchr & XLLP_USBOHCI_UHCHR_FSBIR );	// auto clears in 3 system bus clocks

    DEBUGMSG(m_pDCUSBOHCIReg,(TEXT("OHCI_Reset: done.\r\n")));
    return TRUE;
}

// TurnOnUSBHostClocks:
//      This routine will make sure that the USB Host OHCI block in the
//      Bulverde core is getting clocks. If it is not getting clocks,
//      then some accesses to it may stall, especially if one needs to
//      wait for some OHCI register bits to change.
void
SOhcdPdd::TurnOnUSBHostClocks()
{
    // The clock enable bit for the USB Host OHCI block in Bulverde
    // is bit number 20.
    DEBUGMSG(ZONE_INIT,(TEXT("TurnOnUSBHostClocks: Initial Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), m_pDCCLKReg->cccr, m_pDCCLKReg->cken, m_pDCCLKReg->oscc, m_pDCCLKReg->ccsr));
    m_pDCCLKReg->cken |= XLLP_CLKEN_USBHOST;
    DEBUGMSG(ZONE_INIT,(TEXT("TurnOnUSBHostClocks: Final   Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), m_pDCCLKReg->cccr, m_pDCCLKReg->cken, m_pDCCLKReg->oscc, m_pDCCLKReg->ccsr));
}


// TurnOffUSBHostClocks:
//      This routine will make sure that the USB Host OHCI block in the
//      Bulverde core is not getting clocks. If it is not getting clocks,
//      then there will be power savings.
void
SOhcdPdd::TurnOffUSBHostClocks()
{
    // The clock enable bit for the USB Host OHCI block in Bulverde
    // is bit number 20.
    DEBUGMSG(ZONE_INIT,(TEXT("TurnOfUSBHostClocks: Initial Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), m_pDCCLKReg->cccr, m_pDCCLKReg->cken, m_pDCCLKReg->oscc, m_pDCCLKReg->ccsr));
    m_pDCCLKReg->cken &= ~XLLP_CLKEN_USBHOST;
    DEBUGMSG(ZONE_INIT,(TEXT("TurnOfUSBHostClocks: Final   Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), m_pDCCLKReg->cccr, m_pDCCLKReg->cken, m_pDCCLKReg->oscc, m_pDCCLKReg->ccsr));
}


void
SOhcdPdd::SelectUSBHOSTPowerManagementMode(
    int	Mode,
    int	NumPorts,
    int	*PortMode

⌨️ 快捷键说明

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