?? phcd.cpp
字號:
{
DWORD dwInterval = READ_REGISTER_ULONG(HcFmInterval(m_regBase));
dwInterval &= gcHcFmIntervalFImask;
if(dwInterval != gcHcFmIntervalNominal)
m_regBase = 0;
}
if(m_regBase)
{
DWORD dwThreshold = READ_REGISTER_ULONG(HcLSThreshold(m_regBase));
#if 0 // the CMD HC uses a non-standard threshold; hosts using their chip cannot make this check.
if((dwThreshold & gcHcLSThresholdLSTmask) != gcHcLSThresholdNominal)
m_regBase = 0;
#endif
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
m_regBase = 0;
}
}
CPhcd::~CPhcd()
{
DWORD dwWaitReturn;
UINT dev, endpt;
SDevice *pDev;
SEndpoint *pEndpt;
m_bClosing = TRUE;
// Most of this destructor is never used! We can remove
// the parts that are never called...
// Wake up the interrupt thread and give it time to die.
if(m_hUsbInterrupt)
SetEvent(m_hUsbInterrupt);
// set the psudo interrupt to free it too
if(m_hUsbPsudoInterrupt)
SetEvent(m_hUsbPsudoInterrupt);
if (m_hIsrThread)
{
dwWaitReturn = WaitForSingleObject(m_hIsrThread, 1000);
if (dwWaitReturn != WAIT_OBJECT_0)
{
TerminateThread(m_hIsrThread, DWORD(-1));
}
CloseHandle(m_hIsrThread);
m_hIsrThread = NULL;
}
#ifdef USE_CRITICAL_THREAD
if (m_hCriticalThread)
{
dwWaitReturn = WaitForSingleObject(m_hCriticalThread, 1000);
if (dwWaitReturn != WAIT_OBJECT_0)
{
TerminateThread(m_hCriticalThread, DWORD(-1));
}
CloseHandle(m_hCriticalThread);
m_hCriticalThread = NULL;
}
if(m_hReleaseCriticalThread)
{
CloseHandle(m_hReleaseCriticalThread);
m_hReleaseCriticalThread = NULL;
}
if(m_hCriticalThreadDone)
{
CloseHandle(m_hCriticalThreadDone);
m_hCriticalThreadDone = NULL;
}
#endif // USE_CRITICAL_THREAD
// we have to close our interrupt before closing the event!
InterruptDisable(m_sysIntr);
if(m_hUsbInterrupt)
{
CloseHandle(m_hUsbInterrupt);
m_hUsbInterrupt = NULL;
}
if(m_hUsbPsudoInterrupt)
{
CloseHandle(m_hUsbPsudoInterrupt);
m_hUsbPsudoInterrupt = NULL;
}
if(m_hClientDriverComplete)
{
CloseHandle(m_hClientDriverComplete);
m_hClientDriverComplete = NULL;
}
if(m_regBase)
{
// let's stop ALL TD processing
DisableControlList(m_regBase);
DisableBulkList(m_regBase);
DisableIntrAndIsochLists(m_regBase);
}
// wait long enough for all transfers to stop (10 ms - because the frame
// length can change... I assume nobody makes it this long though)
Sleep(10);
if(m_hUSBDInstance)
{
LPUSBD_HCD_DETACH_PROC lpHcdDetachProc;
lpHcdDetachProc = (LPUSBD_HCD_DETACH_PROC)
GetProcAddress(m_hUSBDInstance, gcszHcdDetach);
if(lpHcdDetachProc)
(*lpHcdDetachProc)(m_pvHcdContext);
FreeLibrary(m_hUSBDInstance);
}
for(dev = 0 ; dev < m_curMaxNumDevices ; dev++)
{
pDev = m_ppDevices[dev];
if (pDev != NULL)
{
if(pDev->pHubPorts)
delete [] pDev->pHubPorts;
// if(pDev->pnHubPortPowerDraw)
// delete [] pDev->pnHubPortPowerDraw;
if (pDev->ppEndpts != NULL)
{
for (endpt = 0; endpt < pDev->maxEndpts; endpt++)
{
pEndpt = pDev->ppEndpts[endpt];
if (pEndpt != NULL)
{
STransfer *pTransferHead;
pTransferHead = pEndpt->pTransferHead;
while (pTransferHead != NULL)
{
pEndpt->pTransferHead = pTransferHead->pNext;
if(pTransferHead->aCopyLengths)
delete [] pTransferHead->aCopyLengths;
delete pTransferHead;
pTransferHead = pEndpt->pTransferHead;
}
DeleteCriticalSection(&pEndpt->csSTransferListLock);
#ifdef USE_CRITICAL_THREAD
DeleteCriticalSection(&pEndpt->csCriticalThreadCancel);
#endif
delete pEndpt;
}
}
delete [] pDev->ppEndpts;
}
if (pDev->pfEndptAbortTransfers)
{
delete [] pDev->pfEndptAbortTransfers;
}
if(pDev->ohciDevice.lpConfigs)
{
LPPHCI_CONFIGURATION lpConfig = pDev->ohciDevice.lpConfigs;
for(UINT iConfig = 0 ; iConfig <
pDev->ohciDevice.Descriptor.bNumConfigurations ;
++iConfig, ++lpConfig)
{
if(lpConfig->lpInterfaces)
{
LPPHCI_INTERFACE lpInterface = lpConfig->lpInterfaces;
for(UINT iInterface = 0 ; iInterface <
lpConfig->Descriptor.bNumInterfaces ;
++iInterface, ++lpInterface)
{
if(lpInterface->lpEndpoints)
{
LPPHCI_ENDPOINT lpEndpoint =
lpInterface->lpEndpoints;
for(UINT iEndpoint = 0 ; iEndpoint <
lpInterface->Descriptor.bNumEndpoints ;
++iEndpoint, ++lpEndpoint)
{
if(lpEndpoint->lpbExtended)
delete lpEndpoint->lpbExtended;
}
delete [] lpInterface->lpEndpoints;
}
if(lpInterface->lpbExtended)
delete [] lpInterface->lpbExtended;
}
delete [] lpConfig->lpInterfaces;
}
if(lpConfig->lpbExtended)
delete [] lpConfig->lpbExtended;
}
delete [] pDev->ohciDevice.lpConfigs;
}
DeleteCriticalSection(&pDev->csAccessingEndpointArray);
DeleteCriticalSection(&pDev->csAttachementDetachement);
delete pDev;
}
}
if(m_ppDevices)
delete [] m_ppDevices;
if (m_PortPowerAllocated)
delete [] m_PortPowerAllocated;
STdInfo * pFreeSTdInfoHead;
pFreeSTdInfoHead = m_pFreeSTdInfoHead;
while (pFreeSTdInfoHead != NULL)
{
m_pFreeSTdInfoHead = pFreeSTdInfoHead->pNext;
delete pFreeSTdInfoHead;
pFreeSTdInfoHead = m_pFreeSTdInfoHead;
}
STdInfo * pTdRemovalList;
pTdRemovalList = m_pTdProcessList;
while (pTdRemovalList != NULL)
{
m_pTdProcessList = pTdRemovalList->pNext;
delete pTdRemovalList;
pTdRemovalList = m_pTdProcessList;
}
SEdInfo * pFreeSEdInfoHead;
pFreeSEdInfoHead = m_pFreeSEdInfoHead;
while (pFreeSEdInfoHead != NULL)
{
m_pFreeSEdInfoHead = pFreeSEdInfoHead->pNext;
delete pFreeSEdInfoHead;
pFreeSEdInfoHead = m_pFreeSEdInfoHead;
}
SEdInfo * pEdRemovalList;
pEdRemovalList = m_pEdRemovalList;
while (pEdRemovalList != NULL)
{
m_pEdRemovalList = pEdRemovalList->pNext;
delete pEdRemovalList;
pEdRemovalList = m_pEdRemovalList;
}
SPhysAddr * pFreePhysAddrHead;
pFreePhysAddrHead = m_pFreePhysAddrHead;
while (pFreePhysAddrHead != NULL)
{
m_pFreePhysAddrHead = pFreePhysAddrHead->pNext;
delete pFreePhysAddrHead;
pFreePhysAddrHead = m_pFreePhysAddrHead;
}
STransfer * pFreeTransferHead;
pFreeTransferHead = m_pFreeTransferHead;
while (pFreeTransferHead != NULL)
{
m_pFreeTransferHead = pFreeTransferHead->pNext;
delete pFreeTransferHead;
pFreeTransferHead = m_pFreeTransferHead;
}
SThreadParams * pFreeThreadParamsHead;
pFreeThreadParamsHead = m_pFreeThreadParamsHead;
while (pFreeThreadParamsHead != NULL)
{
m_pFreeThreadParamsHead = pFreeThreadParamsHead->pNext;
delete pFreeThreadParamsHead;
pFreeThreadParamsHead = m_pFreeThreadParamsHead;
}
DeleteCriticalSection(&m_csSTdInfoListLock);
DeleteCriticalSection(&m_csThreadParamListLock);
DeleteCriticalSection(&m_csAddr0Lock);
DeleteCriticalSection(&m_csDeviceListLock);
DeleteCriticalSection(&m_csOtherListsLock);
DeleteCriticalSection(&m_csFrameAdjustment);
DeleteCriticalSection(&m_csPortPower);
DeleteCriticalSection(&m_csEdInfoListsLock);
DeleteCriticalSection(&m_csTdListsLock);
DeleteCriticalSection(&m_csScheduleLock);
#ifdef USE_CRITICAL_THREAD
DeleteCriticalSection(&m_csClientInstallCriticalThread);
DeleteCriticalSection(&m_csCriticalTds);
#endif
}
BOOL CPhcd::Initialize(void)
{
BOOL bOk;
EError errorCode;
RETAILMSG(ISPDBG,(TEXT("+PHCD::Initialize\r\n")));
if(!m_regBase)
{
return FALSE;
}
m_hUSBDInstance = LoadDriver(gcszUSBDFileName);
if(m_hUSBDInstance)
{
m_pAttachProc = (LPUSBD_ATTACH_PROC)
GetProcAddress(m_hUSBDInstance, gcszHcdDeviceAttach);
m_pDetachProc = (LPUSBD_DETACH_PROC)
GetProcAddress(m_hUSBDInstance, gcszHcdDeviceDettach);
if(!m_pAttachProc || !m_pDetachProc)
return FALSE;
LPUSBD_HCD_ATTACH_PROC lpHcdAttachProc;
lpHcdAttachProc = (LPUSBD_HCD_ATTACH_PROC)
GetProcAddress(m_hUSBDInstance, gcszHcdAttach);
if(lpHcdAttachProc)
(*lpHcdAttachProc)((LPVOID)this, m_pHcdFuncs, &m_pvHcdContext);
else
return FALSE;
}
else
return FALSE;
m_numRootHubPorts = READ_REGISTER_ULONG(HcRhDescriptorA(m_regBase))
& gcRhDescriptorANDPmask;
m_PortPowerAllocated = new DWORD [gcFirstRootPortNum + m_numRootHubPorts];
// each port has 100 mA to start with for a new device to draw
for(UINT iPower = gcFirstRootPortNum ;
iPower < m_numRootHubPorts + gcFirstRootPortNum ;
iPower++)
m_PortPowerAllocated[iPower] = 100;
m_PowerOnToPowerGoodTime = ((READ_REGISTER_ULONG(HcRhDescriptorA(m_regBase))
& gcRhDescriptorAPOTPGTmask) >> 24) * 2;
DEBUGMSG(ZONE_INIT,(TEXT("PHCI:PowerOn2PowerGood: %u\r\n"), m_PowerOnToPowerGoodTime));
// We've got three threads, one for the interrupt DPC, another used
// exclusively for bus enumeration (handling connects and disconnects),
// and another for critical processing
#ifdef USE_CRITICAL_THREAD
m_hReleaseCriticalThread = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hReleaseCriticalThread == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("PHCD: Error on CreateEvent\r\n")));
// return(STATUS_UNSUCCESSFUL);
return FALSE;
}
m_hCriticalThreadDone = CreateEvent(NULL, FALSE, FALSE, NULL);
if(m_hCriticalThreadDone == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("PHCD: Error on CreateEvent\r\n")));
// return(STATUS_UNSUCCESSFUL);
return FALSE;
}
#endif
m_hUsbPsudoInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hUsbPsudoInterrupt == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("PHCD: Error on CreateEvent\r\n")));
// return(STATUS_UNSUCCESSFUL);
return FALSE;
}
m_hUsbInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hUsbInterrupt == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("PHCD: Error on CreateEvent for interrupt\r\n")));
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -