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

📄 pci_sample.c

📁 PCI驱动编程实例
💻 C
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//    (C) Copyright 1995 - 1999 OSR Open Systems Resources, Inc.
//    All Rights Reserved
//
//    This sofware is supplied for instructional purposes only.
//
//    OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
//    for this software.  THIS SOFTWARE IS PROVIDED  "AS IS" WITHOUT WARRANTY
//    OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
//    THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
//    PURPOSE.  THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
//    WITH YOU.  OSR's entire liability and your exclusive remedy shall not
//    exceed the price paid for this material.  In no event shall OSR or its
//    suppliers be liable for any damages whatsoever (including, without
//    limitation, damages for loss of business profit, business interruption,
//    loss of business information, or any other pecuniary loss) arising out
//    of the use or inability to use this software, even if OSR has been
//    advised of the possibility of such damages.  Because some states/
//    jurisdictions do not allow the exclusion or limitation of liability for
//    consequential or incidental damages, the above limitation may not apply
//    to you.
//
//    OSR Open Systems Resources, Inc.
//    105 Route 101A Suite 19
//    Amherst, NH 03031  (603) 595-6500 FAX: (603) 595-6503
//    email bugs to: bugs@osr.com
//
//
//    MODULE:
//
//        PCI_SAMPLE.C
//
//    ABSTRACT:
//
//      This file contains the initial entry point for the OSR Sample
//      WDM PCI Busmaster DMA device driver for the AMCC 5933 chip.
//
//    AUTHOR(S):
//
//        OSR Open Systems Resources, Inc.
// 
//    REVISION:   
//
//
///////////////////////////////////////////////////////////////////////////////

#include "osr-pci.h"        // include <WDM.H> for us

//
// Forward Declarations
//
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObj, PUNICODE_STRING RegistryPath);
VOID OsrUnload(PDRIVER_OBJECT DriverObject);
static VOID OsrReturnPool(PPCI_COMMON_CONFIG  configInfo, PDEVICE_DESCRIPTION
            deviceDescription,  PCM_RESOURCE_LIST resources);

#if DBG
VOID OsrPrintResourceList(PCM_RESOURCE_LIST);
VOID OsrPrintConfig(PPCI_COMMON_CONFIG  configInfo);
#endif

//
// Globals used by WDM Sample.
//
PUNICODE_STRING OsrWDMSample_RegistryPath = NULL;


//
// The following pragma allows the DriverEntry code to be discarded once
// initialization is completed
//
//#pragma alloc_text(INIT,DriverEntry)

///////////////////////////////////////////////////////////////////////////////
//
//  DriverEntry
//
//      This routine is called by NT when the driver is first loaded.  It is the
//    responsibility of this routine to find it's device and create whatever
//    device objects it needs.
//
//  INPUTS:
//
//      DriverObj - Address of the DRIVER_OBJECT created by NT for this driver.
//
//      RegistryPath - UNICODE_STRING which represents this drivers KEY in the
//                   Registry.  
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      STATUS_SUCCESS. Otherwise an error indicating why the driver could not
//                    Load.
//
//  IRQL:
//
//    This routine is called at IRQL_PASSIVE_LEVEL.
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObj, PUNICODE_STRING RegistryPath)
{
    
    DbgPrint("\nOSR WDM PCI Sample Driver v1.4 -- Compiled %s %s\n",__DATE__, __TIME__);
    DbgPrint("(c) 1998-1999 OSR Open Systems Resources, Inc.\n\n");

    //
    // Establish dispatch entry points for the functions we support
    //
    DriverObj->MajorFunction[IRP_MJ_CREATE]         =  OsrCreateClose;
    DriverObj->MajorFunction[IRP_MJ_CLOSE]          =  OsrCreateClose;

    DriverObj->MajorFunction[IRP_MJ_READ]           =  OsrRead;
    DriverObj->MajorFunction[IRP_MJ_WRITE]          =  OsrWrite;
    DriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] =  OsrDeviceControl;

    //
    // PnP and Power entry points
    //
    DriverObj->MajorFunction[IRP_MJ_PNP]            =  OsrPnp;
//    DriverObj->MajorFunction[IRP_MJ_POWER]          =  OsrPower;

    //
    // WMI entry point
    //
    DriverObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =  OsrSystemControl;

    //
    // AddDevice Function
    //
    DriverObj->DriverExtension->AddDevice = OsrAddDevice;

    //
    // Unload function
    //
    DriverObj->DriverUnload = OsrUnload;

    //
    // Save the registry path for later use.
    //
    OsrWDMSample_RegistryPath = RegistryPath;

#if DBG
    DbgPrint("DriverEntry: done\n");
#endif
    
    return(STATUS_SUCCESS);
    
}

///////////////////////////////////////////////////////////////////////////////
//
//  OsrUnload
//
//      This routine is our dynamic unload entry point.  We are called here when
//    the OS wants to unload our driver.  It is our responsibility to release any
//    resources we allocated.
//
//  INPUTS:
//
//      DriverObj - Address of our DRIVER_OBJECT.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//    This routine is called at IRQL_PASSIVE_LEVEL.
//
//  NOTES:
//
//    No doubt we pool leak at this entry point by not properly returning everything.
//
///////////////////////////////////////////////////////////////////////////////
VOID OsrUnload(PDRIVER_OBJECT DriverObject)
{
    POSR_DEVICE_EXT devExt;
    PDEVICE_OBJECT devObj;
    IO_RESOURCE_REQUIREMENTS_LIST reqList;
    NTSTATUS code;
    UNICODE_STRING linkName;
    CM_RESOURCE_LIST returnResources;
    BOOLEAN conflictDetected;
            
#if DBG
    DbgPrint("SAMPLE-PCI: UNLOAD called.\n");
#endif

    //
    // For THIS driver, there will only ever be a single device object.
    // Because of this, we just get it from the DriverObj.  If this were
    // a multiple device driver, we would do this in a while loop...
    //
    devObj = DriverObject->DeviceObject;

    if (!devObj) {

        return;
    }

    devExt= (POSR_DEVICE_EXT)devObj->DeviceExtension;

    RtlInitUnicodeString(&linkName, L"\\DosDevices\\OSRPCI");

    IoDeleteSymbolicLink(&linkName);

    //
    // Reset the adapter card
    //
    OsrResetAdapter(devObj, FALSE);

    if (devExt->InterruptObject) {
        //
        // Disconnect the interrupt.
        //
        IoDisconnectInterrupt(devExt->InterruptObject);
    }

    //
    // Unmap any ports that were mapped
    //
    if (devExt->MappedPorts) {

        MmUnmapIoSpace(devExt->AmccBaseRegisterAddress, 0x40);

        devExt->MappedPorts = FALSE;
        devExt->AmccBaseRegisterAddress = 0;
        
    }

    //
    // Delete the device object
    //
    IoDeleteDevice(devObj);
}

#if DBG
///////////////////////////////////////////////////////////////////////////////
//
//  OsrPrintConfig
//
//    This routine is called to print out the PCI configuration information for
//    our device. This output is pretty "chatty" but it can be extremely
//    useful during initial debugging. And, hey, it's only output when
//    we get a START_DEVICE.
//
//  INPUTS:
//
//      configInfo - Address of the PCI_COMMON_CONFIG information for our device.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//    This routine is called at IRQL_PASSIVE_LEVEL.
//
//  NOTES:
//
//    We only use this for debugging purposes.
//
///////////////////////////////////////////////////////////////////////////////
VOID OsrPrintConfig(PPCI_COMMON_CONFIG  configInfo)
{
    ULONG index;

    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("\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");

}    


//
// Some static string tables we use as part of debugging
//
static PSTR CmResourceTypeStrings[] = 
{
    "CmResourceTypeNull",
    "CmResourceTypePort",
    "CmResourceTypeInterrupt",
    "CmResourceTypeMemory",
    "CmResourceTypeDma",
    "CmResourceTypeDeviceSpecific",
    "CmResourceTypeBusNumber"
};

static PSTR CmResourceTypeStringsAt128[] =
{
    "CmResourceTypeConfigData",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -