📄 genport.c
字号:
/*++
Copyright (c) 1990-2000 Microsoft Corporation, All Rights Reserved
Module Name:
genport.c
Abstract: Generic Port I/O driver for Windows 2000
Author: Author: Robert R. Howell January 8, 1993
Environment:
Kernel mode
Revision History:
Robert B. Nelson (Microsoft) January 12, 1993
Cleaned up comments
Enabled and tested resource reporting
Added code to retrieve I/O address and port count from the Registry.
Robert B. Nelson (Microsoft) March 1, 1993
Added support for byte, word, and long I/O.
Added support for MIPS.
Fixed resource reporting.
Robert B. Nelson (Microsoft) May 1, 1993
Fixed port number validation.
Robert B. Nelson (Microsoft) Oct 25, 1993
Fixed MIPS support.
Eliyas Yakub
Fixed AddressSpace Bug Nov 30, 1997
Eliyas Yakub
Converted to Windows 2000 Dec 29, 1998
Fixed bugs Feb 17, 2000
--*/
#include "Def.h"
#include "Serial.h"
#include "genport.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, GpdAddDevice)
#pragma alloc_text (PAGE, GpdDispatchPnp)
#pragma alloc_text (PAGE, GpdDispatchSystemControl)
#pragma alloc_text (PAGE, GpdUnload)
#pragma alloc_text (PAGE, GpdDispatch)
#pragma alloc_text (PAGE, GpdIoctlReadPort)
#pragma alloc_text (PAGE, GpdIoctlWritePort)
#pragma alloc_text (PAGE, SerialReadData)
#pragma alloc_text (PAGE, SerialWriteData)
#pragma alloc_text (PAGE, SerialSetBaud)
#pragma alloc_text (PAGE, SerialReset)
#pragma alloc_text (PAGE, GetDataNum)
#pragma alloc_text (PAGE, GpdStartDevice)
#pragma alloc_text (PAGE, WriteSwitch)
#endif
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
Installable driver initialization entry point.
This entry point is called directly by the I/O system.
Arguments:
DriverObject - pointer to the driver object
RegistryPath - pointer to a unicode string representing the path,
to driver-specific key in the registry.
Return Value:
STATUS_SUCCESS
--*/
{
// AddDevice 中的定义
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject = NULL;
PLOCAL_DEVICE_INFO deviceInfo;
UNICODE_STRING ntDeviceName;
UNICODE_STRING win32DeviceName;
// end AddDevice
//PCI
PPCI_COMMON_CONFIG configInfo = NULL;
ULONG busNumber;
ULONG deviceNumber;
ULONG AddressSpace;
PCI_SLOT_NUMBER slotNumber;
ULONG length;
BOOLEAN moreBuses;
BOOLEAN adapterFound;
ULONG index;
ULONG index2;
ULONG addressSpace;
PHYSICAL_ADDRESS address;
PCM_RESOURCE_LIST resources = NULL;
// PDEVICE_OBJECT devObj;
UNICODE_STRING devName, linkName;
PDEVICE_DESCRIPTION deviceDescription = NULL;
ULONG interruptLevel;
ULONG interruptVector;
ULONG mappedSystemVector;
PHYSICAL_ADDRESS portStart;
ULONG portLength;
KIRQL irql;
KAFFINITY affinity;
//end PCI
//UNREFERENCED_PARAMETER (RegistryPath);//原来的代码
//关于一些初始化参数的定义
USHORT i,j;
USHORT COMBASE_PORT[COM_NUM] = {COMBASE_PORT0,COMBASE_PORT1,COMBASE_PORT2,COMBASE_PORT3};
USHORT BUFBASE[2][COM_NUM] ={ {BUFBASE_P0R,BUFBASE_P1R,BUFBASE_P2R,BUFBASE_P3R},
{BUFBASE_P0T,BUFBASE_P1T,BUFBASE_P2T,BUFBASE_P3T}};
USHORT NUMBASE[2][COM_NUM] = { {NUMBASE_0R,NUMBASE_1R,NUMBASE_2R,NUMBASE_3R},
{NUMBASE_0T,NUMBASE_1T,NUMBASE_2T,NUMBASE_3T}};
//定义结束
DebugPrint (("Entered Driver Entry\n"));
DebugPrint (("RegistryPath.Buffer = %s\n",RegistryPath->Buffer));
//
// Create dispatch points for the IRPs.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = GpdDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = GpdDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GpdDispatch;
DriverObject->DriverUnload = GpdUnload;
DriverObject->MajorFunction[IRP_MJ_PNP] = GpdDispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = GpdDispatchPower;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = GpdDispatchSystemControl;
// DriverObject->DriverExtension->AddDevice = GpdAddDevice;
////////////////////////////// 20060217 /////////////////////////////////////
//---------------------查找PCI---------------------
//
// Allocate space for a configuration information structure
//
configInfo = ExAllocatePoolWithTag(PagedPool,
sizeof(PCI_COMMON_CONFIG),
'pRSO');
if (!configInfo) {
//
// Clean up the mess
//
if(configInfo)
ExFreePool(configInfo);
if(resources)
ExFreePool(resources);
//
// Indicate load failure to the I/O manager
//
return(STATUS_INSUFFICIENT_RESOURCES);
}
//
// Search for our device on all the PCI busses in the system
//
// We do this by ennumerating the configuration information for each
// slot on each PCI bus in the system, until we find a device with
// our Vendor ID and Device ID.
//
// Since this sample driver supports only a single card, we stop looking as
// soon as we find one device. Drivers that support multiple cards would
// ennumerate all the busses and slots, finding as many devices as exist.
//
// Since our device is not a PCI "multifunction" device, we don't search
// each function in each slot.
//
//
adapterFound = FALSE;
moreBuses = TRUE;
for (busNumber = 0; !adapterFound && moreBuses; busNumber++) {
//
// Ennumerate all the devices on this bus
//
for (deviceNumber = 0;
!adapterFound && deviceNumber < PCI_MAX_DEVICES;
deviceNumber++) {
//
// For PCI buses, the logical slot number is a PCI_SLOT_NUMBER
// structure, comprising a combination of the device number and the
// function number on the card. The Reserved section MUST be set
// to zero.
//
// Note that since we're not a multifunction device, we only look
// at FunctionNumber 0 in each slot.
//
slotNumber.u.bits.Reserved = 0;
slotNumber.u.bits.DeviceNumber = deviceNumber;
slotNumber.u.bits.FunctionNumber = 0;
//
// Get the configuration space for the adapter in this slot
//
length = HalGetBusData(PCIConfiguration,
busNumber,
slotNumber.u.AsULONG,
configInfo,
sizeof(PCI_COMMON_CONFIG) );
//
// A return value of zero indicates no more PCI buses on the system
//
if (length == 0) {
#if DBG
DbgPrint("Reached end of PCI bus list\n");
#endif
moreBuses = FALSE;
break;
}
//
// If there's nothing in this slot, PCI_INVALID_VENDORID is returned
// as the vendor ID. If this is the case, just continue running
// the bus.
//
if (configInfo->VendorID == PCI_INVALID_VENDORID) {
continue;
}
//
// Dump out information about the device found.
//
#if DBG
DbgPrint("Found a PCI device at Bus %d. Device %d.\n",
busNumber,
deviceNumber);
DbgPrint("Vendor id = 0x%0x, Device id = 0x%0x\n",
(int)configInfo->VendorID,
(int)configInfo->DeviceID);
#endif // DBG
//
// Is this the PCI device for which we've been searching? It is
// if both the vendor and device ID match
//
if ( (configInfo->VendorID == PCI_954_VID) &&
(configInfo->DeviceID == PCI_954_DID) ) {
//
// FOUND IT! No need to keep searching. We support only
// one device.
//
adapterFound = TRUE;
#if DBG
DbgPrint("*** Found OUR PCI ADAPTER ***");
//
// Just for the sake of interest, let's dump some of the
// configuration information for our device.
//
DbgPrint("Displaying PCI Configuration Information\n");
DbgPrint("\tRevisionID is 0x%x\n", (int)configInfo->RevisionID);
DbgPrint("\tProgIf is 0x%x\n", (int) configInfo->ProgIf);
DbgPrint("\tSubClass is 0x%x\n", (int) configInfo->SubClass);
DbgPrint("\tBaseClass is 0x%x\n", (int) configInfo->BaseClass);
DbgPrint("\tCacheLineSize is 0x%x\n", (int) configInfo->CacheLineSize);
DbgPrint("\tLatencyTimer is 0x%x\n", (int) configInfo->LatencyTimer);
DbgPrint("\tHeaderType is 0x%x\n", (int) configInfo->HeaderType);
DbgPrint("\tBIST is 0x%x\n", (int) configInfo->HeaderType);
for (index = 0; index < PCI_TYPE0_ADDRESSES; index++) {
DbgPrint("\tBaseAddresses[%d] is 0x%x\n",index, configInfo->u.type0.BaseAddresses[index]);
// DbgPrint("\ttype1.MemoryBase is 0x%x\n",configInfo->u.type1.MemoryBase);
/* if(index == 2)
{
PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
PHYSICAL_ADDRESS portStart,address;
unsigned long addressSpace = 0;
prd = &resources->List[index].PartialResourceList.PartialDescriptors[index];
// deviceInfo->PortBase = (PVOID)((configInfo->u.type0.BaseAddresses[index])&0xFFFFFFFC);
// deviceInfo->PortCount = 0x3FFF;
portStart.HighPart = 0xd800;
portStart.LowPart = 0x0000;
portLength = 0x3fff;
{
// DbgPrint("\taddresses is 0x%x 0x%x\n",address.HighPart,address.LowPart);
deviceInfo->PortBase = MmMapIoSpace (portStart,
0x3fff,
MmNonCached);
deviceInfo->PortCount = 0x3FFF;
deviceInfo->PortWasMapped = TRUE;
}
}*/
}
DbgPrint("\tROMBaseAddress is 0x%x\n", configInfo->u.type0.ROMBaseAddress);
DbgPrint("\tInterruptLine is 0x%x\n", configInfo->u.type0.InterruptLine);
DbgPrint("\tInterruptPin is 0x%x\n", configInfo->u.type0.InterruptPin);
DbgPrint("****************************\n");
// DebugPrint(("****PCI Resource Translated Port: (%x) Length: (%d)\n",
// deviceInfo->PortBase,
// deviceInfo->PortCount));
#endif
}
}
}
//
// If we didn't find our adapter, we bail out here, thereby aborting
// the driver load process. The I/O Manager will delete our driver
// object.
//
if (!adapterFound) {
#if DBG
DbgPrint("OSR PCI Sample device was not found!? -- EXITING.\n");
#endif
//
// Clean up the mess
//
if(configInfo)
ExFreePool(configInfo);
if(resources)
ExFreePool(resources);
//
// Indicate load failure to the I/O manager; driver image is deleted...
//
return(STATUS_NO_SUCH_DEVICE);
}
//----------------------结束 查找PCI------------------------------------------------
//----------------------创建设备 AddDevice中的代码--------------------------------------
DebugPrint (("-- Entered GpdAddDevice\n"));
// PAGED_CODE();
RtlInitUnicodeString(&ntDeviceName, GPD_DEVICE_NAME); //GPD_DEVICE_NAME 就是宏定义 L"\\Device\\Gpd0"
DebugPrint((">>> ntDeviceName.len=%d Buffer=%s\n"
,ntDeviceName.Length
,ntDeviceName.Buffer));
//
// Create a device object.
//
status = IoCreateDevice (DriverObject,
sizeof (LOCAL_DEVICE_INFO),
&ntDeviceName,
GPD_TYPE,
0,
FALSE,
&deviceObject);//分配内存并初始化一个设备deviceObject
if (!NT_SUCCESS (status)) {
//
// Either not enough memory to create a deviceobject or another
// deviceobject with the same name exits. This could happen
// if you install another instance of this device.
//
return status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -