/*++
*******************************************************************************
* 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"

#if NT5_BUILD
#define PADAPTER_OBJECT PDMA_ADAPTER
#endif

// 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;

	// Info about queued data packets ready to retrieve:
	unsigned int CntQueued;

} 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
		} 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;
	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 DXB_DEVICE_EXTENSION
{
	DXB_OBJECT_TYPE  Type;

	#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;

	// 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;

	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
