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

📄 phcd.cpp

📁 ISP1161 USB Driver under WinCE for StrongARM processor implementation
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*++
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.
Copyright (c) 1995-1998  Microsoft Corporation

Module Name:  
    phcd.cpp
Abstract:  
    This file implements the USB host controller driver for the
    Open HCI interface.
    
Notes: 

--*/


// There are four warnings that I like from Warning level 4.  Since we build
// at warning level 3, I'm setting these four down to level 3 so I still get
// them.
// C4100 unrefrenced formal parameter
// C4101 unrefrenced local variable
// C4705 statement has no effect
// C4706 assignment in conditional
#pragma warning (3 : 4100 4101 4705 4706)

#include <windows.h>
extern "C" {  // nkintr.h now contains this, but autopc doesn't have the latest,
              // so include here as well for now.
#include <nkintr.h>
}
#include <ceddk.h>
#include <phcdddsi.h>

#include "hcdi.h"
#include "globals.hpp"
#include "mem.hpp"
#include "hub.hpp"
#include "phcdinc.hpp"
#include "phcd.hpp"
#include "bcr.h"


#undef ZONE_HUB
#define ZONE_HUB 0

#undef ZONE_TD
#define ZONE_TD 0

#undef ZONE_WARNING
#define ZONE_WARNING 2

#define ISPDBG 0

#define PLAT_STRONGARM 

extern "C" PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);

// This flag will cause our free routines to overwrite structures with invalid
// data, to verify that no one is still accessing them.  For test only.
#undef  OVERWRITE_STRUCTS_ON_FREE
#ifdef  OVERWRITE_STRUCTS_ON_FREE
#define INVALID_STRUCT_DATA 0xff
#endif

// Define the following constant to be gcTdNoInterrupt to cause the HC to
// be interrupted only at the end of each transfer; this has some unpleasant
// side effects at the moment due to the way in which transfers are aborted
// and the fact that we don't track TDs well enough; nonetheless, you can get
// a performance gain with that setting if you don't do frequent power-suspend
// operations or hot-plugging of USB devices.
// Define the constant to be zero to get interrupts on every single TD.
// Note that we always arrange for an interrupt on the last TD of any transfer.

#define TDIRQ_NORM 0

#define NUM_ELEMENTS(a)  ((sizeof(a) / sizeof(a[0])))

const TCHAR gcszUSBDFileName[]     = TEXT("USBD.DLL");
const TCHAR gcszHcdAttach[]        = TEXT("HcdAttach");
const TCHAR gcszHcdDetach[]        = TEXT("HcdDetach");
const TCHAR gcszHcdDeviceAttach[]  = TEXT("HcdDeviceAttached");
const TCHAR gcszHcdDeviceDettach[] = TEXT("HcdDeviceDetached");

// Definitions for accessing PHCI registry values
const TCHAR gcPhciKeyName[]              = TEXT("Drivers\\PHCI");
const TCHAR gcPhciRsvdBandwidthValName[] = TEXT("ReservedBandwidth");


//#ifdef DEBUG
#if 1
static const TCHAR *szCfgStateStrings[] =
{
   TEXT("NoState"),
   TEXT("UsingAddr0"),
   TEXT("GettingInitialDescriptor"),
   TEXT("SettingAddress"),
   TEXT("GettingDeviceDescriptor"),
   TEXT("GettingInitialConfig"),
   TEXT("GettingConfig"),
   TEXT("SettingConfig"),
   TEXT("DoneConfig"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("HubGettingDescriptor"),
   TEXT("HubConfiguring"),
   TEXT("HubPoweringPorts"),
   TEXT("HubReady"),
   TEXT("HubClearingChanges"),
   TEXT("HubGettingPortStatus"),
   TEXT("HubStartingPortReset"),
   TEXT("HubResettingPort"),
   TEXT("HubWaitingForPortReset"),
   TEXT("HubWaitingForPortShutoff"),
   TEXT("HubKillingPort"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("Unused"),
   TEXT("HubWaitingForHubClearFlags"),
   TEXT("HubClearingLocalPowerFlag"),
   TEXT("HubClearingOverCurrentFlag"),
};

#define CONFIG_STATE_STR(pDev)  (( pDev->configStatus < NUM_ELEMENTS(szCfgStateStrings)) ? \
                                   szCfgStateStrings[pDev->configStatus] : TEXT("Invalid"))
#endif

// Inline function to copy data to or from a client buffer.  Return successful
// if copy was successful, or invalidBuffer if an exception occurs while copying
// the data.
//
// Note the dwPerms parameter - this is used for the PHCI interrupt thread, which
// may have different process permissions than the client that initiated the 
// transfer (e.g. if client driver exposes another interface and some application
// calls through with a buffer).  This isn't necessary as long as we are in the
// context of the thread that owns the memory, since permissions are automatically
// added in a PSL call.
static inline EError
CopyClientData(PUCHAR pDst, PUCHAR pSrc, UINT cLen, DWORD dwPerms)
{
    DWORD dwOldPerms;
    EError eRet;

    // Set process permissions for accessing client buffer, if necessary
    if (dwPerms)
        dwOldPerms = SetProcPermissions(dwPerms);
    __try {
        memcpy(pDst,pSrc,cLen);
        eRet = successful;
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {
        ERRORMSG(1,(TEXT("!PHCD: Exception copying client data: 0x%X-->0x%X (%u)\r\n"),
                     pSrc,pDst,cLen));
        eRet = invalidPtr;
    }
    if (dwPerms)
        SetProcPermissions(dwOldPerms);
    return eRet;
}

ULONG CALLBACK CPhcd::UsbDriverThreadStub(PVOID context)
{
    CPhcd* pHcd = (CPhcd*)context;
    return(pHcd->UsbDriverThread());
}

#ifdef USE_CRITICAL_THREAD
ULONG CALLBACK CPhcd::UsbDriverCriticalThreadStub(PVOID context)
{
    CPhcd* pHcd = (CPhcd*)context;
    return(pHcd->UsbDriverCriticalThread());
}
#endif // USE_CRITICAL_THREAD


ULONG CALLBACK CPhcd::Isp1161AuxThreadStub (PVOID context)
{
    CPhcd* pHcd = (CPhcd*)context;
    return(pHcd->Isp1161AuxThread());
}

DWORD CPhcd::Isp1161AuxThread(void)
{

	RETAILMSG(1, (TEXT("PHCD: Enter Isp1161AuxThread\r\n")));

	while (!m_bClosing)
    {
		WaitForSingleObject(m_hUsbInterrupt, INFINITE);
		RETAILMSG(1, (TEXT("PHCD: Got one interrupt\r\n")));

		InterruptDone(m_sysIntr);
	}
//	DumpRegisters();
	return 0;
}



CPhcd::CPhcd(LPVOID pvPhcdPddObject, CPhysMem * pobMem,
        LPCWSTR szDriverRegistryKey, REGISTER regBase, DWORD dwSysIntr)
{
    extern HCD_FUNCS gc_HcdFuncs;

    //save this to pass on the the USBD
    UnusedParameter(szDriverRegistryKey);

    UINT index;

    m_pHcdFuncs = &gc_HcdFuncs;

    m_pvPhcdPddObject = pvPhcdPddObject;
    m_pobMem = pobMem;
    m_regBase = regBase;
	
    m_sysIntr = dwSysIntr;

    m_nAdjustFrame = 0;
    m_fAdjust = FALSE;
    m_hAdjustmentEvent = NULL;

    m_numRootHubPorts = 0;
    m_PowerOnToPowerGoodTime = 0;
    m_bAddr0Busy = FALSE;
    m_addrThatOwnsAddr0 = 0;
    m_numPortsWaitingForAddr0 = 0;
    m_addr0CurRetryValue = 0;
    m_schedOverrunCount = 0;

    m_pHcca = NULL;
    m_paLastIntrEd = NULL;
                                                      
    DEBUGMSG(ZONE_INIT, (TEXT("PHCD: SysIntr = %d, regBase = 0x%X\r\n"),
             dwSysIntr, regBase));

    m_bClosing = FALSE;
    m_bPoweredUpAfterPowerDown = FALSE;
    m_fStabilizing = FALSE;

    m_fTimeWarp = FALSE;
    m_fWDH = FALSE;
    m_fSF = FALSE;
    m_fRHSC = FALSE;
    m_fSO = FALSE;
    m_fUE = FALSE;
    m_fFNO = FALSE;

    m_paWriteBackDone = 0;
    m_paWriteBackDone2 = 0;
    m_paLastWriteBackDone = 0;

    m_hClientDriverComplete = NULL;
    m_hUsbPsudoInterrupt = NULL;
    
    m_fCriticalRunning = FALSE;
#ifdef USE_CRITICAL_THREAD
    m_cCriticalTds = 0;
    m_hReleaseCriticalThread = NULL;
    m_hCriticalThreadDone = NULL;
    m_hCriticalThread = NULL;
#endif

    m_hUsbInterrupt = NULL;
    m_hIsrThread = NULL;

    m_nReserveFakeBandwidth  = 0;

	//Zouying
	m_EdpointServicedOne1ms  = 0;
	
	m_TdsPutToATLIndex       = 0;
	m_TdsPutToITLFirstIndex  = 0;
	m_TdsPutToITLSecondIndex = 0;

	
	m_ATLTransferLen		 = 0;


	m_ATLBeingReadOut		 = FALSE;
	m_bReDump				 = FALSE;
	
	for(UINT i=0; i< sizeof(m_bsPTDReDump)/sizeof(BOOL); i++)
		m_bsPTDReDump[i] = FALSE;

	m_DataToggleBit			 = 1;
	uFrameNumber			 = 0;
	uTimes					 = 0;

	
	m_HcBulkHeadED			= 0;
    m_HcBulkCurrentED		= 0;
	m_HcControlHeadED		= 0;
	m_HcControlCurrentED	= 0;
	m_HcHCCA				= 0;
	m_HcPeriodCurrentED		= 0;
	m_HcDoneHead			= 0;
	m_HcPeriodicStart		= 0;

	m_HcControlCBSR			= 4;
	m_HcControlPLE			= 0;
	m_HcControlIE			= 0;
	m_HcControlCLE			= 0;
	m_HcControlBLE			= 0;

	m_HcCommandCLF			= 0;
	m_HcCommandBLF			= 0;
	
	// Allow fake bandwidth to be initialized via registry.  This gives platforms
    // a way to account for delays in accessing the host bus, etc.
    HKEY hKey;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,gcPhciKeyName,0,KEY_READ,&hKey) == ERROR_SUCCESS) 
	{
        DWORD dwSize = sizeof(m_nReserveFakeBandwidth);
        
		if (RegQueryValueEx(hKey,gcPhciRsvdBandwidthValName,NULL,NULL,
                            (UCHAR *)&m_nReserveFakeBandwidth,&dwSize) == ERROR_SUCCESS) 
		{
            DEBUGMSG(ZONE_INIT,(TEXT("PHCD: Reserved bandwidth read from registry: %u\r\n"),
                                m_nReserveFakeBandwidth));
        }
        RegCloseKey(hKey);
    }

    m_dwFrameNumber = 0;

    m_pFreeSEdInfoHead = NULL;
    m_pFreePhysAddrHead = NULL;
    m_pFreeTransferHead = NULL;
    m_pFreeSTdInfoHead = NULL;

    m_curMaxNumDevices = gcInitialMaxNumDevices;
    m_ppDevices = new SDevice * [gcInitialMaxNumDevices];
    for (index = 0; index < gcInitialMaxNumDevices; index++)
    {
        m_ppDevices[index] = NULL;
    }

    m_pTdProcessList = NULL;
    m_pEdRemovalList = NULL;

    m_hUSBDInstance = NULL;
    m_pAttachProc = NULL;
    m_pDetachProc = NULL;

    m_pFreeThreadParamsHead = NULL;
    m_pActiveThreadParamsHead = NULL;

    InitializeCriticalSection(&m_csSTdInfoListLock);
    InitializeCriticalSection(&m_csThreadParamListLock);
    InitializeCriticalSection(&m_csAddr0Lock);
    InitializeCriticalSection(&m_csDeviceListLock);
    InitializeCriticalSection(&m_csOtherListsLock);
    InitializeCriticalSection(&m_csFrameAdjustment);
    InitializeCriticalSection(&m_csPortPower);
    InitializeCriticalSection(&m_csEdInfoListsLock);
    InitializeCriticalSection(&m_csTdListsLock);
    InitializeCriticalSection(&m_csScheduleLock);

#ifdef USE_CRITICAL_THREAD
    InitializeCriticalSection(&m_csClientInstallCriticalThread);
    InitializeCriticalSection(&m_csCriticalTds);
#endif // USE_CRITICAL_THREAD

    // now we check for certain values to ensure that the HC is present
    __try
    {

		
#ifdef PLAT_STRONGARM
		//edge trigger, active high, 16-bits
		WRITE_REGISTER_USHORT(HcWRHwConfig(m_regBase), 0x2F);
#else
		//Hardware config write, 
		//level trigger, active high, 16-bits
		WRITE_REGISTER_USHORT(HcWRHwConfig(m_regBase), 0x2D);
#endif
		//Hardware config read
		USHORT temp = READ_REGISTER_USHORT(HcRDHwConfig(m_regBase));
				
		RETAILMSG(1, (TEXT("PHCD: Hardware config %x\r\n"), temp));

		if(m_regBase)
        {
			DWORD dwRevision = READ_REGISTER_ULONG(HcRevision(m_regBase));
			
            if((dwRevision & gcHcRevisonMask) != gcHcRevisonNominal)
                m_regBase = 0;
        }
		
        if(m_regBase)

⌨️ 快捷键说明

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