#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
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
} DEVICE_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 PCIVMEOpen(PDEVICE_OBJECT deviceObj, PIRP irp);
NTSTATUS PCIVMEClose(PDEVICE_OBJECT deviceObj, PIRP irp);
VOID PCIVMEUnload(PDRIVER_OBJECT driverObj);
NTSTATUS SearchDevices(PDEVICE_OBJECT device_Obj);
NTSTATUS PLX9050BugFix(PDEVICE_OBJECT device_Obj);
NTSTATUS PCIVMEExtractResources(PCIADA *pciada, PCM_RESOURCE_LIST pList);
NTSTATUS PCIVMEReserveResources(PDEVICE_OBJECT device_Obj);
NTSTATUS PCIVMEFreeResources(PDEVICE_OBJECT device_Obj);
NTSTATUS PCIVMETranslateBusAddresses(PDEVICE_OBJECT device_Obj);
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 (init, SearchDevices)
#pragma alloc_text (init, PLX9050BugFix)
#pragma alloc_text (init, PCIVMEExtractResources)
#pragma alloc_text (init, PCIVMEReserveResources)
#pragma alloc_text (init, PCIVMETranslateBusAddresses)
#pragma alloc_text (init, PCIVMETranslateInterrupt)
#pragma alloc_text (init, PCIVMEMapIOspace)
#pragma alloc_text (init, PCIVMESoftInit)
#endif
/* put all this procedures in the paged memory-pool, all called at passiv Level */
#ifdef ALLOC_PRAGMA
#pragma alloc_text (page, PCIVMEOpen)
#pragma alloc_text (page, PCIVMEClose)
#pragma alloc_text (page, PCIVMEUnload)
#pragma alloc_text (page, PCIVMEFreeResources)
#endif
#endif // WIN2000 change versus WINNT?
#endif // __PCIVME_DRV_H__