⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci9052.c

📁 用C语言写得PCI8052的WDM结构驱动程序
💻 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 + -