#if !defined(SPD_CARD_H)
#define SPD_CARD_H	




#if DBG
#define SERDIAG1              ((ULONG)0x00000001)
#define SERDIAG2              ((ULONG)0x00000002)
#define SERDIAG3              ((ULONG)0x00000004)
#define SERDIAG4              ((ULONG)0x00000008)
#define SERDIAG5              ((ULONG)0x00000010)
#define SERIRPPATH            ((ULONG)0x00000020)
#define SERWARNING            ((ULONG)0x00000100)
#define SERINFO               ((ULONG)0x00000200)

#define SERFLOW               ((ULONG)0x00000400)
#define SERERRORS             ((ULONG)0x00000800)
#define SERBUGCHECK           ((ULONG)0x00001000)

// -- OXSER Diag 3 --
// Additional debug levels
#define PCIINFO               ((ULONG)0x00002000)
#define XTLINFO               ((ULONG)0x00004000)
#define ISRINFO				  ((ULONG)0x00008000)
#define TXINFO				  ((ULONG)0x00010000)
#define RXINFO				  ((ULONG)0x00020000)
#define LSINFO				  ((ULONG)0x00040000)
#define MSINFO				  ((ULONG)0x00080000)
#define KICKINFO			  ((ULONG)0x00100000)
#define FIFOINFO			  ((ULONG)0x00200000)
#define CLOSE_STATS			  ((ULONG)0x00400000)
#define BAUDINFO			  ((ULONG)0x00800000)	

extern ULONG SpxDebugLevel;

#define SerialDump(LEVEL,STRING)											\
    do {																	\
        ULONG _level = (LEVEL);												\
		if (SpxDebugLevel & _level) {										\
            DbgPrint STRING;												\
        }																	\
        if (_level == SERBUGCHECK) {										\
            ASSERT(FALSE);													\
        }																	\
    } while (0)
#else
#define SerialDump(LEVEL,STRING) do {NOTHING;} while (0)
#endif





// For the above directory, the serial port will
// use the following name as the suffix of the serial
// ports for that directory.  It will also append
// a number onto the end of the name.  That number
// will start at 1.
#define DEFAULT_SERIAL_NAME L"COM"


// This define gives the default NT name for
// for serial ports detected by the firmware.
// This name will be appended to Device prefix
// with a number following it.  The number is
// incremented each time encounter a serial
// port detected by the firmware.  Note that
// on a system with multiple busses, this means
// that the first port on a bus is not necessarily
// \Device\Serial0.
//
#define DEFAULT_NT_SUFFIX L"Serial"



// Default xon/xoff characters.
#define SERIAL_DEF_XON		0x11
#define SERIAL_DEF_XOFF		0x13

// Reasons that recption may be held up.
#define SERIAL_RX_DTR       ((ULONG)0x01)
#define SERIAL_RX_XOFF      ((ULONG)0x02)
#define SERIAL_RX_RTS       ((ULONG)0x04)
#define SERIAL_RX_DSR       ((ULONG)0x08)

// Reasons that transmission may be held up.
#define SERIAL_TX_CTS       ((ULONG)0x01)
#define SERIAL_TX_DSR       ((ULONG)0x02)
#define SERIAL_TX_DCD       ((ULONG)0x04)
#define SERIAL_TX_XOFF      ((ULONG)0x08)
#define SERIAL_TX_BREAK     ((ULONG)0x10)


//////////////////////////////////////////////////////////////////////////////////////////
// SPEED Port Device Extenstion.
// Information specific to SPEED Ports.
//////////////////////////////////////////////////////////////////////////////////////////
typedef struct _PORT_DEVICE_EXTENSION 
{

	COMMON_PORT_DEVICE_EXTENSION;		// Common Card Device Extension 

	ULONG			SysPortNumber;		// System port number 

	// Timing variables... 
    LARGE_INTEGER		IntervalTime;			// Read interval time 
	LARGE_INTEGER		ShortIntervalAmount;	// Short tread interval time 
	LARGE_INTEGER		LongIntervalAmount;		// Long read interval time 
	LARGE_INTEGER		CutOverAmount;			// Used to determine short/long interval time 
	LARGE_INTEGER		LastReadTime;			// System time of last read 
	PLARGE_INTEGER		IntervalTimeToUse;		// Interval timing delta time delay 
	
	// Queued IRP lists... 
	LIST_ENTRY		ReadQueue;		// Head of read IRP list, protected by cancel spinlock 
	LIST_ENTRY		WriteQueue;		// Head of write IRP list, protected by cancel spinlock 
	LIST_ENTRY		MaskQueue;		// Head of set/wait mask IRP list, protected by cancel spinlock 
	LIST_ENTRY		PurgeQueue;		// Head of purge IRP list, protected by cancel spinlock 

	// Current IRPs... 
	PIRP			CurrentReadIrp;			// Pointer to current read IRP 
	PIRP			CurrentWriteIrp;		// Pointer to current write IRP 
	PIRP			CurrentMaskIrp;			// Pointer to current mask IRP 
	PIRP			CurrentPurgeIrp;		// Pointer to current purge IRP 
	PIRP			CurrentWaitIrp;			// Pointer to current wait IRP 
	PIRP			CurrentImmediateIrp;	// Pointer to current send immediate IRP 
	PIRP			CurrentXoffIrp;			// Pointer to current XOFF_COUNTER IRP 

	// Write IRP variables... 
	ULONG			WriteLength;			// Write character count in current write IRP 
	PUCHAR			WriteCurrentChar;		// Pointer to write character in current write IRP 

	// Read IRP variables... 
	PUCHAR			InterruptReadBuffer;	// Read buffer current pointer in current read IRP 
	PUCHAR			ReadBufferBase;			// Read buffer base pointer in current read IRP 
	ULONG			CharsInInterruptBuffer;	// Characters read into read buffer 
//	KSPIN_LOCK		BufferLock;				// Spinlock protecting "CharsInInterruptBuffer" 
	PUCHAR			CurrentCharSlot;		// Pointer at space to store new read data 
	PUCHAR			LastCharSlot;			// Last valid position in read buffer 
	PUCHAR			FirstReadableChar;		// First read character in read buffer 
	ULONG			BufferSize;				// Read buffer size 
	ULONG			BufferSizePt8;			// 80% read buffer size 
	ULONG			NumberNeededForRead;	// Number of characters requested in current read IRP 

	// Mask IRP variables... 
	ULONG			IsrWaitMask;			// Wait mask in current wait IRP 
	ULONG			HistoryMask;			// History of masked events 
	ULONG			*IrpMaskLocation;		// Pointer to mask location 

	// Serial port configuration...
//	ULONG				CurrentBaud;		// Current baud rate 
	ULONG				SupportedBauds;		// Bitmask defining supported baud rates 
	SERIAL_HANDFLOW		HandFlow;			// Current handshaking and flow control settings 
	UCHAR				LineControl;		// Current parity,databits,stopbits 
	SERIAL_CHARS		SpecialChars;		// Current Special error/replacement characters 
	SERIAL_TIMEOUTS		Timeouts;			// Read and write timeouts 
	UCHAR				ValidDataMask;		// Read data mask 
	UCHAR				EscapeChar;			// Escape character used with line/modem status strings 
//	BOOLEAN				InsertEscChar;		// Indicates of EscapeChar should be inserted 

	// Serial port status... 
	LONG			CountSinceXoff;			// Nun chars read since XOFF counter started 
	ULONG			CountOfTryingToLowerRTS;// Count of processes trying to lower RTS 
	BOOLEAN			TransmitImmediate;		// Indicates of transmit immediate is pending 
	BOOLEAN			EmptiedTransmit;		// Indicates transmit empty 
	UCHAR			ImmediateChar;			// Character to be transmitted immediately 
	ULONG			TXHolding;				// Reasons for transmit blocked 
	ULONG			RXHolding;				// Reasons for receive blocked 
	ULONG			ErrorWord;				// Error conditions 
	ULONG			TotalCharsQueued;		// Total number of queued characters in all write IRPs 
	LONG			CountOnLastRead;		// Number of chars read last time interval timer DPC ran 
	ULONG			ReadByIsr;				// Number of characters read during ISR 

	KSPIN_LOCK		ControlLock;			// Used to protect certain fields 

	// Deferred procedure calls... 
	KDPC		CompleteWriteDpc;			// DPC used to complete write IRPs 
	KDPC		CompleteReadDpc;			// DPC used to complete read IRPs 
	KDPC		TotalReadTimeoutDpc;		// DPC used to handle read total timeout 
	KDPC		IntervalReadTimeoutDpc;		// DPC used to handle read interval timeout 
	KDPC		TotalWriteTimeoutDpc;		// DPC used to handle write total timeout 
	KDPC		CommErrorDpc;				// DPC used to handle cancel on error 
	KDPC		CommWaitDpc;				// DPC used to handle waking IRPs waiting on an event 
	KDPC		CompleteImmediateDpc;		// DPC used to handle transmitting an immediate character 
	KDPC		TotalImmediateTimeoutDpc;	// DPC used to handle immediate char timeout 
	KDPC		XoffCountTimeoutDpc;		// DPC used to handle XOFF_COUNT timeout 
	KDPC		XoffCountCompleteDpc;		// DPC used to complete XOFF_COUNT IRP 
	KDPC		StartTimerLowerRTSDpc;		// DPC used to check for RTS lowering 
	KDPC		PerhapsLowerRTSDpc;			// DPC used to check for RTS lowering 

	// Timers... 
	KTIMER		ReadRequestTotalTimer;		// Timer used to handle total read request timeout 
	KTIMER		ReadRequestIntervalTimer;	// Timer used to handle interval read timeout 
	KTIMER		WriteRequestTotalTimer;		// Timer used to handle total write request timeout 
	KTIMER		ImmediateTotalTimer;		// Timer used to handle send immediate timeout 
	KTIMER		XoffCountTimer;				// Timer used to handle XOFF_COUNT timeout 
	KTIMER		LowerRTSTimer;				// Timer used to handle lower RTS timing 



	PUART_LIB		pUartLib;	// Uart library finctions.
	PUART_OBJECT	pUart;
	UART_CONFIG		UartConfig;
	BOOLEAN			DTR_Set;
	BOOLEAN			RTS_Set;
	SET_BUFFER_SIZES BufferSizes;

	DWORD			MaxTxFIFOSize;		// Max Tx FIFO Size.
	DWORD			MaxRxFIFOSize;		// Max Rx FIFO Size.

	DWORD			TxFIFOSize;			// Tx FIFO Size.
	DWORD			RxFIFOSize;			// Rx FIFO Size.
	DWORD			TxFIFOTrigLevel;	// Tx FIFO Trigger Level.
	DWORD			RxFIFOTrigLevel;	// Rx FIFO Trigger Level.
	DWORD			HiFlowCtrlThreshold;	// High Flow Control Threshold.
	DWORD			LoFlowCtrlThreshold;	// Low Flow Control Threshold.

	#ifdef WMI_SUPPORT
	SPX_SPEED_WMI_FIFO_PROP		SpeedWmiFifoProp;
	#endif

	BYTE			ImmediateIndex;

    // This holds the isr that should be called from our own
    // dispatching isr for "cards" that are trying to share the
    // same interrupt.

    PKSERVICE_ROUTINE TopLevelOurIsr;

    // This holds the context that should be used when we
    // call the above service routine.
    
	PVOID TopLevelOurIsrContext;

    // This links together all of the different "cards" that are
    // trying to share the same interrupt of a non-mca machine.
    
    LIST_ENTRY TopLevelSharers;

    // This circular doubly linked list links together all
    // devices that are using the same interrupt object.
    // NOTE: This does not mean that they are using the
    // same interrupt "dispatching" routine.
    
    LIST_ENTRY CommonInterruptObject;

    // For reporting resource usage, we keep around the physical
    // address we got from the registry.
    
	PHYSICAL_ADDRESS OriginalController;

    // For reporting resource usage, we keep around the physical
    // address we got from the registry.
    
    PHYSICAL_ADDRESS OriginalInterruptStatus;




    // This points to the object directory that we will place
    // a symbolic link to our device name.
    
    UNICODE_STRING ObjectDirectory;
    
    // This points to the device name for this device
    // sans device prefix.
    
    UNICODE_STRING NtNameForPort;

    // After initialization of the driver is complete, this
    // will either be NULL or point to the routine that the
    // kernel will call when an interrupt occurs.
    
    // If the pointer is null then this is part of a list
    // of ports that are sharing an interrupt and this isn't
    // the first port that we configured for this interrupt.
    
    // If the pointer is non-null then this routine has some
    // kind of structure that will "eventually" get us into
    // the real serial isr with a pointer to this device extension.
    
    // NOTE: On an MCA bus (except for multiport cards) this
    // is always a pointer to the "real" serial isr.
    
	PKSERVICE_ROUTINE OurIsr;

    // This will generally point right to this device extension.
    //
    // However, when the port that this device extension is
    // "managing" was the first port initialized on a chain
    // of ports that were trying to share an interrupt, this
    // will point to a structure that will enable dispatching
    // to any port on the chain of sharers of this interrupt.
    
    PVOID OurIsrContext;

    // The base address for the set of device registers
    // of the serial port.
    
    PUCHAR Controller;

    // The base address for interrupt status register.
    // This is only defined in the root extension.
    
    PUCHAR InterruptStatus;

    // Points to the interrupt object for used by this device.
    
    PKINTERRUPT Interrupt;




    // Pointer to the lock variable returned for this extension when
    // locking down the driver
    
    PVOID LockPtr;


	// This value holds the span (in units of bytes) of the register
    // set controlling this port.  This is constant over the life
    // of the port.

    ULONG SpanOfController;

    // This value holds the span (in units of bytes) of the interrupt
    // status register associated with this port.  This is constant
    // over the life of the port.

    ULONG SpanOfInterruptStatus;

    // Hold the clock rate input to the serial part.

    ULONG ClockRate;

    // The number of characters to push out if a fifo is present.

    ULONG TxFifoAmount;

    // Set to indicate that it is ok to share interrupts within the device.

    ULONG PermitShare;





    // Set at intialization to indicate that on the current
    // architecture we need to unmap the base register address
    // when we unload the driver.

    BOOLEAN UnMapRegisters;

	// Set at intialization to indicate that on the current
    // architecture we need to unmap the interrupt status address
    // when we unload the driver.

    BOOLEAN UnMapStatus;

    // This is only accessed at interrupt level.  It keeps track
    // of whether the holding register is empty.

    BOOLEAN HoldingEmpty;



    // This simply indicates that the port associated with this
    // extension is part of a multiport card.

    BOOLEAN PortOnAMultiportCard;

    // We keep the following values around so that we can connect
    // to the interrupt and report resources after the configuration
    // record is gone.

    ULONG Vector;
    KIRQL Irql;
    ULONG OriginalVector;
    ULONG OriginalIrql;
    KINTERRUPT_MODE InterruptMode;
    KAFFINITY ProcessorAffinity;
    ULONG AddressSpace;
    ULONG BusNumber;
    INTERFACE_TYPE InterfaceType;



    // These two booleans are used to indicate to the isr transmit
    // code that it should send the xon or xoff character.  They are
    // only accessed at open and at interrupt level.

    BOOLEAN SendXonChar;
    BOOLEAN SendXoffChar;

    // This boolean will be true if a 16550 is present *and* enabled.

    BOOLEAN FifoPresent;

  	//	-- OXSER Mod 12 --
	// The Jensen does not interest us and all references to it have been
	// removed

	// This denotes that this particular port is an on the motherboard
    // port for the Jensen hardware.  On these ports the OUT2 bit
    // which is used to enable/disable interrupts is always hight.
    // BOOLEAN Jensen;
	
    // This is the water mark that the rxfifo should be
    // set to when the fifo is turned on.  This is not the actual
    // value, but the encoded value that goes into the register.

    UCHAR RxFifoTrigger;

    // Says whether this device can share interrupts with devices
    // other than serial devices.

    BOOLEAN InterruptShareable;


} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;











