📄 pcidp_if.cpp
字号:
//*****************************************************************************
// Copyright (C) 2000, Cypress Semiconductor.
//
// ALL RIGHTS RESERVED. USE, DISCLOSURE, OR REPRODUCTION WITHOUT WRITTEN
// PERMISSION OF CYPRESS SEMICONDUCTOR IS PROHIBITED.
//
//
// This is PCIDP_IF.cpp. It provides direct access to the PCIDP
// kernel driver under Windows 95/98.
//
// NOTE: for optimal readability set your TABs option to 2 spaces.
//*****************************************************************************
#include "windows.h"
#include "process.h"
#include "PCIDP_IF_KRNL.h"
#include "PCIDP.h"
// Declare the OpenVxDHandle entry point into kernel32.dll.
typedef DWORD (CALLBACK* OPENVXDHANDLE)(HANDLE);
// Declare global variables local to the application.
unsigned long Handles[] = {0,0,0,0,0,0,0,0};
char Device[] = "\\\\.\\PCIDP"; //Win32 device name for PCIDP driver
unsigned long RequestService(
unsigned long ControlFunction,
void* InputBuffer,
void* OutputBuffer,
unsigned long InputSize,
unsigned long OutputSize
){
// Declare variables.
unsigned long RTNStatus;
BOOL Status;
HANDLE HDriver;
DWORD BytesReturned;
// Create a "file" object with which to communicate I/O requests.
HDriver = CreateFile(
Device,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
// Now "call" the driver via the system DeviceIoControl service.
if(HDriver != INVALID_HANDLE_VALUE){
Status = DeviceIoControl(
HDriver,
ControlFunction,
InputBuffer,
InputSize,
OutputBuffer,
OutputSize,
&BytesReturned,
0
);
if(Status == TRUE)
RTNStatus = ERROR_SUCCESS;
else
RTNStatus = GetLastError();
CloseHandle(HDriver);
}
else
RTNStatus = GetLastError();
return RTNStatus;
}
// ----------------------------------------------------------------------------
// OpenPCIDP -
// ----------------------------------------------------------------------------
unsigned long Krnl_OpenPCIDP(
in unsigned long BoardNumber,
out unsigned long* PCIDPHandle
){
// Define variables.
PCIDP00_HELLO_SEND Input;
unsigned long RTNStatus;
// Check for a valid board number.
if(BoardNumber < 8){
// The driver for this board/application pair has not been opened.
if(Handles[BoardNumber] == 0){
// Request the kernel service Hello, just to see if the device
// exists.
Input.Devnode = BoardNumber;
RTNStatus = RequestService(
IOCTL_PCIDP00_HELLO, //control function
&Input, //input buffer
NULL, //output buffer
sizeof(Input), //input buffer size
0 //output buffer size
);
if(RTNStatus == ERROR_SUCCESS){
Handles[BoardNumber] = BoardNumber | 0xF0CEB000;
*PCIDPHandle = Handles[BoardNumber];
}
}
else{
*PCIDPHandle = Handles[BoardNumber];
RTNStatus = ERROR_SUCCESS;
}
}
else
RTNStatus = ERROR_BAD_DEVICE;
return RTNStatus;
}
// ----------------------------------------------------------------------------
// GetDriverVersion -
// ----------------------------------------------------------------------------
unsigned long Krnl_GetDriverVersion(
in unsigned long PCIDPHandle,
out unsigned long* Version
){
// Declare variables.
unsigned long RTNStatus;
PCIDP00_GET_VERSION_SEND Input;
PCIDP00_GET_VERSION_RECV Output;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Get Driver Version.
Input.Devnode = PCIDPHandle & 0x7;
RTNStatus = RequestService(
IOCTL_PCIDP00_GET_VERSION,
&Input,
&Output,
sizeof(Input),
sizeof(Output)
);
if(RTNStatus == ERROR_SUCCESS){
*Version = Output.Version;
}
}
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;
// Initialize variables.
Input.RegNumber = RegisterNumber;
Input.Length = *Length;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Map Base Regs.
Input.Devnode = PCIDPHandle & 0x7;
RTNStatus = RequestService(
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;
// Initialize variables.
Input.Address = (unsigned long)Address;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Unmap.
Input.Devnode = PCIDPHandle & 0x7;
RTNStatus = RequestService(
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_SEND Input;
PCIDP00_MAP_DMA_MEM_RECV Output;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Map DMA Mem.
Input.Devnode = PCIDPHandle & 0x7;
RTNStatus = RequestService(
IOCTL_PCIDP00_MAP_DMA_MEM,
&Input,
&Output,
sizeof(Input),
sizeof(Output)
);
if(RTNStatus == ERROR_SUCCESS){
*LinearAddress = (unsigned long*)Output.LinearAddress;
*PhysicalAddress = Output.PhysicalAddress;
}
}
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;
// Initialize variables.
Input.LinearAddress = (unsigned long)Address;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Unmap.
Input.Devnode = PCIDPHandle & 0x7;
RTNStatus = RequestService(
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_SEND Input;
PCIDP00_GET_PCI_CONFIG_REGS_RECV Output;
unsigned long i;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){
// Request the kernel service Get PCI Config Regs.
Input.Devnode = PCIDPHandle & 0x7;
RTNStatus = RequestService(
IOCTL_PCIDP00_GET_PCI_CONFIG_REGS,
&Input,
&Output,
sizeof(Input),
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 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.
Input.Devnode = PCIDPHandle & 0x7;
RTNStatus = RequestService(
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.
unsigned long RTNStatus;
HMODULE LibHandle;
OPENVXDHANDLE OpenVxDHandle;
PCIDP00_REGISTER_INTERRUPT_SEND Input;
// Validate the handle.
if((PCIDPHandle & 0xFFFFF000) != 0xF0CEB000){
RTNStatus = ERROR_INVALID_HANDLE;
goto ExitRoutine;
}
// Create a nameless event the application will wait to be signaled when
// a registered interrupt occurs.
*InterruptEvent = (HANDLE)CreateEvent(NULL, TRUE, FALSE, NULL);
if(*InterruptEvent == NULL){
RTNStatus = GetLastError();
goto ExitRoutine;
}
// Create the associated ring 0 event the driver can signal when the
// registered interrupt occurs. Signaling this event will in turn
// signal the ring 3 event.
LibHandle = LoadLibrary("kernel32.dll");
if(LibHandle == NULL){
RTNStatus = GetLastError();
goto ExitA;
}
OpenVxDHandle = (OPENVXDHANDLE)GetProcAddress(LibHandle, "OpenVxDHandle");
if(OpenVxDHandle == NULL){
RTNStatus = GetLastError();
goto ExitB;
}
Input.Event0 = OpenVxDHandle(*InterruptEvent);
if(Input.Event0 == NULL){
RTNStatus = ERROR_INVALID_EVENTNAME;
goto ExitB;
}
*InterruptID = (PVOID)Input.Event0;
// Request the kernel service Register Interrupt.
Input.InterruptType = InterruptType | 0xF0C00000;
Input.Devnode = PCIDPHandle & 0x7;
RTNStatus = RequestService(
IOCTL_PCIDP00_REGISTER_INTERRUPT,
&Input,
NULL,
sizeof(Input),
0
);
FreeLibrary(LibHandle);
goto ExitRoutine;
ExitB:
FreeLibrary(LibHandle);
ExitA:
CloseHandle(*InterruptEvent);
*InterruptEvent = 0;
*InterruptID = 0;
ExitRoutine:
return RTNStatus;
}
// ----------------------------------------------------------------------------
// UnregisterInterrupt -
// ----------------------------------------------------------------------------
unsigned long Krnl_UnRegisterInterrupt(
in unsigned long PCIDPHandle,
in void* InterruptID
){
unsigned long RTNStatus;
PCIDP00_UNREGISTER_INTERRUPT_SEND Input;
// Request the kernel service Unregister Interrupt.
Input.Devnode = PCIDPHandle & 0x7;
Input.Event0 = (DWORD)InterruptID;
RTNStatus = RequestService(
IOCTL_PCIDP00_UNREGISTER_INTERRUPT,
&Input,
NULL,
sizeof(Input),
0
);
return RTNStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -