Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

681 lines
23 KiB

#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