// PORT_DEVICE_EXTENSION.CountOnLastRead definitions... 
#define		SERIAL_COMPLETE_READ_CANCEL		((LONG)-1)
#define		SERIAL_COMPLETE_READ_TOTAL		((LONG)-2)
#define		SERIAL_COMPLETE_READ_COMPLETE	((LONG)-3)


// PORT_DEVICE_EXTENSION.LineControl definitions... 
#define		SERIAL_5_DATA		((UCHAR)0x00)
#define		SERIAL_6_DATA		((UCHAR)0x01)
#define		SERIAL_7_DATA		((UCHAR)0x02)
#define		SERIAL_8_DATA		((UCHAR)0x03)
#define		SERIAL_DATA_MASK	((UCHAR)0x03)

#define		SERIAL_1_STOP		((UCHAR)0x00)
#define		SERIAL_1_5_STOP		((UCHAR)0x04) // Only valid for 5 data bits
#define		SERIAL_2_STOP		((UCHAR)0x04) // Not valid for 5 data bits
#define		SERIAL_STOP_MASK	((UCHAR)0x04)

#define		SERIAL_NONE_PARITY	((UCHAR)0x00)
#define		SERIAL_ODD_PARITY	((UCHAR)0x08)
#define		SERIAL_EVEN_PARITY	((UCHAR)0x18)
#define		SERIAL_MARK_PARITY	((UCHAR)0x28)
#define		SERIAL_SPACE_PARITY	((UCHAR)0x38)
#define		SERIAL_PARITY_MASK	((UCHAR)0x38)
#define		SERIAL_LCR_BREAK	0x40


// PORT_DEVICE_EXTENSION.SpecialChars default xon/xoff characters... 
#define		SERIAL_DEF_XON		0x11
#define		SERIAL_DEF_XOFF		0x13

// PORT_DEVICE_EXTENSION.TXHolding definitions... 
#define		SERIAL_TX_CTS		((ULONG)0x01)
#define		SERIAL_TX_DSR		((ULONG)0x02)
#define		SERIAL_TX_DCD		((ULONG)0x04)
#define		SERIAL_TX_XOFF		((ULONG)0x08)
#define		SERIAL_TX_BREAK		((ULONG)0x10)

// PORT_DEVICE_EXTENSION.RXHolding definitions...
#define		SERIAL_RX_DTR		((ULONG)0x01)
#define		SERIAL_RX_XOFF		((ULONG)0x02)
#define		SERIAL_RX_RTS		((ULONG)0x04)
#define		SERIAL_RX_DSR		((ULONG)0x08)	
#define		SERIAL_RX_FULL      ((ULONG)0x10)   // VIV: If Io8 Rx queue is full.

// PORT_DEVICE_EXTENSION.LastStatus definitions... 
#define		SERIAL_LSR_DR       0x01
#define		SERIAL_LSR_OE		0x02
#define		SERIAL_LSR_PE		0x04
#define		SERIAL_LSR_FE		0x08
#define		SERIAL_LSR_BI		0x10

// 16550 Modem Control Register definitions... 
#define		SERIAL_MCR_DTR		0x01
#define		SERIAL_MCR_RTS		0x02

// 16550 Modem Status Register definitions... 
#define		SERIAL_MSR_DCTS		0x01
#define		SERIAL_MSR_DDSR		0x02
#define		SERIAL_MSR_TERI		0x04
#define		SERIAL_MSR_DDCD		0x08
#define		SERIAL_MSR_CTS		0x10
#define		SERIAL_MSR_DSR		0x20
#define		SERIAL_MSR_RI		0x40
#define		SERIAL_MSR_DCD		0x80



// These masks define the interrupts that can be enabled or disabled.
//
// This interrupt is used to notify that there is new incomming
// data available.  The SERIAL_RDA interrupt is enabled by this bit.
#define SERIAL_IER_RDA   0x01


// This interrupt is used to notify that there is space available
// in the transmitter for another character.  The SERIAL_THR
// interrupt is enabled by this bit.
#define SERIAL_IER_THR   0x02

// This interrupt is used to notify that some sort of error occured
// with the incomming data.  The SERIAL_RLS interrupt is enabled by
// this bit.
#define SERIAL_IER_RLS   0x04

// This interrupt is used to notify that some sort of change has
// taken place in the modem control line.  The SERIAL_MS interrupt is
// enabled by this bit.
#define SERIAL_IER_MS    0x08


// These masks define the values of the interrupt identification
// register.  The low bit must be clear in the interrupt identification
// register for any of these interrupts to be valid.  The interrupts
// are defined in priority order, with the highest value being most
// important.  See above for a description of what each interrupt
// implies.
#define SERIAL_IIR_RLS      0x06
#define SERIAL_IIR_RDA      0x04
#define SERIAL_IIR_CTI      0x0c
#define SERIAL_IIR_THR      0x02
#define SERIAL_IIR_MS       0x00


// This bit mask get the value of the high two bits of the
// interrupt id register.  If this is a 16550 class chip
// these bits will be a one if the fifo's are enbled, otherwise
// they will always be zero.
#define SERIAL_IIR_FIFOS_ENABLED 0xc0

