📄 pci.c
字号:
CloseHandle( ghPCIDriver );
ghPCIDriver = NULL;
}
}
//---------------------------------------------------------------------------------------
// PUBLIC FUNCTION: pcibAddInterruptRegister()
//---------------------------------------------------------------------------------------
Boolean pcibAddInterruptRegister( UInt32 EnableRegOffset, UInt32 StatusRegOffset, UInt32 BitMask, UInt32 AccessSize, Boolean fRawStatus )
{
gLastError = PCIB_ERR_NONE;
if ( gISRInfo.nIntInfoItems < MAX_INT_REGS )
{
INT_STRUCT *pIntInfo = &gISRInfo.aIntInfo[gISRInfo.nIntInfoItems];
// Set our process ID if this is the first time here.
if ( gISRInfo.nIntInfoItems == 0 )
gISRInfo.dwProcessID = GetCurrentProcessId();
// Add this interrupt register information to interrupt register array.
pIntInfo->EnableReg = EnableRegOffset;
pIntInfo->StatusReg = StatusRegOffset;
pIntInfo->BitMask = BitMask;
pIntInfo->AccessSize= AccessSize;
pIntInfo->Flags = (fRawStatus) ? INTFLAG_RAWSTATUS : INTFLAG_NONE;
gISRInfo.nIntInfoItems++;
}
else
gLastError = PCIB_ERR_IRQ_FAILURE;
return (gLastError == PCIB_ERR_NONE);
}
//---------------------------------------------------------------------------------------
// PUBLIC FUNCTION: pcibHookInterrupt()
//---------------------------------------------------------------------------------------
Boolean pcibHookInterrupt( PISR_CALLBACK pISRCallback )
{
DWORD nReturned;
gLastError = PCIB_ERR_NONE;
// If the PCI driver has not been acquired, exit with an error.
if ( !ghPCIDriver )
{
gLastError = PCIB_ERR_ADAPTER_NOT_MAPPED;
return FALSE;
}
// If the caller passes a NULL callback, kill the ISR hook and return successful.
if ( pISRCallback == NULL )
{
UnhookInterrupt();
return TRUE;
}
// If an ISR is already hooked and active, allow the caller to change the callback ISR.
if ( gfISRHooked )
{
gpISRCallback = pISRCallback;
return TRUE;
}
gLastError = PCIB_ERR_IRQ_FAILURE; // Assume code below fails, set to no error is everything is OK.
// Now, ask the driver to hook in the new ISR callback.
gfISRHooked = DeviceIoControl( ghPCIDriver, IOCTL_SED_HOOK_ISR_CALLBACK, (LPVOID)&gISRInfo, sizeof(gISRInfo), &ghISRId, sizeof(ghISRId), &nReturned, NULL );
if ( gfISRHooked )
{
HANDLE hISREvent; // ISR thread completion/unblock event
// Create the ISR complete/unblock event handle.
hISREvent = CreateEvent( NULL, TRUE, FALSE, NULL ); // Manual reset, Initial State = non-signaled, Unnamed object
if ( hISREvent )
{
HANDLE hISRThread; // Thread handle to ISR dispatcher code
DWORD dwISRThreadId; // Thread ID of ISR dispatcher code
gpISRCallback = pISRCallback;
// Create the ISR dispatcher thread itself.
// (handle cannot be inherited, use default stack size, pass event handle to thread, thread to run immediately).
hISRThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)DispatchPCIInterrupt, hISREvent, 0, &dwISRThreadId );
if ( hISRThread )
{
// Raise the thread priority up to "very high".
SetThreadPriority( hISRThread, THREAD_PRIORITY_TIME_CRITICAL ); // DSM FIXIT: Juro says not needed???
CloseHandle( hISRThread ); // Release the thread handle.
gLastError = PCIB_ERR_NONE; // Flag that everything is OK.
}
else
CloseHandle( hISREvent );
}
}
if ( gLastError != PCIB_ERR_NONE )
UnhookInterrupt();
return (gLastError == PCIB_ERR_NONE);
}
//---------------------------------------------------------------------------
// PUBLIC FUNCTION: pcibGetLastError() - Get last error code.
//---------------------------------------------------------------------------
int pcibGetLastError( void )
{
return gLastError;
}
//---------------------------------------------------------------------------
// PUBLIC FUNCTION: pcibGetLastErrorText() - Get last error text.
//---------------------------------------------------------------------------
const char * pcibGetLastErrorText( void )
{
static const char * const apszErrors[] =
{
"No error", // PCIB_ERR_NONE
"Adapter not found", // PCIE_ERR_ADAPTER_NOT_FOUND
"Driver not found", // PCIB_ERR_DRIVER_NOT_FOUND
"IRQ failure", // PCIB_ERR_IRQ_FAILURE
"Adapter not mapped", // PCIB_ERR_ADAPTER_NOT_MAPPED
"Unknown error" // PCIB_ERR_UNKNOWN_ERROR - MUST BE LAST!!!
};
if ( gLastError < 0 || gLastError > PCIB_ERR_UNKNOWN_ERROR )
return apszErrors[PCIB_ERR_UNKNOWN_ERROR];
return apszErrors[gLastError];
}
//---------------------------------------------------------------------------
// PRIVATE FUNCTION: UnhookInterrupt()
//---------------------------------------------------------------------------
static void UnhookInterrupt( void )
{
DWORD nReturned;
// Remove the active application ISR callback, if any.
gpISRCallback = NULL;
// If the ISR is still hooked, ask the driver to take it down.
if ( gfISRHooked )
{
gfISRHooked = FALSE;
// There is previously hooked ISR, ask the driver to unhook it if the driver is still alive.
if ( ghPCIDriver )
DeviceIoControl( ghPCIDriver, IOCTL_SED_UNHOOK_ISR_CALLBACK, (LPVOID)&gISRInfo, sizeof(gISRInfo), &ghISRId, sizeof(ghISRId), &nReturned, NULL );
}
}
//---------------------------------------------------------------------------
// PRIVATE FUNCTION: DispatchPCIInterrupt()
//---------------------------------------------------------------------------
static Boolean DispatchPCIInterrupt( LPVOID hISREvent )
{
DWORD nReturned;
OVERLAPPED OverLapped;
OverLapped.hEvent = (HANDLE)hISREvent;
OverLapped.Offset = 0;
OverLapped.OffsetHigh = 0;
while ( gfISRHooked )
{
if ( !WriteFile(ghPCIDriver, &ghISRId, sizeof(ghISRId), &nReturned, &OverLapped) )
{
if ( GetLastError() != ERROR_IO_PENDING )
continue;
WaitForSingleObject( OverLapped.hEvent, INFINITE );
ResetEvent( OverLapped.hEvent );
}
if ( !gfISRHooked )
break;
if ( gpISRCallback )
gpISRCallback();
}
CloseHandle( OverLapped.hEvent );
return TRUE;
}
//---------------------------------------------------------------------------
// PLATFORM FUNCTION: halpMapPhysicalToVirtual()
//---------------------------------------------------------------------------
int halpMapPhysicalToVirtual( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize )
{
pcibUnmapAddress();
return Pci2Hal( pcibMapAddress(PhysicalAddr,pVirtualAddr,pBlockSize) );
}
//---------------------------------------------------------------------------
// PRIVATE FUNCTION: Pci2Hal() - Map PCI to HAL return code. >>>WIN32 ONLY<<<
//---------------------------------------------------------------------------
static int Pci2Hal( Boolean fPCIResult )
{
int Result = ERR_NONE;
if ( !fPCIResult )
{
switch ( pcibGetLastError() )
{
case PCIE_ERR_ADAPTER_NOT_FOUND: Result = ERR_PCI_ADAPTER_NOT_FOUND; break;
case PCIB_ERR_DRIVER_NOT_FOUND: Result = ERR_PCI_DRIVER_NOT_FOUND; break;
case PCIB_ERR_IRQ_FAILURE: Result = ERR_IRQ_FAILURE; break;
case PCIB_ERR_ADAPTER_NOT_MAPPED: Result = ERR_NOT_ACQUIRED; break;
default: Result = ERR_FAILED; break;
}
}
return Result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -