/*++
*******************************************************************************
* Copyright (c) 1990-99 Digi International Inc., All Rights Reserved          *
*                                                                             *
* This software contains proprietary and confidential information of Digi     *
* International Inc.  By accepting transfer of this copy, Recipient agrees    *
* to retain this software in confidence, to prevent disclosure to others,     *
* and to make no use of this software other than that for which it was        *
* delivered.  This is an unpublished copyrighted work of Digi International   *
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly   *
* prohibited.                                                                 *
*                                                                             *
* Restricted Rights Legend                                                    *
*                                                                             *
* Use, duplication, or disclosure by the Government is subject to             *
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in         *
* Technical Data and Computer Software clause at DFARS 252.227-7031 or        *
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -          *
* Restricted Rights at 48 CFR 52.227-19, as applicable.                       *
*                                                                             *
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343          *
*                                                                             *
*******************************************************************************

Module Name:

   digidxb.h

Abstract:

   This header defines data structures and constants used throughout the dxb driver.

Author:

   Michael Zarns

--*/
#ifndef DIGIDXB_H
#define DIGIDXB_H

// System
#define UNICODE
#include <ntddk.h>


#if 0
    //#include <sys\stream.h>
#else
    // Stolen from stream.h

    #define MAXIOCBSZ   1024    /* max ioctl data block size */
    #define M_PCSIG     0204    /* generate process signal */
    #define M_FLUSH     0206    /* flush your queues */
    #define M_ERROR     0212    /* fatal error used to set u.u_error */

    struct iocblk {
        int             ioc_cmd;        /* ioctl command type */
        unsigned short  ioc_uid;        /* effective uid of user { *ioc_cr } */
        unsigned short  ioc_gid;        /* effective gid of user { in SVR4 } */
        unsigned int    ioc_id;         /* ioctl id */
        unsigned int    ioc_count;      /* count of bytes in data field */
        int             ioc_error;      /* error code */
        int             ioc_rval;       /* return value  */
    };
#endif

#include "dxbtypes.h"

// Sync/Prime Firmware
#include "fr_cont.h"
#include "errno.h"
#include "dxb.h"

// Dense Firmware
#include "triglbl.h"
#include "dxbglbl.h"
#include "fepglbl.h"
#include "mgmthlc.h"

// Digi Driver Libraries
#include "digilib.h"
#include "dsioctl.h"
#include "dsapi.h"
#include "digikme.h"

#include <sraddk.h>
#include <sraproto.h>
#include <sratype.h>
#include <sradbg.h>

// Driver Global Data
extern PDRIVER_OBJECT gpDriverObject;
extern LIST_ENTRY     gDeviceExtList;
extern UNICODE_STRING gDriverRegPath;

// Default pool tag for ExAllocatePoolWithTag memory allocations
extern ULONG DefaultPoolTag;

// DigiDump Flags
#define DIGIINIT                0x00000001
#define DIGIINITLOUD                0x00000002
#define DIGICONFIG              0x00000004
#define DIGIDEVICE              0x00000008

#define DIGIV1                      0x00000010
#define DIGIV2                      0x00000020
#define DIGIQUEUE                   0x00000040
#define DIGIEVENTQ              0x00000080

#define DIGITXCREDIT                0x00000100
#define DIGIRXCREDIT                0x00000200
#define DIGITXDATA              0x00000400
#define DIGIRXDATA              0x00000800

#define DIGIIOCTL                   0x00001000
#define DIGISTREAMLOCK          0x00002000
#define DIGIPCI                 0x00004000
#define DIGIKME                 0x00008000

#define DIGIDSOPEN              0x00010000
#define DIGIDSCLOSE             0x00020000
#define DIGICANCEL              0x00040000
#define UNUSED19                    0x00080000

#define DIGIPNP                 0x00100000
#define DIGIPNPLOUD             0x00200000
#define DIGIPNPCHILD                0x00400000
#define DIGIPOWER                   0x00800000

#define UNUSED24                    0x01000000
#define UNUSED25                    0x02000000

#define DIGIWARN                    DEBUG_WARN
#define DIGIERROR                   DEBUG_ERROR
#define DIGIBREAK                   DEBUG_BREAK


// Should be defined in f/w header file!
#define DXB_MAX_CHANNELS 256

#if NT5_BUILD
typedef enum 
{
    DXBPNP_ADDED,       // Device object exists, but card hasn't started or is stopped
    DXBPNP_STARTED, // Means card is running
    DXBPNP_REMOVED, // Used only to protect against multiple remove requests
    DXBPNP_COUNT
} DXB_PNP_STATE;
#endif

#if NT5_BUILD
typedef enum DXB_POWER_STATE
{
  PWRSTATE_ON,            // power on, device in D0 state
  PWRSTATE_OFF_PENDING,   // power off operation is pending
  PWRSTATE_OFF,           // power off, device in D3 state
  PWRSTATE_OFF_IDLE,      // power off due to idle detection
} DXB_POWER_STATE, *PDXB_POWER_STATE;
#endif

struct DXB_DEVICE_EXTENSION;

typedef enum DXB_OBJECT_TYPE
{
    DXB_TYPE_DEVICE_EXT = 0xDDBB0000,
    DXB_TYPE_CHILD_DEVICE,
    DXB_TYPE_STREAM_OBJECT,
    DXB_TYPE_DXB_MSG,
    DXB_TYPE_MAX
} DXB_OBJECT_TYPE, *PDXB_OBJECT_TYPE;


typedef enum DXB_STREAM_STATE
{
    STREAM_STATE_INACTIVE,
    STREAM_STATE_OPENING,
    STREAM_STATE_READY,
    STREAM_STATE_CLOSING,
    STREAM_STATE_CLOSED,
    STREAM_STATE_MAX
} DXB_STREAM_STATE;


// Credits are used for flow control between the dxb driver and the dxb firmware.
// Credits are implemented on a per-stream basis.  Put simply, when you have credits, 
// you can send data across the bus...when you don't have enough credits for a msg, you
// can't send it across the bus.
typedef struct DXB_CREDIT_DESCRIPTOR
{
    ULONG nCreditsMax;  // For debugging...
    ULONG nCredits;     // Count of credits available
    ULONG nRefundable;  // Count of credits to be refunded by the CreditDpc routine (RX only)
    ULONG FCost;            // Fixed cost.  Overhead added to each packet of data 
    ULONG Max;              // Effectively a credit limit.  nCredits can never exceed this
} DXB_CREDIT_DESCRIPTOR, *PDXB_CREDIT_DESCRIPTOR;


typedef struct DXB_IO_REQUEST
{
    PIRP pIrp;
    BOOLEAN InProgress;
} DXB_IO_REQUEST, *PDXB_IO_REQUEST;


typedef struct DXB_DPC
{
    KDPC    Dpc;
    KTIMER  Timer;
    BOOLEAN InProgress;
    BOOLEAN StopDpc;
} DXB_DPC, *PDXB_DPC;


typedef struct DXB_WORK_QUEUE
{
    LIST_ENTRY Head;
    KSPIN_LOCK Lock;
    DXB_DPC    DxbDpc;
} DXB_WORK_QUEUE, *PDXB_WORK_QUEUE;


typedef struct DXB_WORK_QUEUE_ENTRY
{
    LIST_ENTRY Entry;
    BOOLEAN    fInList;
} DXB_WORK_QUEUE_ENTRY, *PDXB_WORK_QUEUE_ENTRY;


typedef struct DXB_STREAM_OBJECT
{
    DXB_OBJECT_TYPE Type;

    // This stream's DXB API channel number on the adapter.  Also, is the index into
    // parent device channel array which references this stream.
    ULONG Channel;

    // The device (i.e. adapter) on which this stream exists
    struct DXB_DEVICE_EXTENSION *pExt;

    // The FileObject used to open this stream, i.e. the stream owner.  Used to close 
    // down all Streams opened by a process when that process goes away (or dies, or 
    // is terminated). 
    PFILE_OBJECT OriginalFileObject;

    struct
    {
        // Outbound requests
        DXB_IO_REQUEST Open;
        DXB_IO_REQUEST Close;
        DXB_IO_REQUEST Ioctl;
        DXB_IO_REQUEST Link;
        ULONG LinkedAbove;  // Channel number of stream we're linked above
        ULONG LinkedUnder;  // Channel number of stream we're linked under
    } Control;

    struct
    {
        // Outbound requests
        LIST_ENTRY PutQ[DS_PRIORITY_COUNT];
        LIST_ENTRY GetQ[DS_PRIORITY_COUNT];

        // Incoming data messages queued up here until read via GetMsg 
        LIST_ENTRY IncomingQ[DS_PRIORITY_COUNT];
    } Data;

    struct 
    {
        // Entries on various device extension lists
        LIST_ENTRY           StreamList;
        DXB_WORK_QUEUE_ENTRY Command;
        DXB_WORK_QUEUE_ENTRY Credit;
    } Entries;

    // Dxb Position Reports are used for per-stream flow control
    DXB_CREDIT_DESCRIPTOR Write;
    DXB_CREDIT_DESCRIPTOR Read;
    
    struct
    {
        ULONG nIoctls;
        ULONG nLinks;
        ULONG nPutRequests;
        ULONG nPuts[DS_PRIORITY_COUNT];
        ULONG nGets[DS_PRIORITY_COUNT];
        ULONG nIncoming[DS_PRIORITY_COUNT];
    } Stats;

} DXB_STREAM_OBJECT, *PDXB_STREAM_OBJECT;


typedef struct DXB_CHANNEL
{
    PDXB_STREAM_OBJECT pStream;
    DIGI_SPINLOCK      DxbLock;
    DXB_STREAM_STATE   State;
} DXB_CHANNEL, *PDXB_CHANNEL;


// Device ext contains table of fcn pointers for ADAPTER io (reads and writes)
typedef VOID ( *PDXB_ADAPTER_WRITE )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    VOID CONST                  *pBuf,
    ULONG                       AdapterOffset,
    ULONG                       cb );

typedef VOID ( *PDXB_ADAPTER_WRITE_DWORD )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    ULONG                       AdapterOffset,
    ULONG                       Data );

typedef VOID ( *PDXB_ADAPTER_WRITE_WORD )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    ULONG                       AdapterOffset,
    USHORT                      Data );

typedef VOID ( *PDXB_ADAPTER_WRITE_BYTE )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    ULONG                       AdapterOffset,
    UCHAR                       Data );

typedef VOID ( *PDXB_ADAPTER_READ )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    PVOID                       pBuf,
    ULONG                       AdapterOffset,
    ULONG                       cb );

typedef UCHAR ( *PDXB_ADAPTER_READ_BYTE )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    ULONG                       AdapterOffset );

typedef USHORT ( *PDXB_ADAPTER_READ_WORD )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    ULONG                       AdapterOffset );

typedef ULONG ( *PDXB_ADAPTER_READ_DWORD )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    ULONG                       AdapterOffset );

typedef VOID ( *PDXB_MEMORY_WINDOW_ENABLE )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    USHORT                      Window );

typedef VOID ( *PDXB_MEMORY_WINDOW_DISABLE )( 
    struct DXB_DEVICE_EXTENSION *pExt );

typedef struct DXB_ADAPTER_IO
{
    PDXB_ADAPTER_WRITE         Write;
    PDXB_ADAPTER_READ          Read;

    PDXB_ADAPTER_WRITE_BYTE    WriteByte;
    PDXB_ADAPTER_READ_BYTE     ReadByte;

    PDXB_ADAPTER_WRITE_WORD    WriteWord;
    PDXB_ADAPTER_READ_WORD     ReadWord;

    PDXB_ADAPTER_WRITE_DWORD    WriteDword;
    PDXB_ADAPTER_READ_DWORD     ReadDword;

    PDXB_MEMORY_WINDOW_ENABLE  Enable;
    PDXB_MEMORY_WINDOW_DISABLE Disable;
} DXB_ADAPTER_IO;


#define MAX_PAGES 32
typedef struct DXB_MESSAGE_QUEUE
{
    ULONG         cbTotal;  // Total queue bytes
    ULONG         QOffset;  // My QOffset.  For CmdQ: QIn.  For EventQ: QOut.
    ULONG         cbPage;   // Bytes per page
    DIGI_SPINLOCK Lock;     // Spinlock to protect access to queue and queue pointers.

    struct
    {
        struct
        {
            ULONG            nPages;                            // Number of pages in queue
            PVOID            VirtualPages[MAX_PAGES];       // Virtual addrs, used by host
            PHYSICAL_ADDRESS PhysicalPages[MAX_PAGES];  // Phys addrs used by card

                        PHYSICAL_ADDRESS PhysicalPagestemp[MAX_PAGES];  // Temp Physical for IOVA ampping

        } Master;

        struct
        {
            ULONG  Offset;  // Adapter offset for start of this queue
        } Slave;                
    } Mode;

    union
    {
        struct
        {
            ULONG QInOffset;    // Offset in adapter memory of QIn pointer (DXBV1)
            ULONG QOutOffset;   // Offset in adapter memory of QOut pointer (DXBV1)
        };
        struct 
        {
            PULONG pQIn;        // Host memory address of QIn value (DXBV2)
            PULONG pQOut;       // Host memory address of QOut value (DXBV2)
        };
    } Descriptor;

} DXB_MESSAGE_QUEUE, *PDXB_MESSAGE_QUEUE;