// If the low bit is logic one in the interrupt identification register
// this implies that *NO* interrupts are pending on the device.
#define SERIAL_IIR_NO_INTERRUPT_PENDING 0x01




// These masks define access to the fifo control register.

// Enabling this bit in the fifo control register will turn
// on the fifos.  If the fifos are enabled then the high two
// bits of the interrupt id register will be set to one.  Note
// that this only occurs on a 16550 class chip.  If the high
// two bits in the interrupt id register are not one then
// we know we have a lower model chip.
#define SERIAL_FCR_ENABLE     ((UCHAR)0x01)
#define SERIAL_FCR_RCVR_RESET ((UCHAR)0x02)
#define SERIAL_FCR_TXMT_RESET ((UCHAR)0x04)


// This set of values define the high water marks (when the
// interrupts trip) for the receive fifo.
#define SERIAL_1_BYTE_HIGH_WATER   ((UCHAR)0x00)
#define SERIAL_4_BYTE_HIGH_WATER   ((UCHAR)0x40)
#define SERIAL_8_BYTE_HIGH_WATER   ((UCHAR)0x80)
#define SERIAL_14_BYTE_HIGH_WATER  ((UCHAR)0xc0)



// This defines the bit used to control the definition of the "first"
// two registers for the 8250.  These registers are the input/output
// register and the interrupt enable register.  When the DLAB bit is
// enabled these registers become the least significant and most
// significant bytes of the divisor value.
#define SERIAL_LCR_DLAB     0x80


// This bit is used for general purpose output.
#define SERIAL_MCR_OUT1     0x04

// This bit is used for general purpose output.
#define SERIAL_MCR_OUT2     0x08

// This bit controls the loopback testing mode of the device.  Basically
// the outputs are connected to the inputs (and vice versa).
#define SERIAL_MCR_LOOP     0x10


// This is the transmit holding register empty indicator.  It is set
// to indicate that the hardware is ready to accept another character
// for transmission.  This bit is cleared whenever a character is
// written to the transmit holding register.
#define SERIAL_LSR_THRE     0x20


// This bit is the transmitter empty indicator.  It is set whenever the
// transmit holding buffer is empty and the transmit shift register
// (a non-software accessable register that is used to actually put
// the data out on the wire) is empty.  Basically this means that all
// data has been sent.  It is cleared whenever the transmit holding or
// the shift registers contain data.
#define SERIAL_LSR_TEMT     0x40


// This bit indicates that there is at least one error in the fifo.
// The bit will not be turned off until there are no more errors
// in the fifo.
#define SERIAL_LSR_FIFOERR  0x80


//
// This should be more than enough space to hold then
// numeric suffix of the device name.
//
#define DEVICE_NAME_DELTA 20


//
// Up to 16 Ports Per card.  However for sixteen
// port cards the interrupt status register must be
// the indexing kind rather then the bitmask kind.
//
#define SERIAL_MAX_PORTS_INDEXED      (16)
#define SERIAL_MAX_PORTS_NONINDEXED   (8)




















//////////////////////////////////////////////////////////////////////////////////////////
// SPEED Card Device Extenstion.
// Information specific to SPEED cards.
//////////////////////////////////////////////////////////////////////////////////////////
typedef struct _CARD_DEVICE_EXTENSION 
{

	COMMON_CARD_DEVICE_EXTENSION;	// Common Card Device Extension 
	
	ULONG CrystalFrequency;			// Frequency of onboard crystal

	PHYSICAL_ADDRESS	PCIConfigRegisters;
	ULONG				SpanOfPCIConfigRegisters;
	PUCHAR				LocalConfigRegisters;


	PUCHAR InterruptStatus;
    PPORT_DEVICE_EXTENSION Extensions[SERIAL_MAX_PORTS_INDEXED];
    ULONG MaskInverted;
    UCHAR UsablePortMask;
	ULONG UARTOffset;
	ULONG UARTRegStride;
 
	// First UART in the list to be serviced next by the ISR.
	PUART_OBJECT	pFirstUart;

	UART_LIB		UartLib;	// Uart library finctions.

	ULONG CardOptions;
	

} CARD_DEVICE_EXTENSION, *PCARD_DEVICE_EXTENSION;


#endif // End of SPD_CARD.H