#ifndef __PCIVME_DRV_H__
 
#define __PCIVME_DRV_H__
 
//-------------------------------------------------------------------------
 
// WINNT driver for PCIVME interface from ARW Elektronik, Germany ---------
 
// the main header file of the driver
 
//
 
// (c) 1999-2004 ARW Elektronik
 
//
 
// this source code is published under GPL (Open Source). You can use, redistrubute and 
 
// modify it unless this header   is not modified or deleted. No warranty is given that 
 
// this software will work like expected.
 
// This product is not authorized for use as critical component in life support systems
 
// wihout the express written approval of ARW Elektronik Germany.
 
//
 
// Please announce changes and hints to ARW Elektronik
 
//
 
// $Log: pcivme_drv.h,v $
 
// Revision 1.3  2004/07/24 07:07:26  klaus
 
// Update copyright to 2004
 
//
 
// Revision 1.2  2003/11/15 19:12:50  klaus
 
// Update copyright to 2003
 
//
 
// Revision 1.1.1.1  2003/11/14 23:16:33  klaus
 
// First put into repository
 
//
 
// Revision 1.5  2002/10/27 18:41:21  klaus
 
// changed driver version to 2.0 (not 'inf' version)
 
//
 
// Revision 1.4  2002/10/27 17:02:30  klaus
 
// File addressing bug > 2 Gbtye circumvent
 
//
 
// Revision 1.3  2002/10/27 16:17:48  klaus
 
// Typing bug fixed caused at log addition
 
//
 
// Revision 1.2  2002/10/27 16:11:02  klaus
 
// Added CVS log into header
 
//
 
// what                                            who          when
 
// started                                         AR           15.06.1999
 
// version 1.0 released                                                    AR                   20.10.1ß99
 
// version 1.2 released                            AR           25.11.2001
 
// changed to VisualStudio 6.0                     AR           30.09.2001
 
// compiled with DDK 1/2001                        AR           20.11.2001
 
// removed alloc_text cause of WIN2000 problems    AR           25.11.2001
 
// version 1.3 released                            AR           25.11.2001
 
// changed resource allocation caused by WIN2000   AR           08.06.2002
 
//
 
 
 
//-------------------------------------------------------------------------
 
#define DRIVER_VERSION ((2 << 16) | 0)  // the only place for version info
 
#define DRIVER_VARIANT 0                // mark customisation here
 
//-------------------------------------------------------------------------
 
 
 
//-------------------------------------------------------------------------
 
// precautions for debug compile
 
#define PCIVME_DEBUG
 
 
 
#ifndef PCIVME_DEBUG
 
#ifdef  KdPrint()
 
#undef  KdPrint()
 
#define KdPrint(x)
 
#endif
 
#endif
 
//-------------------------------------------------------------------------
 
 
 
//-------------------------------------------------------------------------
 
// INCLUDES
 
//
 
#define PCI_MAX_BUSES     4   // buses to search for pciada
 
 
 
#define PCIVME_MAX_PCIADA 4   // maximum of PCIADA to search for  
 
#define PCIVME_MAX_VMEMM  16  // maximum number of VMEMMs
 
 
 
//-------------------------------------------------------------------------
 
// DEFINES
 
//
 
#define PCIVME_VENDOR_ID  0x10B5  
 
#define PCIVME_DEVICE_ID  0x9050
 
#define PCIVME_SUBSYS_ID  0x1167
 
#define PCIVME_SUBVEN_ID  0x9050
 
 
 
#define LCR_SPACE         256  // space in bytes of LCR
 
#define IFR_SPACE         8192 // space in bytes of IFR
 
 
 
//-------------------------------------------------------------------------
 
// TYPEDEFS
 
//
 
typedef struct _FILE_OBJ
 
{
 
        USHORT uwAssociatedVMEMM;                  // which VMEMM it belongs
 
        UCHAR  bAddressModifier;                   // this is the current modifier
 
        UCHAR  bAccessType;                            // this is the current access type (1,2,4)
 
        UCHAR  bIncrement;                                   // set 0 if no increment of address
 
        ULONG  dwAddressMask;          // mask for aligned transfers
 
        ULONG  dwAccessBase;
 
        void   (*fRead)(void *to, ULONG length, void *from);  // resulting read
 
        void   (*fWrite)(void *to, ULONG length, void *from); // resulting write
 
 
 
        BOOLEAN bQueueIrq;                                 // queue interrupt vectors belonging to this
 
        PVOID   pIrqListHandle;                    // pointer to the irq FIFO
 
 
 
        BOOLEAN bBusError;                 // marks current access as responsible
 
} FILE_OBJ, *PFILE_OBJ;
 
 
 
typedef struct
 
{
 
        int               Bus;             // bus number of pciada
 
        PCI_SLOT_NUMBER   Slot;            // slot + function number encoded
 
        PCI_COMMON_CONFIG PCIDevice;       // content of pcr
 
 
 
    PHYSICAL_ADDRESS  pvPhysLcr;       // local config register
 
        PHYSICAL_ADDRESS  pvPhysIfr;       // interface registers
 
        PVOID             pvVirtLcr;       // virtual LCR space
 
        PVOID             pvVirtIfr;       // virtual IFR space
 
 
 
        KIRQL                     Irql;                    // virtual Irq level
 
        ULONG                     Vector;              // mapped system vector
 
        KAFFINITY                 Affinity;        // which processor uses this irq
 
 
 
        PKINTERRUPT               InterruptObject; // points to the associated irq obj
 
 
 
        PUSHORT           pwCntrl;         // LCR Cntrl Offset @ LCR + 0x50
 
        PUSHORT           pwIntCSR;        // LCR IntCSR Offset @ LCR + 0x4C
 
 
 
        ULONG                     dwLinkCount;     // how often this interface is requested
 
    BOOLEAN                       bConnected;      // VMEMM is connected and powered
 
        BOOLEAN                   bWordMode;       // WordMode Jumper set
 
        BOOLEAN                   bSysControl;     // SystemController enabled
 
        USHORT                    wModuleNumber;   // Number (Jumper) of VMEMM
 
        USHORT                    wFPGAVersion;    // Revision of (VMEMM) FPGA
 
        USHORT                    wModuleType;     // Type of (VMEMM) module
 
 
 
        PUSHORT                   pwCSR;           // pointer to csr register
 
        PUSHORT                   pwIRQStat;       // pointer to irq status
 
        PUCHAR                    pbVector;        // pointer to vector read register
 
        PULONG                    pdwVMEAdr;       // pointer to VME adress register
 
        PUCHAR                    pbModifier;      // pointer to address modifier register
 
        PVOID                     pvVME;           // pointer into VME window
 
 
 
        ULONG                     dwVMEPage;       // current page to VME
 
        UCHAR                     bModifier;       // current Modifier
 
 
 
        KSPIN_LOCK                AccessLock;      // a lock for Access to VMEMM registers
 
        KSPIN_LOCK                IrqListLock;     // a lock to guard access to List
 
        LIST_ENTRY                IrqListList;     // start of list of IRQ FIFOs
 
 
 
        KDPC                      kDPCobj;                 // custom DPC object for irq tunneling
 
 
 
        PBOOLEAN                  pbBusError;      // points to the responsible party
 
 
 
        int               nInterruptHandlers; // counts the controlling interrupt handlers
 
} PCIADA; 
 
 
 
typedef struct _DEVICE_EXT 
 
{
 
        PDEVICE_OBJECT DeviceObject;       // points to myself
 
        PDEVICE_OBJECT LowerDeviceObject;
 
    PDRIVER_OBJECT driverObj;          // points to my driver                               */
 
        PIRP actualIrp;                                    // points to .. 
 
 
 
        KSPIN_LOCK      IRPLock;                           // a lock to guard access to List
 
        LIST_ENTRY  IRPList;                       // List of queued IRPs
 
 
 
        int    nPCIADAs;                   // how many PCIADAs are found
 
 
 
        PCIADA pciada[PCIVME_MAX_PCIADA];  // for each PCIADA a descriptor 
 
 
 
        PCIADA *vmemm[PCIVME_MAX_VMEMM];   // points to PCIADA to which it belongs
 
 
 
        int    nInitState;                 // tracks the state of initialisation
 
        PBUS_INTERFACE_STANDARD busInterface;
 
} DEVICE_EXT, *PDEVICE_EXT;
 
 
 
typedef struct
 
{
 
        LIST_ENTRY entry;                                  // doubly linked list
 
        PFILE_OBJ  pFile_obj;                      // the owner
 
        PVOID      pIrqListHandle;                 // the irq FIFO of this owner
 
} FIFO_LIST;
 
 
 
// Prototypes to support following pragmas
 
NTSTATUS DriverEntry(PDRIVER_OBJECT driverObj, PUNICODE_STRING regPath);
 
NTSTATUS HandleStartDevice(PDEVICE_OBJECT fdo, PIRP Irp);
 
NTSTATUS HandleStopDevice(PDEVICE_OBJECT fdo, PIRP Irp);
 
NTSTATUS DefaultPnpHandler(PDEVICE_OBJECT fdo, PIRP Irp);
 
NTSTATUS PCIVMEStartDevice(PDEVICE_OBJECT device_object, PIRP irp);
 
NTSTATUS PCIVMEAddDevice( PDRIVER_OBJECT driverObj,  PDEVICE_OBJECT  pdo);
 
NTSTATUS PCIVMEDispatchPnp(PDEVICE_OBJECT deviceObj, PIRP irp);
 
NTSTATUS PCIVMEOpen(PDEVICE_OBJECT deviceObj, PIRP irp);
 
NTSTATUS PCIVMEClose(PDEVICE_OBJECT deviceObj, PIRP irp);
 
VOID     PCIVMEUnload(PDRIVER_OBJECT driverObj);
 
NTSTATUS QueryBusInterface(IN PDEVICE_OBJECT DeviceObject, OUT PBUS_INTERFACE_STANDARD BusInterface);
 
NTSTATUS SearchDevices(PDEVICE_OBJECT device_Obj);
 
NTSTATUS PLX9050BugFix(PDEVICE_OBJECT device_Obj);
 
NTSTATUS PCIVMEExtractResources(PCIADA *pciada, PIRP irp);
 
NTSTATUS PCIVMEReserveResources(PDEVICE_OBJECT device_Obj, PIRP irp);
 
NTSTATUS PCIVMEFreeResources(PDEVICE_OBJECT device_Obj);
 
NTSTATUS PCIVMETranslateBusAddresses(PDEVICE_OBJECT device_Obj, PIRP irp);
 
NTSTATUS PCIVMETranslateInterrupt(PDEVICE_OBJECT device_Obj);
 
NTSTATUS PCIVMEMapIOspace(PDEVICE_OBJECT device_object);
 
VOID     PCIVMESoftInit(PDEVICE_OBJECT device_Obj);
 
PBOOLEAN ExchangePointer(PBOOLEAN *current, PBOOLEAN next);
 
 
 
/* release all this procedures after init of the driver */
 
#if 0 // WIN2000 change versus WINNT?
 
#ifdef ALLOC_PRAGMA
 
#pragma alloc_text (init, DriverEntry)
 
#pragma alloc_text (page, PCIVMEStartDevice)
 
#pragma alloc_text (page, PCIVMEAddDevice)
 
#pragma alloc_text (page, QueryBusInterface)
 
#pragma alloc_text (page, SearchDevices)
 
#pragma alloc_text (page, PLX9050BugFix)
 
#pragma alloc_text (page, PCIVMEExtractResources)
 
#pragma alloc_text (page, PCIVMEReserveResources)
 
#pragma alloc_text (page, PCIVMETranslateBusAddresses)
 
#pragma alloc_text (page, PCIVMETranslateInterrupt)
 
#pragma alloc_text (page, PCIVMEMapIOspace)
 
#pragma alloc_text (page, PCIVMESoftInit)
 
#endif
 
 
 
/* put all this procedures in the paged memory-pool, all called at passiv Level */
 
#ifdef ALLOC_PRAGMA
 
#pragma alloc_text (page, HandleStartDevice)
 
#pragma alloc_text (page, HandleStopDevice)
 
#pragma alloc_text (page, PCIVMEOpen)
 
#pragma alloc_text (page, PCIVMEClose)
 
#pragma alloc_text (page, PCIVMEUnload)
 
#pragma alloc_text (page, PCIVMEFreeResources)
 
#pragma alloc_text (page, PCIVMEDispatchPnp)
 
#pragma alloc_text (page, DefaultPnpHandler)
 
#endif
 
#endif // WIN2000 change versus WINNT?
 
 
 
#endif // __PCIVME_DRV_H__