📄 pcidp_if.cpp
字号:
else
RTNStatus = ERROR_INVALID_HANDLE;
return RTNStatus;
}
// ----------------------------------------------------------------------------
// MapBaseRegister -
// ----------------------------------------------------------------------------
unsigned long Krnl_MapBaseRegister(
in unsigned long PCIDPHandle,
in unsigned long RegisterNumber,
in out unsigned long* Length,
out unsigned long** Address,
out unsigned long* IOAddress,
out unsigned long* IOSpace
){
// Declare variables.
unsigned long RTNStatus;
PCIDP00_MAP_BASE_REGS_SEND Input;
PCIDP00_MAP_BASE_REGS_RECV Output;
unsigned long BoardNumber;
// Initialize variables.
Input.RegNumber = RegisterNumber;
Input.Length = *Length;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Map Base Regs.
BoardNumber = PCIDPHandle & 0x7;
RTNStatus = RequestService(
BoardNumber,
IOCTL_PCIDP00_MAP_BASE_REGS,
&Input,
&Output,
sizeof(Input),
sizeof(Output)
);
if(RTNStatus == ERROR_SUCCESS){
*Length = Output.Length;
*IOSpace = Output.IOSpace;
if(*IOSpace == 0)
*Address = (unsigned long*)Output.Address;
else
*IOAddress = Output.Address;
}
}
else
RTNStatus = ERROR_INVALID_HANDLE;
return RTNStatus;
}
// ----------------------------------------------------------------------------
// UnMapBaseRegister -
// ----------------------------------------------------------------------------
unsigned long Krnl_UnMapBaseRegister(
in unsigned long PCIDPHandle,
in unsigned long* Address
){
// Declare variables.
unsigned long RTNStatus;
PCIDP00_UNMAP_SEND Input;
unsigned long BoardNumber;
// Initialize variables.
Input.VirtualAddress = (unsigned long)Address;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Unmap.
BoardNumber = PCIDPHandle & 0x7;
RTNStatus = RequestService(
BoardNumber,
IOCTL_PCIDP00_UNMAP,
&Input,
NULL,
sizeof(Input),
0
);
}
else
RTNStatus = ERROR_INVALID_HANDLE;
return RTNStatus;
}
// ----------------------------------------------------------------------------
// MapDMAMemory -
// ----------------------------------------------------------------------------
unsigned long Krnl_MapDMAMemory(
in unsigned long PCIDPHandle,
out unsigned long** LinearAddress,
out unsigned long* PhysicalAddress
){
// Declare variables.
unsigned long RTNStatus;
PCIDP00_MAP_DMA_MEM_RECV Output;
unsigned long BoardNumber;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Map DMA Mem.
BoardNumber = PCIDPHandle & 0x7;
RTNStatus = RequestService(
BoardNumber,
IOCTL_PCIDP00_MAP_DMA_MEM,
NULL,
&Output,
0,
sizeof(Output)
);
if(RTNStatus == ERROR_SUCCESS){
*LinearAddress = (unsigned long*)Output.LinearAddress;
*PhysicalAddress = Output.PhysicalAddress;
CancelMapDMAMemory(PCIDPHandle, *LinearAddress);
}
}
else
RTNStatus = ERROR_INVALID_HANDLE;
return RTNStatus;
}
// ----------------------------------------------------------------------------
// UnMapDMAMemory -
// ----------------------------------------------------------------------------
unsigned long Krnl_UnMapDMAMemory(
in unsigned long PCIDPHandle,
in unsigned long* Address
){
// Declare variables.
unsigned long RTNStatus;
PCIDP00_UNMAP_DMA_SEND Input;
unsigned long BoardNumber;
// Initialize variables.
Input.LinearAddress = (unsigned long)Address;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Unmap.
BoardNumber = PCIDPHandle & 0x7;
RTNStatus = RequestService(
BoardNumber,
IOCTL_PCIDP00_UNMAP_DMA,
&Input,
NULL,
sizeof(Input),
0
);
}
else
RTNStatus = ERROR_INVALID_HANDLE;
return RTNStatus;
}
// ----------------------------------------------------------------------------
// GetPCIConfigurationSpace -
// ----------------------------------------------------------------------------
unsigned long Krnl_GetPCIConfigurationSpace(
in unsigned long PCIDPHandle,
out unsigned long* PCIConfiguration
){
// Declare variables.
unsigned long RTNStatus;
PCIDP00_GET_PCI_CONFIG_REGS_RECV Output;
unsigned long BoardNumber;
unsigned long i;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Get PCI Config Regs.
BoardNumber = PCIDPHandle & 0x7;
RTNStatus = RequestService(
BoardNumber,
IOCTL_PCIDP00_GET_PCI_CONFIG_REGS,
NULL,
&Output,
0,
sizeof(Output)
);
if(RTNStatus == ERROR_SUCCESS){
for(i=0; i<16; i++)
PCIConfiguration[i] = Output.PCIConfigRegs[i];
}
}
else
RTNStatus = ERROR_INVALID_HANDLE;
return RTNStatus;
}
// ----------------------------------------------------------------------------
// SetPCIConfigurationSpace -
// ----------------------------------------------------------------------------
unsigned long Krnl_SetPCIConfigurationSpace(
in unsigned long PCIDPHandle,
in unsigned long* PCIConfiguration
){
// Declare variables.
unsigned long RTNStatus;
PCIDP00_SET_PCI_CONFIG_REGS_SEND Input;
unsigned long BoardNumber;
unsigned long i;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
for(i=0; i<16; i++)
Input.PCIConfigRegs[i] = PCIConfiguration[i];
// Request the kernel service Get PCI Config Regs.
BoardNumber = PCIDPHandle & 0x7;
RTNStatus = RequestService(
BoardNumber,
IOCTL_PCIDP00_SET_PCI_CONFIG_REGS,
&Input,
NULL,
sizeof(Input),
0
);
}
else
RTNStatus = ERROR_INVALID_HANDLE;
return RTNStatus;
}
// ----------------------------------------------------------------------------
// RegisterInterrupt -
// ----------------------------------------------------------------------------
unsigned long Krnl_RegisterInterrupt(
in unsigned long PCIDPHandle,
in unsigned long InterruptType,
out void** InterruptID,
out void** InterruptEvent
){
// Declare variables.
BOOL Status;
unsigned long RTNStatus;
unsigned long BoardNumber;
unsigned long HThread;
unsigned long BytesReturned;
char* Device;
unsigned long DeviceLength = 200;
pTHREAD_PARAMS ThreadParams = new THREAD_PARAMS;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) != 0xF0CEB000){
RTNStatus = ERROR_INVALID_HANDLE;
goto ExitRoutine;
}
// Create the nameless events for the interrupt setup. One event
// will used each time the interrupt occurs. The other will be
// used to cancel the interrupt.
ThreadParams->SyncEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(ThreadParams->SyncEvent == NULL){
RTNStatus = GetLastError();
goto ExitA;
}
ThreadParams->EndEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(ThreadParams->EndEvent == NULL){
RTNStatus = GetLastError();
goto ExitB;
}
ThreadParams->IntEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(ThreadParams->IntEvent == NULL){
RTNStatus = GetLastError();
goto ExitC;
}
// Open the connection between the application and the driver.
// This connection supports asynchonous I/O so we can return
// immedidately.
// Set up the device name based on board number.
BoardNumber = PCIDPHandle & 0x7;
Device = new char[DeviceLength];
RTNStatus = EnumerateBoards(BoardNumber, Device, DeviceLength);
if(RTNStatus == DeviceLength){
delete Device;
DeviceLength *= 2;
Device = new char[DeviceLength];
RTNStatus = EnumerateBoards(BoardNumber, Device, DeviceLength);
}
// Create a "file" object with which to communicate I/O requests.
ThreadParams->HDriver = CreateFile(
Device,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
delete Device;
if(ThreadParams->HDriver == INVALID_HANDLE_VALUE){
RTNStatus = GetLastError();
goto ExitD;
}
// Set up the information structure for the DeviceIoControl call.
ThreadParams->Input.InterruptType = InterruptType | 0xF0C00000;
ThreadParams->AsyncOvl.hEvent = ThreadParams->SyncEvent;
// Now "call" the driver to register the interrupt using the system
// DeviceIoControl service.
Status = DeviceIoControl(
ThreadParams->HDriver,
(DWORD) IOCTL_PCIDP00_REGISTER_INTERRUPT,
&ThreadParams->Input,
sizeof(PCIDP00_REGISTER_INTERRUPT_SEND),
NULL,
0,
&BytesReturned,
&ThreadParams->AsyncOvl
);
RTNStatus = GetLastError();
if(RTNStatus != ERROR_IO_PENDING)
goto ExitE;
// Now create the thread which will handle the interrupt
// I/O between the application and the driver.
HThread = _beginthread(
InterruptThread,
0x1000,
(LPVOID)ThreadParams
);
if(HThread == (ULONG)-1){
RTNStatus = errno;
goto ExitF;
}
// The service is a success. Interrupt handling is in place.
Sleep(500);
RTNStatus = ERROR_SUCCESS;
*InterruptID = ThreadParams->EndEvent;
*InterruptEvent = ThreadParams->IntEvent;
goto ExitRoutine;
ExitF:
DeviceIoControl(
ThreadParams->HDriver,
(DWORD) IOCTL_PCIDP00_UNREGISTER_INTERRUPT,
&ThreadParams->Input,
sizeof(PCIDP00_REGISTER_INTERRUPT_SEND),
NULL,
0,
&BytesReturned,
NULL
);
ExitE:
CloseHandle(ThreadParams->HDriver);
ExitD:
CloseHandle(ThreadParams->IntEvent);
ExitC:
CloseHandle(ThreadParams->EndEvent);
ExitB:
CloseHandle(ThreadParams->SyncEvent);
ExitA:
delete ThreadParams;
ExitRoutine:
return RTNStatus;
}
// ----------------------------------------------------------------------------
// UnregisterInterrupt -
// ----------------------------------------------------------------------------
unsigned long Krnl_UnRegisterInterrupt(
in unsigned long PCIDPHandle,
in void* InterruptID
){
SetEvent(InterruptID);
Sleep(500);
return ERROR_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -