shanshan-dian
驱动牛犊
驱动牛犊
  • 注册日期2008-09-04
  • 最后登录2009-04-21
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望17点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1920回复:0

请教一PCI驱动中断的问题。。。。。

楼主#
更多 发布于:2008-09-07 17:37


程序如下
// rs4Device.cpp
//
// Generated by DriverWizard 3.2.0 (Build 2485)
// Requires DDK and DriverWorks
// File created on 1/2/2003
//
// This source file contains the implementation of a subclass of KDevice.
// WDM drivers implement a subclass of KPnpDevice and override member
// functions to handle requests (IRPs) from the system.
//

#include <vdw.h>
#include "rs4Driver.h"
#include "rs4Device.h"
#include "..\\intrface.h"

#pragma hdrstop("rs4.pch")

// Global driver trace object
// TODO:    Use KDebugOnlyTrace if you want trace messages
//            to appear only in checked builds.  Use KTrace if
//            you want trace messages to always appear.  Call
//            method SetOutputLevel to set the output threshold.
extern KDebugOnlyTrace T;

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::rs4Device
//        This is the constructor for the class representing the Functional
//        Device Object, or FDO.  It is derived from KPnpDevice, which builds
//        in automatic dispatching of subfunctions of IRP_MJ_POWER and IRP_MJ_PNP
//        to virtual member functions.
//        The object being constructed contains a data member (m_Lower) of type
//        KPnpLowerDevice. By initializing it, the driver binds the FDO to the
//        PDO and creates an interface to the upper edge of the system class driver.
//
//    Arguments:
//        IN    Pdo
//                Physical Device Object.  This is a pointer to a system
//                device object that represents the physical device.
//
//        IN    Unit
//                Unit number to append to the device's base device name
//                to distinguish multiple units of this device type.
//
//    Return Value:
//        none
//
rs4Device::rs4Device(PDEVICE_OBJECT Pdo, ULONG Unit) :
    m_PciConfig(NULL),
    KPnpDevice(Pdo, NULL)
{
    if (!NT_SUCCESS(m_ConstructorStatus))
    {
        T.Trace(TraceError, __FUNCTION__": Failed to create device rs4Device"
            " unit number %d status %x\n", Unit, m_ConstructorStatus);
        ASSERT(FALSE);
        return;
    }

    // Initialize the lower device
    m_Lower.Initialize(this, Pdo);

    // Inform the base class of the lower edge device object
    SetLowerDevice(&m_Lower);

    // Initialize the PnP Policy settings to the "standard" policy
    SetPnpPolicy();

    // TODO: Customize the PnP Policy for this device by setting
    //         flags in m_Policies.

    // Initialize the Power Policy settings to the "standard" policy
    SetPowerPolicy();

    // TODO: Customize the Power Policy for this device by setting
    //         flags in m_PowerPolicies.

}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::~rs4Device
//        This is the destructor for the class.
//
//    Arguments:
//        none
//
//    Return Value:
//        none
//
rs4Device::~rs4Device()
{
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::DefaultPnp
//        Default handler for IRP_MJ_PNP.
//        This routine just passes the IRP through to the lower device. IRPs
//        that correspond to any virtual members of KpnpDevice that handle
//        minor functions of IRP_MJ_PNP and that are not overridden get
//        passed to this routine.
//
//    Arguments:
//        IN    I
//            the plug and play IRP
//
//    Return Value:
//        NTSTATUS
//            Result returned from lower device
//
NTSTATUS rs4Device::DefaultPnp(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);
    T << I;

    I.ForceReuseOfCurrentStackLocationInCalldown();
    NTSTATUS status = m_Lower.PnpCall(this, I);

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::DefaultPower
//        Default handler for IRP_MJ_POWER.
//        This routine just passes the IRP through to the lower device. IRPs
//        that correspond to any virtual members of KpnpDevice that handle
//        minor functions of IRP_MJ_POWER and that are not overridden get
//        passed to this routine.
//
//    Arguments:
//        IN    I
//            the power IRP
//
//    Return Value:
//        NTSTATUS
//            Result returned from lower device
//
NTSTATUS rs4Device::DefaultPower(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);
    T << I;

    I.IndicatePowerIrpProcessed();
    I.CopyParametersDown();
    NTSTATUS status = m_Lower.PnpPowerCall(this, I);

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::SystemControl
//        Default handler for IRP_MJ_SYSTEM_CONTROL.
//        This routine just passes the IRP through to the next device since
//        this driver is not a WMI provider.
//
//    Arguments:
//        IN    I
//            the system control (WMI) IRP
//
//    Return Value:
//        NTSTATUS
//            Result returned from lower device
//
NTSTATUS rs4Device::SystemControl(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);
    T << I;

    NTSTATUS status = STATUS_SUCCESS;

    I.ForceReuseOfCurrentStackLocationInCalldown();
    status = m_Lower.PnpCall(this, I);

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::OnStartDevice
//        Handler for IRP_MJ_PNP subfcn IRP_MN_START_DEVICE.
//        Initialize the hardware device. Typically, the driver initializes
//        physical resources here.  Call I.AllocatedResources() for a list
//        of the raw resources that the system has assigned to the device,
//        or I.TranslatedResources() for the translated resource list.
//
//    Arguments:
//        IN    I
//            the start device IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::OnStartDevice(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    I.Information() = 0;

    // Get the list of raw resources from the IRP
    PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources();
    // Get the list of translated resources from the IRP
    PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources();

    // Initialize an instance of KPciConfiguration so we can access
    // PCI configuration space.
    m_PciConfig.Initialize(m_Lower.TopOfStack());
    
    do
    {

        // For each memory mapped region, initialize the memory mapped range
        // using the resources provided by the system. Once initialized, each memory
        // range's base virtual address in system space can be obtained by calling
        // member Base(). Each memory range's physical address in CPU space can
        // obtained by calling CpuPhysicalAddress(). To access the memory mapped
        // range use member functions such as inb/outb, or the array element operator.
        // TODO: Verify that the variable is assigned the correct PCI BAR.  

        status = m_MemoryRange0.Initialize(
            pResListTranslated,
            pResListRaw,
            0
            );

        if (!NT_SUCCESS(status))
        {
            T.Trace(TraceWarning,__FUNCTION__" Failed to initialize m_MemoryRange0 STATUS %x\n", status);
            break;
        }

        status = m_MemoryRange1.Initialize(
            pResListTranslated,
            pResListRaw,
            1
            );

        if (!NT_SUCCESS(status))
        {
            T.Trace(TraceWarning,__FUNCTION__" Failed to initialize m_MemoryRange1 STATUS %x\n", status);
            break;
        }

        // For each I/O port mapped region, initialize the I/O port range using the
        // resources provided by the system. Once initialized, use member functions
        // such as inb/outb, or the array element operator to access the ports range.
        // TODO: Verify that the variable is assigned the correct PCI BAR.  

        status = m_IoPortRange0.Initialize(
            pResListTranslated,
            pResListRaw,
            0
            );
        
        if (!NT_SUCCESS(status))
        {
            T.Trace(TraceWarning,__FUNCTION__" Failed to initialize m_IoPortRange0 STATUS %x\n", status);
            break;
        }

        // TODO: Make sure that interrupts are disabled on the hardware
        
        // Initialize the interrupt resource and connect the ISR to the interrupt resource
        status = m_rs4Interrupt.InitializeAndConnect(
            pResListTranslated,
            LinkTo(Isr),
            this
            );
            
        if (!NT_SUCCESS(status))
        {
            T.Trace(TraceWarning,__FUNCTION__" Failed to initialize m_rs4Interrupt STATUS %x\n", status);
            break;
        }
        
        // Setup the Deferred Procedure Call (DPC) to be used for interrupt processing
        m_rs4IsrDpc.Setup(LinkTo(IsrDpc), this);



    } while (FALSE);

    if (!NT_SUCCESS(status))
    {
        Invalidate();
        return status;        
    }
    else
    {
        // TODO: Add PCI device-specific code to start the hardware.
    }

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::OnStopDevice
//        Handler for IRP_MJ_PNP subfcn IRP_MN_STOP_DEVICE.
//        The system calls this when the device is stopped.  Release any
//        hardware resources in this routine.
//
//    Arguments:
//        IN    I
//            the stop device IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::OnStopDevice(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    // TODO: Add device-specific code to stop your hardware device.
    // The base class will handle completion of the IRP

    // Release the system resources
    m_rs4Interrupt.Disconnect();    //使 KInterrupt类实例断开并无效
    Invalidate();

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, STATUS_SUCCESS);
    
    // Can't fail this IRP
    return STATUS_SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::OnRemoveDevice
//        Handler for IRP_MJ_PNP subfcn IRP_MN_REMOVE_DEVICE.
//        The system calls this when the device is removed.
//        Our PnP policy will take care of
//            (1) giving the IRP to the lower device
//            (2) detaching the PDO
//            (3) deleting the device object
//
//    Arguments:
//        IN    I
//            the remove device IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::OnRemoveDevice(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    // TODO: Add device-specific code to remove your hardware device.
    // The base class will handle completion of the IRP

    // Release the system resources
    m_rs4Interrupt.Disconnect();    //使 KInterrupt类实例断开并无效
    Invalidate();

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, STATUS_SUCCESS);

    // Can't fail this IRP
    return STATUS_SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::OnDevicePowerUp
//        Handler for IRP_MJ_POWER subfcn IRP_MN_SET_POWER
//        for a request to go to power on state from low power state
//        This function was called by the framework from the completion
//        routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
//        The bus driver has completed the IRP and this driver can now
//        access the hardware device.  
//        This routine runs at DISPATCH_LEVEL.
//
//    Arguments:
//        IN    I
//            the power IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::OnDevicePowerUp(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    // TODO: Add device-specific code to:
    //         Restore any context to the hardware device that
    //         was saved during the handling of a power down request.
    //         See the OnDeviceSleep function.
    //         Do NOT complete this IRP.
    //         The base class will handle completion of the IRP

    // TODO: Enable interrupts on the hardware

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::OnDeviceSleep
//        Handler for IRP_MJ_POWER subfcn IRP_MN_SET_POWER
//        for a request to go to a low power state from a high power state
//        This function was called by the framework from the IRP_MJ_POWER
//        dispatch handler in KPnpDevice prior to forwarding to the PDO.
//        The hardware has yet to be powered down and this driver can now
//        access the hardware device.  
//        This routine runs at PASSIVE_LEVEL.
//
//    Arguments:
//        IN    I
//            the power IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::OnDeviceSleep(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    // TODO: Add device-specific code to:
    //         Save any context to the hardware device that will be required
    //         during a power up request. See the OnDevicePowerUp function.
    //         Do NOT complete this IRP.  The base class handles forwarding
    //         this IRP to the PDO.

    // TODO: Disable interrupts on the hardware

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::Create
//        Dispatch routine for IRP_MJ_CREATE requests.  
//
//    Arguments:
//        IN I
//            the create IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::Create(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    // TODO: For any IRP, to display the contents of the IRP
    //         in a formatted way, use the KTrace << operator:
    //             T << I;

    NTSTATUS status = STATUS_SUCCESS;

    // TODO: At this point, perform custom processing for IRP_MJ_CREATE
    // Generally a create IRP is targeted at our FDO, so its not needed
    // to pass it down to the PDO.  

    I.Information() = 0;
    I.PnpComplete(this, status);

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::Close
//        Dispatch routine for IRP_MJ_CLOSE requests.  
//
//    Arguments:
//        IN I
//            the close IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::Close(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    // TODO: At this point, perform custom processing for IRP_MJ_CLOSE
    // Generally a close IRP is targeted at our FDO, so we don't need
    // to pass it down to the PDO.  

    I.Information() = 0;
    I.PnpComplete(this, status);

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::Read
//        Dispatch routine for IRP_MJ_READ requests.  
//
//    Arguments:
//        IN I
//            the read IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::Read(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    // TODO: Validate the parameters of the IRP.  Replace "FALSE"
    //         in the following line with error checking code that
    //         evaulates to TRUE if the request is not valid.
    if (FALSE)
    {
        status = STATUS_INVALID_PARAMETER;
        I.Information() = 0;
        I.PnpComplete(status);

        T.Trace(TraceWarning, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

        return status;
    }

    

    // Always ok to read 0 elements
    if (I.ReadSize() == 0)
    {
        I.Information() = 0;
        I.PnpComplete(this, status);

        T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

        return status;
    }


    KMemory Mem(I.Mdl());    // Declare a memory object

    // Get a pointer to the caller's buffer.  Note that this
    // routine is safe on all platforms.
    PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
    ULONG readSize = I.ReadSize();
    ULONG bytesRead = 0;

    ULONG Data = 0;

    int  n ;
    for (n =0; n< i ; n ++)
    {
        *pBuffer = *(PNUM-i+n);
        pBuffer++;
    }
    
    

    I.Information() = (ULONG)1;
    I.Status() = status;

    I.PnpComplete(this, status);

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::Write
//        Dispatch routine for IRP_MJ_WRITE requests.  
//
//    Arguments:
//        IN I
//            the write IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::Write(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    // TODO: Validate the parameters of the IRP.  Replace "FALSE"
    //         in the following line with error checking code that
    //         evaulates to TRUE if the request is not valid.
    if (FALSE)
    {
        status = STATUS_INVALID_PARAMETER;
        I.Information() = 0;
        I.PnpComplete(status);

        T.Trace(TraceWarning, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

        return status;
    }

    // Always ok to write 0 elements
    if (I.WriteSize() == 0)
    {
        I.Information() = 0;
        I.PnpComplete(this, status);

        T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

        return status;
    }


    //m_MemoryRange1.outd(0xC8,0x02);    

    KMemory Mem(I.Mdl());    // Declare a memory object

    // Get a pointer to the caller's buffer.  Note that this
    // routine is safe on all platforms.
    PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
    ULONG writeSize = I.WriteSize();
    ULONG bytesSent = 0;

    ULONG channelNum  = 0;
    ULONG Data = 0;

    channelNum = (ULONG)(*pBuffer);
    pBuffer ++;
    Data = (ULONG)(*pBuffer);

    switch(channelNum)
    {
    case (ULONG)0x10:
            if (((m_MemoryRange1.inb((ULONG)0x5c))&0x01) == (UCHAR)0x01)
            {
                I.Information() = (ULONG)0;
                 I.Status() = status;
            }
            else
            {
                m_MemoryRange1.outd(channelNum,&Data,(ULONG)1);
                I.Information() = (ULONG)2;
                I.Status() = status;
            }

        break;

    case (ULONG)0x30:
        if (((m_MemoryRange1.inb((ULONG)0x5c))&0x02) == (UCHAR)0x02)
        {
            I.Information() = (ULONG)0;
            I.Status() = status;
        }
        else
        {
            m_MemoryRange1.outd(channelNum,&Data,(ULONG)1);
            I.Information() = (ULONG)2;
            I.Status() = status;
        }
        break;

    case (ULONG)0x50:
        if (((m_MemoryRange1.inb((ULONG)0x5c))&0x04) == (UCHAR)0x04)
        {
            I.Information() = (ULONG)0;
            I.Status() = status;
        }
        else
        {
            m_MemoryRange1.outd(channelNum,&Data,(ULONG)1);
            I.Information() = (ULONG)2;
            I.Status() = status;
        }
        break;

    case (ULONG)0x70:
        if (((m_MemoryRange1.inb((ULONG)0x5c))&0x08) == (UCHAR)0x08)
        {
            I.Information() = (ULONG)0;
            I.Status() = status;
        }
        else
        {
            m_MemoryRange1.outd(channelNum,&Data,(ULONG)1);
            I.Information() = (ULONG)2;
            I.Status() = status;
        }
        break;
        
    case (ULONG)0x90:
        if (((m_MemoryRange1.inb((ULONG)0x5c))&0x10) ==(UCHAR)0x10)
        {
            I.Information() = (ULONG)0;
            I.Status() = status;
        }
        else
        {
            m_MemoryRange1.outd(channelNum,&Data,(ULONG)1);
            I.Information() = (ULONG)2;
            I.Status() = status;
        }
        break;

    case (ULONG)0xB0:
        if (((m_MemoryRange1.inb((ULONG)0x5c))&0x20) == (UCHAR)0x20)
        {
            I.Information() = (ULONG)0;
            I.Status() = status;
        }
        else
        {
            m_MemoryRange1.outd(channelNum,&Data,(ULONG)1);
            I.Information() = (ULONG)2;
            I.Status() = status;
        }
        break;

    case (ULONG)0xD0:
        if (((m_MemoryRange1.inb((ULONG)0x5c))&(0x40)) == (UCHAR)0x40)
        {
            I.Information() = (ULONG)0;
            I.Status() = status;

        }
        else
        {
            m_MemoryRange1.outd(channelNum,&Data,(ULONG)1);
            I.Information() = (ULONG)2;
            I.Status() = status;
        }
        break;

    case (ULONG)0xF0:
        if (((m_MemoryRange1.inb((ULONG)0x5C)) & (0x80))==0x80)
        {
            I.Information() = (ULONG)0;
            I.Status() = status;
        }
        else
        {
            m_MemoryRange1.outd(channelNum,&Data,(ULONG)1);
            I.Information() = (ULONG)2;
            I.Status() = status;
        }
        break;

    default:
        {
            m_MemoryRange1.outd(channelNum,&Data,(ULONG)1);
            I.Information() = (ULONG)2;
            I.Status() = status;
        }
        break;
    }

 
    I.PnpComplete(this, status);

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::DeviceControl
//        Dispatch routine for IRP_MJ_DEVICE_CONTROL requests.  
//
//    Arguments:
//        IN I
//            the ioctl IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::DeviceControl(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    switch (I.IoctlCode())
    {
    case 0:
        {

        }

    default:
        status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    // If the IRP's IOCTL handler deferred processing using some driver
    // specific scheme, the status variable is set to STATUS_PENDING.
    // In this case we simply return that status, and the IRP will be
    // completed later.  Otherwise, complete the IRP using the status
    // returned by the IOCTL handler.
    if (status != STATUS_PENDING)
    {
        I.PnpComplete(this, status);
    }

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::CleanUp
//        Dispatch routine for IRP_MJ_CLEANUP requests.  
//
//    Arguments:
//        IN I
//            the cleanup IRP
//
//    Return Value:
//        NTSTATUS
//
NTSTATUS rs4Device::CleanUp(KIrp I)
{
    T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

    NTSTATUS status = STATUS_SUCCESS;

    // TODO: At this point, perform custom processing for IRP_MJ_CLEANUP

    I.PnpComplete(this, status);

    T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::Isr
//        Interrupt Service Routine (ISR).  Minimal processing may be done
//        here in the ISR, but most processing should be deferred to a DPC.
//        This routine is called at DEVICE IRQL that is higher than
//        DISPATCH_LEVEL.
//
//    Arguments:
//        none
//
//    Return Value:
//        BOOLEAN        TRUE if this is our interrupt
//
BOOLEAN rs4Device::Isr(void)
{
    // TODO: Test if the Interrupt was from our hardware device.
    // Replace "TRUE" in next line with actual test.



    //2008.08.29
    #define    mask_int_9030  0x00000004
    #define    clear_int_9030  0x00000400
    #define    default_int_9030 0x00000043
    ULONG Offset_9030 = 0x4C, temp;

#if 1

    temp=m_MemoryRange0.ind(Offset_9030);
    

    if ((temp&mask_int_9030) ==0)
    {
        // Return FALSE to indicate that this device did not cause the interrupt.
        return FALSE;
    }

    //temp=m_MemoryRange0.ind(Offset_9030)|clear_int_9030;
    //m_MemoryRange0.outd(Offset_9030,temp);
//    m_MemoryRange0.outd(Offset_9030,0x00000000);
//    m_MemoryRange0.outd(Offset_9030,default_int_9030);

    if (!m_rs4IsrDpc.Request(NULL, NULL))
    {
        // TODO: The DPC is already in the queue
        //         You may want to set flags or perform
        //         other actions in this case
    }
    // Return TRUE to indicate that our device caused the interrupt



    
#endif
return TRUE;
        

    // TODO: Service the device.
    //         Minimal processing may be done here in the ISR, but
    //         most processing should be deferred to a DPC.
    //         Generally, you should:
    //            o  stop the device from generating interrupts
    //            0  get the reason for the interrupt (DMA done, read complete,
    //                    write complete, other operation complete)
    //            o  perform any additional time-critical functions
    //            o  schedule a DPC to perform the bulk of the work.    

//    RS4_ISR_REASON reason = IsrReasonNone;

    // Request deferred procedure call (DPC)
    // TODO: The arguments to Request may be any values that you choose
    //         Perhaps the reason for the interrupt

}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::IsrDpc
//        Deferred Procedure Call (DPC).
//        This function is called for secondary processing of an interrupt.
//        Most code that runs at elevated IRQL should run here rather than
//        in the ISR, so that other interrupt handlers can continue to run.
//        This routine executes at DISPATCH_LEVEL.
//
//    Arguments:
//        IN    Arg1
//                User-defined context variable passed from Isr()
//
//        IN    Arg2
//                User-defined context variable passed from Isr()
//
//    Return Value:
//        none
//
VOID rs4Device::IsrDpc(PVOID Arg1, PVOID Arg2)
{
    
    //RS4_ISR_REASON reason = (RS4_ISR_REASON)(ULONG_PTR) Arg1;

    ULONG Data = 0;
    i=0;
    
    while((m_MemoryRange1.ind((ULONG)0x1C) &0x02)==0x02)
    {
        m_MemoryRange1.ind((ULONG)0x34,&Data ,(ULONG)1);
        *PNUM = (ULONG)0X34;
        PNUM ++;
        i++;
        *PNUM = (UCHAR)(Data & 0x000000ff);
        PNUM ++;
        i++;    
    }


    


        
    // TODO: Typically, the interrupt signals the end of a data transfer
    //         operation for a READ or WRITE or IOCTL operation. If this is
    //         the case, add code to handle the completion of the IRP
    //         associated with this operation here.

    // The following macros simply allows compilation at Warning Level 4
    // If you reference these parameters in the function simply remove the macro.
//    UNREFERENCED_PARAMETER(Arg1);
//    UNREFERENCED_PARAMETER(Arg2);
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  rs4Device::Invalidate
//        This method performs resource cleanup.
//        This function is called from OnStopDevice, OnRemoveDevice and
//        OnStartDevice (in error conditions).  It calls the Invalidate
//        member funcitons for each resource to free the underlying system
//        resource if allocated.  It is safe to call Invalidate more than
//        once for a resource, or for an uninitialized resource.
//
//    Arguments:
//        none
//
//    Return Value:
//        none
//
VOID rs4Device::Invalidate()
{
    NTSTATUS status = STATUS_SUCCESS;

    // TODO: Disable interrupts on the hardware before doing this.
    // Disconnet the Interrupt Service Routine (ISR) from the interrupt object
    m_rs4Interrupt.Invalidate();

    // For each I/O port mapped region, unmap the memory associated with it.
    m_IoPortRange0.Invalidate();

    // For each memory mapped region, unmap the memory associated with it.
    m_MemoryRange0.Invalidate();
    m_MemoryRange1.Invalidate();
}



装上后运行write 程序时就蓝屏, 有时候死机, 很是恼火, 中断估计是写的不对, 求那位高人指点一下啊,
或者可以在延迟程序DPC里面调用读的程序, 可是不晓得要怎么写, 也拜托告知一下, 万分感谢了

游客

返回顶部