// Device ext contains table of fcn pointers for DXB QUEUE io (reads and writes)
typedef ULONG ( *PDXB_QUEUE_WRITE )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    PDXB_MESSAGE_QUEUE          pDesc,
    ULONG                       QueueOffset,
    PVOID                       pBuf,
    ULONG                       cb );

typedef ULONG ( *PDXB_QUEUE_READ )( 
    struct DXB_DEVICE_EXTENSION *pExt,
    PDXB_MESSAGE_QUEUE          pDesc,
    ULONG                       QueueOffset,
    PVOID                       pBuf,
    ULONG                       cb );

typedef struct DXB_QUEUE_IO
{
    PDXB_QUEUE_WRITE Write;
    PDXB_QUEUE_READ  Read;
} DXB_QUEUE_IO;


// Device ext contains table of fcn pointers for building and interpreting DXB MSG's.
typedef NTSTATUS 
    (*PDXB_CMD_OPEN) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt,
        IN ULONG                       Channel,
        IN DS_OPEN const               *pOpen );

typedef NTSTATUS 
    (*PDXB_CMD_CLOSE) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt,
        IN ULONG                       Channel,
        IN DS_CLOSE const              *pClose );

typedef NTSTATUS 
    (*PDXB_CMD_IOCTL) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt,
        IN ULONG                       Channel,
        IN DS_IOCTL const              *pIoctl );

typedef NTSTATUS 
    (*PDXB_CMD_PUTMSG) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt,
        IN ULONG                       Channel,
        IN DS_PUTMSG const             *pPutMsg );

typedef NTSTATUS 
    (*PDXB_CMD_LINK) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt,
        IN ULONG                       Channel,
        IN DS_LINK const               *pLink );

typedef NTSTATUS 
    (*PDXB_CMD_CREDIT) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt,
        IN ULONG                       Channel,
        IN USHORT                      nCredits );

typedef ULONG
    (*PDXB_EVENT_PROCESSOR) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt, 
        IN ULONG                       QStart );

typedef ULONG
    (*PDXB_READ_CONTROLDATA) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt,
        IN ULONG                       QOut,
        IN PVOID                       pCtrl,
        IN ULONG                       cbCtrl,
        IN PVOID                       pData,
        IN ULONG                       cbData );

typedef ULONG
    (*PDXB_GET_CMD_QIN) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt );

typedef ULONG
    (*PDXB_GET_CMD_QOUT) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt );

typedef VOID
    (*PDXB_SET_CMD_QIN) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt, 
        IN ULONG                       QIn );

typedef ULONG
    (*PDXB_GET_EVENT_QIN) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt );

typedef ULONG
    (*PDXB_GET_EVENT_QOUT) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt );

typedef VOID
    (*PDXB_SET_EVENT_QOUT) ( 
        IN struct DXB_DEVICE_EXTENSION *pExt, 
        IN ULONG                       QOut );

typedef struct DXB_CODEC
{
    PDXB_CMD_OPEN   Open;
    PDXB_CMD_CLOSE  Close;
    PDXB_CMD_PUTMSG PutMsg;
    PDXB_CMD_IOCTL  Ioctl;
    PDXB_CMD_LINK   Link;
    PDXB_CMD_CREDIT CreditAward;

    PDXB_EVENT_PROCESSOR  EventProcessor;
    PDXB_READ_CONTROLDATA ReadCData;

    PDXB_GET_CMD_QIN    GetCmdQIn;
    PDXB_GET_CMD_QOUT   GetCmdQOut;
    PDXB_SET_CMD_QIN    SetCmdQIn;
    PDXB_GET_EVENT_QIN  GetEventQIn;
    PDXB_GET_EVENT_QOUT GetEventQOut;
    PDXB_SET_EVENT_QOUT SetEventQOut;
} DXB_CODEC, *PDXB_CODEC;


typedef struct DXB_IO_RESOURCE
{
    PHYSICAL_ADDRESS Physical;

        PHYSICAL_ADDRESS Physicaltemp; //Physical Address used in Mapping for IOVA

    PVOID            Virtual;
    ULONG            Length;
    ULONG            cbWindow;  // Use if dual-port mem window is smaller than length
    BOOLEAN          fUnmap;
} DXB_IO_RESOURCE, *PDXB_IO_RESOURCE;

typedef struct DXB_IRQ_RESOURCE
{
    PHYSICAL_ADDRESS Number;
    PKINTERRUPT      Interrupt;
    ULONG            Vector;
    KIRQL            Irql;
    KAFFINITY        Affinity;
    KINTERRUPT_MODE  Mode;
    BOOLEAN          fShared;
    ULONG            Period;
} DXB_IRQ_RESOURCE, *PDXB_IRQ_RESOURCE;

typedef struct DXB_HLC_QUEUE_POINTERS
{
    ULONG CmdQIn;
    ULONG pad1[7];
    ULONG CmdQOut;
    ULONG pad2[7];

    ULONG EventQIn;
    ULONG pad3[7];
    ULONG EventQOut;
    ULONG pad4[7];
} DXB_HLC_QUEUE_POINTERS, *PDXB_HLC_QUEUE_POINTERS;


typedef struct DXB_ADAPTER_RESOURCES
{
    // Bus Info
    INTERFACE_TYPE   BusType;
    ULONG            BusNumber;
    ULONG            SlotNumber;
    ULONG            PciId;
    ULONG            PciVendorId;
    ULONG            PciSubSystemId;
    ULONG            PciSubVendorId;

    // Physical Resources
    DXB_IO_RESOURCE  Memory;                // Common dualport memory area
    DXB_IO_RESOURCE  Memory2;               // Adapter specific memory bank (PCI only) 
                                                    // For Epc, Clydesdale: PLX runtime registers
                                                    // For Dense: GPP and DSP memory
    DXB_IO_RESOURCE  Io;                        // EPC ISA reset and windowing bits located here
    DXB_IO_RESOURCE  PciInterfaceChip;  // Memory mapped PLX or Galileo registers
    DXB_IRQ_RESOURCE Irq;

} DXB_ADAPTER_RESOURCES, *PDXB_ADAPTER_RESOURCES;


typedef enum DXB_BUS_MODE
{
    DXB_BUSMODE_INVALID,
    DXB_BUSMODE_SLAVE,
    DXB_BUSMODE_MASTER_WINDOWED,
    DXB_BUSMODE_MASTER_FLAT,
    DXB_BUSMODE_LIM,
    DXB_BUSMODE_MIN = DXB_BUSMODE_INVALID+1,
    DXB_BUSMODE_MAX = DXB_BUSMODE_LIM-1
} DXB_BUS_MODE;

typedef VOID 
    (*PDXB_STOP_ADAPTER)( 
        IN struct DXB_DEVICE_EXTENSION *pExt );

typedef VOID 
    (*PDXB_ASSERT_RESET)( 
        IN struct DXB_DEVICE_EXTENSION *pExt );

typedef BOOLEAN
    (*PDXB_CLEAR_INTERRUPT)(
        IN struct DXB_DEVICE_EXTENSION *pExt );

typedef struct _SRA_ADAPTER SRA_ADAPTER,*PSRA_ADAPTER;

typedef struct DXB_DEVICE_EXTENSION
{
    DXB_OBJECT_TYPE  Type;

    ULONG            UniqueId;

    #define NAME_BUFFER_LENGTH 64
    UNICODE_STRING   Name;
    WCHAR            NameBuffer[NAME_BUFFER_LENGTH];

#if NT5_BUILD
    #define INSTANCE_BUFFER_LENGTH 8
    UNICODE_STRING   Instance;
    WCHAR            InstanceBuffer[INSTANCE_BUFFER_LENGTH];
    PDEVICE_OBJECT   pPdo;  // Physical Device object created by PCI bus enumerator
    PDEVICE_OBJECT   pNextDeviceObject; // Could be different than Pdo if filter 
                                        // drivers are present.  Forward Irps to this.
    LIST_ENTRY       ChildListHead;     // List of child PDOs.
#endif

    // Alloc'd string defines the adapter type, i.e. "SyncPort".  This must be freed!
    UNICODE_STRING   Option;

    DIGI_SPINLOCK    DxbLock;

#if NT5_BUILD
    DXB_PNP_STATE       PnpState;       // Current PNP State, started, removed, etc
    DXB_POWER_STATE     PowerState;     // current power state
    DEVICE_POWER_STATE  DevPower;       // current device power state
    SYSTEM_POWER_STATE  SysPower;       // current system power state
    SYSTEM_POWER_STATE  WakeSysPower;   // wakeup system power state
    DIGI_RESOURCE_LIST  PowerResources; // Copy of resources, used on SET_POWER StartDevice
    LIST_ENTRY          RequestList;    // Queue of Irps held while stopping device
    BOOLEAN             fHoldNewRequests;   // Set when stopping device via PNP Irps
#endif  

    BOOLEAN          fSpoof;                // Are we spoofing startup?  If so, fail Create requests!

    // Flag set when shutting down - tells EventDpc to stop servicing the queue
    BOOLEAN          bShutdown;
    // New Stratus 25/3/02 - flag set when adapter failure is detected
    BOOLEAN          bAdapterFailed;
    // Timer and DPC objects to help implement our hardware sanity checks
    KTIMER           HardwareCheckTimer;
    KDPC             HardwareCheckDpc;
    BOOLEAN          bTimerInitialized;

    // Handle from DsApi library.  Used to send myself DStreams requests to build the
    // protocol stacks at init time.
    HANDLE           hDsDevice;

    // The "parent" device object containing this device extension
    PDEVICE_OBJECT   pDeviceObject;

    // Entry on list of device extensions
    LIST_ENTRY       ExtListEntry;

    // List of stream objects
    LIST_ENTRY       StreamList;

    DXB_ADAPTER_RESOURCES Hardware;

    // Handle of reported resources for this adapter.  See digires.h for details.
    HANDLE           hReportedResources;

    DXB_BUS_MODE     DxbBusMode;

    // Spinlock protection used on windowed adapters (ISA, MCA) to synchronize access
    // to adapter memory windows.
    DIGI_SPINLOCK    WindowLock;

    struct 
    {
        struct DXB_STREAM_OBJECT *Fr;
        struct DXB_STREAM_OBJECT *Isdn;
        struct DXB_STREAM_OBJECT *Lapb;
        struct DXB_STREAM_OBJECT *X25;
    } ControlStreams;

    // DXB Command and Event queues
    DXB_MESSAGE_QUEUE DxbCmdQ;
    DXB_MESSAGE_QUEUE DxbEventQ;

    // PCI BusMaster 

    PADAPTER_OBJECT pDmaAdapter;    // NT DMA Adapter object

    // Dense specific BusMaster structures residing in the host
    DXB_IO_RESOURCE HlcGlobalHost;
    DXB_IO_RESOURCE HlcQueue;

    struct
    {
        DXB_WORK_QUEUE Command;
        DXB_WORK_QUEUE Credit;
    } Work;

    DXB_DPC EventDpc;

    DXB_CREDIT_DESCRIPTOR CreditDefault;

    // Dispatch routines.  
    DXB_ADAPTER_IO    Adapter;  // Adapter routines for reading/writing adapter memory
    DXB_QUEUE_IO      Queue;    // Queue routines for reading/writing dxb queues
    DXB_CODEC         Message;  // Routines for encoding/decoding dxb messages
    PDXB_STOP_ADAPTER StopAdapter;
    PDXB_ASSERT_RESET AssertReset;
    PDXB_CLEAR_INTERRUPT ClearInterrupt;

    LARGE_INTEGER TotalDpcTime;
    ULONG DpcCount;
    BOOLEAN      bAsyncDevice;
    BOOLEAN      bIOVAEnabled;
//#ifdef STRATUS_DEVICE
    ULONG        uBar0Async;
    ULONG        uBar0Sync;
    PHYSICAL_ADDRESS IOVAPhysical_Address[MAX_PAGES];
    ULONG         ulIOVAbufferSize[MAX_PAGES];
    ULONG         ulNumberofAllocations;
    PHYSICAL_ADDRESS         pTempPhysical[MAX_PAGES];
//#endif
    PSRA_ADAPTER SraAdapter;


    DXB_CHANNEL Channels[DXB_MAX_CHANNELS];

} DXB_DEVICE_EXTENSION, *PDXB_DEVICE_EXTENSION;


#if NT5_BUILD
// Child device (PDO) extension
typedef struct DXB_CHILD_DEVICE
{
    DXB_OBJECT_TYPE       Type;             // set to DXB_TYPE_CHILD_DEVICE
    PDEVICE_OBJECT        pPhysicalDeviceObject;    // My device object (a PDO)
    LIST_ENTRY            ListEntry;        // Entry on adapter ChildList
    PDXB_DEVICE_EXTENSION pParentExt;       // parent (FDO) device extension
    UNICODE_STRING        HardwareId;       // DIGIT1
    UNICODE_STRING        RegPath;          // {4D36E972...}\0001\Parameters\ISDN\0
    UNICODE_STRING        InstanceId;       // Instance of HardwareId on this adapter
    ULONG                 DeviceStateFlags; // most child devices will use the PNP_DEVICE_DONT_DISPLAY_IN_UI                            
                                            //  to hide the device in the Device Manager UI. However, Xp ports
                                            //  need to be displayed.                                                                        
    DEVICE_POWER_STATE    PowerState;       // current device power state
    BOOLEAN               Removed;

} DXB_CHILD_DEVICE, *PDXB_CHILD_DEVICE;


#endif


// The DXB_MSG struct is used to queue incoming message from the dxb adapter
// when until a GetMsg Irp request comes down asking for it.  Typical use is to alloc
// a larger chunk of memory and append the control and data portions to this header.
typedef struct DXB_MSG
{
    DXB_OBJECT_TYPE Type;
    LIST_ENTRY      Entry;
    PVOID           pCtrl;
    ULONG           cbCtrl;
    PVOID           pData;
    ULONG           cbData;
} DXB_MSG, *PDXB_MSG;


#define DxbAdapterLock( pExt )      DigiAcquireSpinLock( &(pExt)->DxbLock )
#define DxbAdapterUnlock( pExt )        DigiReleaseSpinLock( &(pExt)->DxbLock )

STATIC __inline VOID 
dxbIoCompleteRequest( PIRP pIrp, NTSTATUS Status, ULONG Information )
{
    DigiUnlockBuffers( pIrp );
    pIrp->IoStatus.Status = Status;
    pIrp->IoStatus.Information = Information;
    IoCompleteRequest( pIrp, IO_NO_INCREMENT );
}


typedef struct DXB_MINOR_TABLE
{
    ULONG Minor;
    PCSTR Name;
} DXB_MINOR_TABLE, PDXB_MINOR_TABLE;


__inline PCSTR
DxbGetIrpName( ULONG Minor, DXB_MINOR_TABLE const Table[], ULONG nEntries )
{
    static const CHAR Unknown[] = "Unknown";
    PCSTR Name = Unknown;
    ULONG i;
    for ( i = 0; i < nEntries; i++ )
    {
        if ( Minor == Table[i].Minor )
        {
            Name = Table[i].Name;
            break;
        }
    }
    return Name;
}


#include "dxbdevice.h"
#include "dxbstream.h"
#include "dxbinit.h"
#include "dxbreg.h"
#include "dxblog.h"
#include "dxberror.h"
#include "dxbfr.h"
#include "dxbiwan.h"
#include "dxbwan.h"
#include "dxbslave.h"
#include "dxbpci.h"
#include "dxbbuild.h"
#include "dxbdpc.h"
#include "dxbworkq.h"
#include "dxbcmd.h"
#include "dxbv1.h"
#include "dxbv2.h"
#include "dxbdma.h"
#include "dxbqueue.h"
#include "dxbstatus.h"
#include "dxbcredit.h"
#include "dxbkme.h"
#include "dxbepc.h"
#include "dxbhlc.h"
#include "dxbclyde.h"
#include "dxbpri.h"
#include "dxbx25.h"
#include "dxbpnp.h"
#include "dxbrap.h"
#include "dxbchild.h"
#include "dxbpower.h"
#include "dxbisr.h"
#endif
