📄 pci9052.c
字号:
/****************************************************************
;----------------------------------------------------------------
;* 时间:2002-6-18 17:12
;* 模块名称:pci9052.c
;*
;* Programmer:桂凯
;* 环境:Windows 2000
//
//
// email:wwwguikai@21cn.com
// All right reserved
;*
;*
;*
;----------------------------------------------------------------
*****************************************************************/
#include <ntddk.h>
#include <ndis.h>
#include <pci9052hw.h>
#include <pci9052sw.h>
/*
ULONG BusNumber;
PCI_SLOT_NUMBER SlotNumber; 1 ULONG
ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; 6 ULONG
*/
#define NUM_DESCRIPTOR 5
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, AddDevice)
#pragma alloc_text (PAGE, Pnp9052)
#pragma alloc_text (PAGE, SystemControl)
#pragma alloc_text (PAGE, UnloadDriver)
#pragma alloc_text (PAGE, MainDispatch)
#pragma alloc_text (PAGE, Read9052)
#pragma alloc_text (PAGE, Write9052)
//#pragma alloc_text (PAGE, StartDevice)
#pragma alloc_text (PAGE, Create9052)
#pragma alloc_text (PAGE, Close9052)
#pragma alloc_text (PAGE, Detect9052)
#pragma alloc_text (PAGE, DpcForIsr)
#pragma alloc_text (PAGE, AssignResource)
//-----------------------------------------------------------------------------
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
WCHAR NameString[] = L"\\Device\\" DEVICE_NAME_STRING;
WCHAR LinkString[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
UNICODE_STRING nameString, linkString;
PDEVICE_OBJECT deviceObject;
PDEVICE_EXTENSION deviceExt;
NTSTATUS status;
ULONG busNumber = 0;
ULONG deviceNumber = 0;
PCI_SLOT_NUMBER slotNumber;
ULONG length = 0;
PCI_COMMON_CONFIG configInfo ;
ULONG found9052 = 0;
PVOID MapedIoBaseAddr = NULL;
PHYSICAL_ADDRESS PhysicalAddress;
ULONG NumberOfBytes = 16;
MEMORY_CACHING_TYPE CacheEnable;
NTSTATUS code;
PDEVICE_DESCRIPTION deviceDescription ;
PCM_RESOURCE_LIST resources ;
ULONG interruptLevel;
ULONG interruptVector;
ULONG mappedSystemVector;
PHYSICAL_ADDRESS portStart;
ULONG portLength;
KIRQL irql;
KAFFINITY affinity;
PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
PHYSICAL_ADDRESS address;
ULONG addressSpace;
ULONG index;
ULONG index2;
PCM_RESOURCE_LIST resReqList ;
RtlInitUnicodeString(&nameString,NameString);
status=IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
&nameString,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
&deviceObject);
// 指定好 Flag = DO_BUFFERED_IO
deviceObject->Flags = DO_BUFFERED_IO ; // 指定 i/o 模式为buffer方式
deviceExt = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
RtlZeroMemory(deviceExt, sizeof(DEVICE_EXTENSION));
deviceExt->DeviceObject = deviceObject;
if(!NT_SUCCESS(status))
return(status);
RtlInitUnicodeString(&linkString,LinkString);
status=IoCreateSymbolicLink(&linkString,&nameString);
if(!NT_SUCCESS(status))
{
IoDeleteDevice (DriverObject->DeviceObject);
return(status);
}
// DriverObject->DriverUnload = UnloadDriver;
DriverObject->MajorFunction[IRP_MJ_CREATE] = MainDispatch;
// DriverObject->MajorFunction[IRP_MJ_CLOSE] = Close9052;
// DriverObject->MajorFunction[IRP_MJ_PNP] = Pnp9052;
DriverObject->MajorFunction[IRP_MJ_READ] = MainDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = Write9052;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MainDispatch;
//
// WMI entry point
//
// DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = SystemControl;
//
// AddDevice Function
//
// DriverObject->DriverExtension->AddDevice = AddDevice;
for( busNumber=0; busNumber<MAX_BUS_NUMBER; busNumber++)
{
for( deviceNumber=0; deviceNumber<PCI_MAX_DEVICES; deviceNumber++)
{
slotNumber.u.bits.Reserved = 0;
slotNumber.u.bits.DeviceNumber = deviceNumber;
slotNumber.u.bits.FunctionNumber = 0;
slotNumber.u.AsULONG = deviceNumber;
length = HalGetBusData(PCIConfiguration,
busNumber,
slotNumber.u.AsULONG,
&configInfo,
sizeof(PCI_COMMON_CONFIG) );
// 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;
if ( (configInfo.VendorID == PLX9052ID_VENID)&&(configInfo.DeviceID == PLX9052ID_DEVID) )
{
found9052 = 1;
break;
}
}
if( found9052 == 1)
break;
}
if ( found9052 == 1 )
{
PhysicalAddress.u.LowPart= (ULONG)configInfo.u.type0.BaseAddresses[2];
PhysicalAddress.u.HighPart= (LONG)0x0;
deviceExt->Local_space0.u.LowPart = (ULONG)PhysicalAddress.u.LowPart;
deviceExt->Local_space0.u.HighPart =(LONG) PhysicalAddress.u.HighPart;
NumberOfBytes = 16;
CacheEnable = MmNonCached;
MapedIoBaseAddr = MmMapIoSpace( PhysicalAddress,NumberOfBytes,CacheEnable);
if( MapedIoBaseAddr !=NULL)
deviceExt->MapedIoLocalSpace0BaseAddr = MapedIoBaseAddr;
deviceExt->BusNumber = busNumber;
deviceExt->SlotNumber = slotNumber;
deviceExt->InterruptLine = configInfo.u.type0.InterruptLine;
deviceExt->BaseAddresses[0] = configInfo.u.type0.BaseAddresses[0];
deviceExt->BaseAddresses[1] = configInfo.u.type0.BaseAddresses[1];
deviceExt->BaseAddresses[2] = configInfo.u.type0.BaseAddresses[2];
}
if( found9052 == 0)
{
DbgPrint(" 9052 don't exist ! \n");
return (STATUS_UNSUCCESSFUL);
}
if( PhysicalAddress.u.LowPart== (ULONG)0xe8000000 )
DbgPrint(("hello"));
{
WCHAR ClassName[] = DEVICE_NAME_STRING;
UNICODE_STRING DriverClassName;
PDEVICE_EXTENSION devExt = (PDEVICE_EXTENSION) deviceObject;
ULONG sizeToAllocate;
// PCM_RESOURCE_LIST resReqList ;
PCM_FULL_RESOURCE_DESCRIPTOR resFullList;
PCM_PARTIAL_RESOURCE_LIST resPartialList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resParDesc[NUM_DESCRIPTOR];
RtlInitUnicodeString(&DriverClassName,ClassName);
sizeToAllocate = sizeof(CM_RESOURCE_LIST) +
sizeof(CM_FULL_RESOURCE_DESCRIPTOR ) +
sizeof(CM_PARTIAL_RESOURCE_LIST ) +
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)*NUM_DESCRIPTOR ;
resReqList = ExAllocatePool( PagedPool , sizeToAllocate);
RtlZeroMemory( resReqList, sizeToAllocate);
resReqList->Count = 1;
resFullList = &resReqList->List[0];
resFullList->InterfaceType = PCIBus ; // 5
resFullList->BusNumber = devExt->BusNumber;
resPartialList = &resFullList->PartialResourceList;
resPartialList->Version = 1;
resPartialList->Revision = 1;
resParDesc[0] = &resPartialList->PartialDescriptors[0];
resParDesc[0]->Type = CmResourceTypePort;
resParDesc[0]->ShareDisposition = CmResourceShareDriverExclusive;
resParDesc[0]->Flags = CM_RESOURCE_PORT_MEMORY;
resParDesc[0]->u.Port.Start.u.LowPart = deviceExt->BaseAddresses[0];
resParDesc[0]->u.Port.Start.u.HighPart = 0;
resParDesc[0]->u.Port.Length = 128;
code = HalAssignSlotResources (
RegistryPath,
&DriverClassName,
DriverObject,
deviceObject,
PCIBus,
deviceExt->BusNumber,
deviceExt->SlotNumber.u.AsULONG,
&resReqList
);
// ExFreePool( resReqList);
if( code != STATUS_SUCCESS)
{
DbgPrint(" HalAssignSlotResources failed !");
return code;
}
}
if( code !=STATUS_SUCCESS)
DbgPrint(" AssignResource failed! \n");
portStart.LowPart = 0;
portLength = 0;
interruptLevel = 0;
interruptVector = 0;
for (index = 0; index < resReqList->Count; index++)
{
for (index2 = 0; index2 < resReqList->List[index].PartialResourceList.Count;index2++)
{
prd =&resReqList->List[index].PartialResourceList.PartialDescriptors[index2];
switch (prd->Type)
{
case CmResourceTypePort:
if((prd->Flags & CM_RESOURCE_PORT_IO)!=0)
DbgPrint(" CM_RESOURCE_PORT_IO\n");
if(( prd->Flags & CM_RESOURCE_PORT_MEMORY)!=0)
DbgPrint(" CM_RESOURCE_PORT_MEMORY \n");
if(prd->u.Port.Length == 128);
DbgPrint(" Port length = 128 \n");
portStart.u.HighPart = 0;
portStart.u.LowPart = prd->u.Port.Start.LowPart;
portLength = prd->u.Port.Length;
deviceExt->portStart.u.HighPart = 0;
deviceExt->portStart.u.LowPart = prd->u.Port.Start.LowPart;
deviceExt->portLength = prd->u.Port.Length;
break;
case CmResourceTypeInterrupt:
if((prd->Flags & CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)!=0)
DbgPrint("CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE\n");
if( (prd->Flags & CM_RESOURCE_INTERRUPT_LATCHED) != 0)
DbgPrint("CM_RESOURCE_INTERRUPT_LATCHED \n");
interruptLevel = prd->u.Interrupt.Level;
interruptVector = prd->u.Interrupt.Vector;
deviceExt->InterfaceType = PCIBus;
deviceExt->InterruptLevel = interruptLevel;
deviceExt->InterruptVector = interruptVector;
deviceExt->InterruptMode = LevelSensitive;
break;
case CmResourceTypeMemory:
if((prd->Flags & CM_RESOURCE_MEMORY_READ_WRITE)!=0)
DbgPrint("...CM_RESOURCE_MEMORY_READ_WRITE!\n");
break;
case CmResourceTypeDma:
DbgPrint("...Unexpected DMA resource!\n");
break;
case CmResourceTypeDeviceSpecific:
DbgPrint("...Unexpected device specific resource!\n");
break;
default:
DbgPrint("Unexpected and unknown resource type\n");
break;
}
}
}
if( portLength == 128)
DbgPrint(" Maped IO space length is 128 bytes !\n");
if( portStart.LowPart == deviceExt->BaseAddresses[0] )
DbgPrint(" port's phys start at 0x%x \n",deviceExt->BaseAddresses[0]);
deviceExt->portStart.u.HighPart = 0;
deviceExt->portStart.u.LowPart = deviceExt->BaseAddresses[0];
deviceExt->PlxRegisterBaseAddr = MmMapIoSpace(deviceExt->portStart,
deviceExt->portLength,
CacheEnable);
DbgPrint("deviceExt->portStart:0x %x\n",deviceExt->portStart);
DbgPrint(" deviceExt->PlxRegisterBaseAddr:0x%x\n", deviceExt->PlxRegisterBaseAddr);
if( deviceExt->PlxRegisterBaseAddr == NULL)
DbgPrint(" MmMapIoSpace failed !\n");
IoInitializeDpcRequest(deviceObject, DpcForIsr);
DbgPrint("interruptVector:0x%x\n",interruptVector);
//
mappedSystemVector = HalGetInterruptVector( PCIBus,
deviceExt->BusNumber,
interruptLevel,
interruptVector,
&irql,
&affinity);
deviceExt->mappedSystemVector = mappedSystemVector;
DbgPrint("irql:0x%x\n",irql);
DbgPrint("deviceExt->mappedSystemVector:0X %x \n",mappedSystemVector);
code = IoConnectInterrupt(&deviceExt->InterruptObject,
HandleInterrupt,
deviceExt,
NULL,
mappedSystemVector,
irql,
irql,
LevelSensitive,
TRUE,
affinity,
FALSE);
if( code != STATUS_SUCCESS)
DbgPrint(" IoConnectInterrupt failed ! \n");
ExFreePool( resReqList);
return(STATUS_SUCCESS);
}
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -