NT4/private/ntos/dd/digibrd/fep5/ntfep5.h
2020-09-30 17:12:29 +02:00

1451 lines
46 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
*****************************************************************************
* *
* 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. *
* *
*****************************************************************************
Module Name:
ntfep5.h
Abstract:
This module has all the information to access a DigiBoard controller
running the FEP/OS 5 program. It also contains all the information
required to create controller objects and device objects which are
used by DigiBoards NT FEP5 driver.
Revision History:
* $Log: ntfep5.h $
* Revision 1.33.2.8 1995/11/28 12:56:30 dirkh
* Move MEMPRINT stuff to header.h.
* DigiDump can be configured whether to print NOTIMPLEMENTED messages.
*
* Revision 1.33.2.7 1995/11/09 13:50:14 dirkh
* Cache last requested port speed in device extension (allows many IOCTL_SERIAL_SET_BAUD_RATE to be ignored).
*
* Revision 1.33.2.6 1995/10/18 11:49:20 dirkh
* Add ReceiveNotificationLimit to DIGI_DEVICE_EXTENSION for SERIAL_EV_RX80FULL.
*
* Revision 1.33.2.5 1995/10/17 10:29:20 dirkh
* Change default FEP break to 2 tics (from 25).
*
* Revision 1.33.2.4 1995/09/19 16:58:22 dirkh
* Add pXoffCounter and XcPreview members to DIGI_DEVICE_EXTENSION.
* Sort the baud rate table.
* BaudRate table and ModemSignalTable are declared as constant arrays.
* Indeces into the ModemSignalTable are declared in an enumeration.
* Simplify FEP command constants.
* Remove unused structures FEP_WRITE and EVENT_STRUCT.
* Clean up structures for shared memory window across multiple controllers.
*
* Revision 1.33.2.3 1995/09/05 13:45:50 dirkh
* Fix comments.
*
* Revision 1.33.2.2 1995/09/01 21:43:20 dirkh
* Update DIGI_DEVICE_EXTENSION structure:
* {
* Remove unnecessary members: WriteTxBufferCnt, WriteOffset, ReadOffset.
* Remove unused members: StartTransmit, FEPWrite, QueueRxIrp, FEPRead.
* Re-order remaining members.
* }
* Redefine ASSERT such that it works on free build kernels.
* Remove unused memory macros.
*
* Revision 1.33.2.1 1995/08/11 14:27:16 dirkh
* Add DIGI_DEVICE_STATE_CLEANUP for SerialCleanup.
*
* Revision 1.33 1995/04/06 17:41:32 rik
* Changed and unused debug flag to something meaningful for new debug trace.
*
* Revision 1.32 1994/11/28 09:16:29 rik
* Made corrections for PowerPC port.
* Optimized the polling loop for determining which port needs servicing.
* Changed from using RtlLarge math functions to direct 64-bit manipulation,
* per Microsoft's request.
*
* Revision 1.31 1994/09/13 09:49:24 rik
* Added debug tracking output for cancel irps.
*
* Revision 1.30 1994/08/18 14:08:19 rik
* Added support for doing FAST RAS reads. Basically, if I get this special
* ioctl, I ignore EV_ERR requests for the port.
*
* Revision 1.29 1994/08/03 23:31:18 rik
* Added entries in device extension to optimize RXCHAR and RXFLAG
* notification.
*
* Keep track of requested queue sizes and Xon/Xoff limits.
*
* Revision 1.28 1994/07/31 14:33:21 rik
* Added support for 1.5 stop bits.
*
* Added/updated debugging levels and debug logging.
*
* Revision 1.27 1994/03/16 14:33:15 rik
* Added entries to device extensions to support flushing better.
*
* Revision 1.26 1994/02/23 03:44:46 rik
* Changed so the controllers firmware can be downloaded from a binary file.
* This releases some physical memory was just wasted previously.
*
* Also updated so when compiling with a Windows NT OS and tools release greater
* than 528, then pagable code is compiled into the driver. This greatly
* reduced the size of in memory code, especially the hardware specific
* miniports.
*
* Revision 1.25 1993/12/03 13:11:23 rik
* Updated to allow logging across modules.
*
* Revision 1.24 1993/09/01 11:02:44 rik
* Ported code over to use READ/WRITE_REGISTER functions for accessing
* memory mapped data. This is required to support computers which don't run
* in 32bit mode, such as the DEC Alpha which runs in 64 bit mode.
*
* Revision 1.23 1993/08/27 09:37:25 rik
* Added support for the FEP5 Events RECEIVE_BUFFER_OVERRUN and
* UART_RECEIVE_OVERRUN. There previously weren't being handled.
*
* Revision 1.22 1993/08/25 17:42:56 rik
* Added support for Microchannel controllers.
* - Added a few more entries to the controller object
* - Added a parameter to the XXPrepInit functions.
*
* Revision 1.21 1993/07/03 09:29:46 rik
* Added simple fix for LSMRT ioctl missing modem status changes.
*
* Made a debugging and non-debugging version of the DigiRtlMoveMemory #define.
*
* Revision 1.20 1993/06/25 09:24:46 rik
* Added better support for the Ioctl LSRMT. It should be more accurate
* with regard to Line Status and Modem Status information with regard
* to the actual data being received.
*
* Revision 1.19 1993/06/06 14:08:36 rik
* Added new ErrorWord entry to the Device Extension struct to better support
* error reporting.
*
* Deleted obsolete code which was commented out.
*
* Revision 1.18 1993/05/20 16:13:42 rik
* Added bitmask's for modem status register, and line status register.
* Updated memory copy macro to account for unaligned moves.
* Added BusType and BusNumber to the Controller extensions.
* Deleted out old commented out stuff for clarity.
*
* Revision 1.17 1993/05/18 05:14:30 rik
* Fixed some complier errors/warnings I got when making checked and free
* versions of the drivers for both i386 and Mips.
*
* Changed the DigiRtlMovelMemory macro to use the UNALIGNED statement. This
* should fix align problems on the Mips.
*
* Revision 1.16 1993/05/09 09:24:40 rik
* Added More debugging defines.
*
* Added structures to support new configuration.
*
* Don't use the ObjectDirectory and DeviceName in the Device Extensions
* any longer.
*
* Added entries in the controller object to help support the new registry
* configuration.
*
* Added macros for tracking controller windowing.
*
* Revision 1.15 1993/04/05 19:03:35 rik
* Added a parameter to the XXInit function call. I now pass in a pointer
* to the registrypath given in the DIGIFEP5.SYS driver.
*
* Revision 1.14 1993/03/15 05:46:44 rik
* Changed to supporte calling miniport drivers. This basically meant taking
* the prototypes for the hardware specific modules and making them into
* defines so I didn't have to go and change all the FEP5 drivers code to
* new names.
*
* Revision 1.13 1993/03/10 06:46:12 rik
* Changed so I can compile out the memprint stuff if required.
*
* Revision 1.12 1993/03/08 07:20:55 rik
* Added new debugging levels. Added support for sending debugging output
* to a log file instead of the debugger.
*
* Revision 1.11 1993/03/01 16:03:09 rik
* Added defines for keeping track of what kind of controller is being used.
*
* Revision 1.10 1993/02/26 21:17:35 rik
* Added 2 new entries into the device extension. The first is a byte for
* keeping track of the state of a device, with regards to being open, close,
* etc... The second keeps track of what events have occured. This was
* required because I found out that I need to start tracking events from the
* time I receive a SET_WAIT_MASK, and not from WAIT_ON_MASK.
*
* Revision 1.9 1993/02/25 19:17:45 rik
* Expanded the baud rate table by adding 28800 into the table.
* Created a macro which will move memory from one location to another. This
* macro should be used to move data to/from the host computer from/to the
* DigiBoard controller because of problems using RtlMoveMemory with
* memory mapped devices.
* Added more debugging macros.
*
* Revision 1.8 1993/02/04 12:24:38 rik
* ??
*
* Revision 1.7 1993/01/22 12:44:52 rik
* *** empty log message ***
*
* Revision 1.6 1992/12/10 16:20:41 rik
* Added more device extensions to allow support of various IOCTLs, including
* wait on events and reporting various information if requested.
*
* Revision 1.5 1992/11/12 12:52:19 rik
* Added more spin-locks, DPC queues, timers and other various pieces of
* information into the device extensions.
*
* Revision 1.4 1992/10/28 21:50:18 rik
* Added support for reading data from the controller. Also added support
* for baud rates, parity, and other settings sometime here or before.
*
* Revision 1.3 1992/10/19 11:27:55 rik
* Added more information for better support of writing to the controllers
* tx buffer, along with the command queue.
*
--*/
#ifndef _NTFEP5_DOT_H
# define _NTFEP5_DOT_H
static char RCSInfo_NTFep5Doth[] = "$Header: s:/win/nt/fep5/rcs/ntfep5.h 1.33.2.8 1995/11/28 12:56:30 dirkh Exp $";
#endif
#define DIGIDIAG1 ((ULONG)0x00000001)
#define DIGIFLUSHIRP ((ULONG)0x00000002)
#define DIGICANCELIRP ((ULONG)0x00000004)
#define DIGIRXTRACE ((ULONG)0x00000008)
#define DIGITXTRACE ((ULONG)0x00000010)
#define DIGIINFO ((ULONG)0x00000020)
#define DIGIINIT ((ULONG)0x00000040)
#define DIGIIOCTL ((ULONG)0x00000080)
#define DIGIREAD ((ULONG)0x00000100)
#define DIGIWRITE ((ULONG)0x00000200)
#define DIGIUNLOAD ((ULONG)0x00000400)
#define DIGIWAIT ((ULONG)0x00000800)
#define DIGIREFERENCE ((ULONG)0x00001000)
#define DIGIEVENT ((ULONG)0x00002000)
#define DIGIMEMORY ((ULONG)0x00004000)
#define DIGICREATE ((ULONG)0x00008000)
#define DIGIFEPCMD ((ULONG)0x00010000)
#define DIGIFLOWCTRL ((ULONG)0x00020000)
#define DIGIIRP ((ULONG)0x00040000)
#define DIGIPORTNAME ((ULONG)0x00080000)
#define DIGIDPCFLOW ((ULONG)0x00100000)
#define DIGIWINDOWTRACK ((ULONG)0x00200000)
#define DIGIMODEM ((ULONG)0x00400000)
#define DIGISLOWREAD ((ULONG)0x00800000)
#define DIGICONC ((ULONG)0x01000000)
#define DIGIBAUD ((ULONG)0x02000000)
#define DIGIFLUSH ((ULONG)0x04000000)
#define DIGINOTIMPLEMENTED ((ULONG)0x08000000)
#define DIGIASSERT ((ULONG)0x10000000)
#define DIGIFLOW ((ULONG)0x20000000)
#define DIGIERRORS ((ULONG)0x40000000)
#define DIGIBUGCHECK ((ULONG)0x80000000)
extern ULONG DigiDebugLevel;
extern const PHYSICAL_ADDRESS DigiPhysicalZero;
#if DBG
// The following ASSERT works under free build kernels as well as checked.
// (The DDK ASSERT is a NOP under a free build kernel.)
#ifdef ASSERT
#undef ASSERT
#endif
#define ASSERT(expr) \
do { \
if(!(expr)) \
{ \
DbgPrint( "*** Failed assertion at " __FILE__ ":%d\n\t" #expr "\n", __LINE__ ); \
DbgBreakPoint(); \
} \
} while(0)
#define DigiDump(LEVEL,STRING) \
do { \
if( DigiDebugLevel & (LEVEL) ) \
{ \
DbgPrint STRING; \
} \
if( (LEVEL) & DIGIBUGCHECK ) \
{ \
ASSERT(FALSE); \
} \
} while (0)
#else // DBG
#define DigiDump(LEVEL,STRING) do {NOTHING;} while (0)
#endif // DBG
extern int IoAllocateCnt;
//****************************************************************************
//
// Defines
//
//****************************************************************************
//
// NT related definitions
//
#define SERIAL_COMPLETE_READ_COMPLETE (STATUS_PENDING + 1)
#define SERIAL_COMPLETE_READ_CANCEL (STATUS_PENDING + 2)
#define SERIAL_COMPLETE_READ_TOTAL (STATUS_PENDING + 3)
#define SERIAL_COMPLETE_READ_PROCESSING (STATUS_PENDING + 4)
#define MCA_BASE_POS_IO_PORT 0x96
#define MCA_INFO_POS_IO_PORT 0x100
#define MAKEWORD(a, b) ((USHORT)(((UCHAR)(a)) | ((USHORT)((UCHAR)(b))) << 8))
//
// NTDeviceIoControlFile IoControlCode values special for DigiBoard.
//
#define IOCTL_DIGI_SPECIAL CTL_CODE(FILE_DEVICE_SERIAL_PORT,2048,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_FAST_RAS CTL_CODE(FILE_DEVICE_SERIAL_PORT,4000,METHOD_BUFFERED,FILE_ANY_ACCESS)
#ifndef IOCTL_SERIAL_GET_STATS
#define IOCTL_SERIAL_GET_STATS CTL_CODE(FILE_DEVICE_SERIAL_PORT,35,METHOD_BUFFERED,FILE_ANY_ACCESS)
#endif
#ifndef IOCTL_SERIAL_CLEAR_STATS
#define IOCTL_SERIAL_CLEAR_STATS CTL_CODE(FILE_DEVICE_SERIAL_PORT,36,METHOD_BUFFERED,FILE_ANY_ACCESS)
#endif
#define IOCTL_DIGI_GET_CONTROLLER_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DIGI_GET_PORT_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DIGI_GET_CONTROLLER_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2051, METHOD_BUFFERED, FILE_ANY_ACCESS)
//
// FEP related definitions
//
// FEP Global data area offsets. These should be relative to the window
// they exist in.
#define FEP_NBUF 0x0C1A // KBytes of Buffers Allocated
#define FEP_NPORT 0x0C22 // # of Asynch. Channels
#define FEP_CONFIG 0x0CD0 // Start of C/X config string
#define FEP_DLREQ 0x0D00 // C/X Download request pointer
#define FEP_CIN 0x0D10 // Command IN pointer
#define FEP_COUT 0x0D12 // Command OUT pointer
#define FEP_CSTART 0x0D14 // Start of Command Queue
#define FEP_CMAX 0x0D16 // End of Command Queue
#define FEP_EIN 0x0D18 // Event IN pointer
#define FEP_EOUT 0x0D1A // Event OUT pointer
#define FEP_ISTART 0x0D1C // Start of Event Queue
#define FEP_IMAX 0x0D1E // End of Event Queue
#define FEP_FEPSTAT 0x0D20 // Startup confirm 'OS' address
#define FEP_FARCALL 0x0D24 // Call/Slice address offset
#define FEP_MCXI 0x0D40 // MC/Xi board
#define FEP_INTERVAL 0x0E04 // Interval between interrupts
#define FEP_CHANNEL_START 0x1000 // Relative offset of start of channel
// data structures
#define FEP_FEPSTAT_OK ((unsigned short)'SO')
//
// FEP Command Queue functions
//
// We OR 0xE0 with the values given so the command #'s will be out
// of range compared with possible channel numbers. This was done
// to support more channels per controller.
//
#define SET_RCV_LOW 0xE0
#define SET_RCV_HIGH 0xE1
#define FLUSH_TX 0xE2
#define PAUSE_TX 0xE3
#define RESUME_TX 0xE4
#define SET_AUX_CHARACTERS 0xE6
#define SEND_BREAK 0xE8
#define SET_MODEM_LINES 0xE9
#define SET_IFLAGS 0xEA
#define SET_XON_XOFF_CHARACTERS 0xEB
#define SET_TX_LOW 0xEC
#define CALL_ARBITRARY_ADDRESS 0xED
#define PAUSE_RECEIVE 0xEE
#define RESUME_RECEIVE 0xEF
#define RESET_CHANNEL 0xF0
#define SET_TIC_TIM 0xF1
#define SET_BUFFER_SPACE 0xF2
#define SET_OFLAGS 0xF3
#define SET_HDW_FLOW_CONTROL 0xF4
#define SET_CFLAGS 0xF5
#define SET_VNEXT_CHAR 0xF6
#define SET_BACKGROUND_TSLICE 0xF7
#define INVALID_COMMAND 0xFF
//
// FEP Event Queue Flags
//
#define FEP_EV_BREAK 0x01
#define FEP_TX_LOW 0x02
#define FEP_TX_EMPTY 0x04
#define FEP_RX_PRESENT 0x08
#define FEP_MODEM_CHANGE_SIGNAL 0x20
#define FEP_RECEIVE_BUFFER_OVERRUN 0x40
#define FEP_UART_RECEIVE_OVERRUN 0x80
#define FEP_ALL_EVENT_FLAGS ( FEP_MODEM_CHANGE_SIGNAL | \
FEP_RX_PRESENT | \
FEP_TX_EMPTY | \
FEP_TX_LOW | \
FEP_EV_BREAK | \
FEP_RECEIVE_BUFFER_OVERRUN | \
FEP_UART_RECEIVE_OVERRUN )
//
// FEP CFlags
//
// Bit Masks for the different settings of CFlags
#define CFLAG_BAUD_MASK 0xFBF0
#define CFLAG_LENGTH 0xFFCF
#define CFLAG_STOP_BIT 0xFFBF
#define CFLAG_PARITY 0xFCFF
// Character size
#define FEP_CS5 0x0000
#define FEP_CS6 0x0010
#define FEP_CS7 0x0020
#define FEP_CS8 0x0030
// Stop Bit
#define FEP_CSTOPB 0x0040
#define FEP_STOP_BIT_1 0x0000
#define FEP_STOP_BIT_2 FEP_CSTOPB
// #define FEP_STOP_BIT_1POINT5 0x0080 // DH no such thing
// Parity
#define FEP_PARENB 0x0100
#define FEP_PARODD 0x0200
#define FEP_NO_PARITY 0x0000
#define FEP_ODD_PARITY (FEP_PARENB | FEP_PARODD)
#define FEP_EVEN_PARITY FEP_PARENB
//
// FEP IFlags
//
// Bit Masks for the different setting of IFlags
#define IFLAG_IGNBRK 0x0001 // Ignore BREAK
#define IFLAG_BRKINT 0x0002 // Interrupt on BREAK
#define IFLAG_IGNPAR 0x0004 // Ignore parity errors
#define IFLAG_PARMRK 0x0008 // Mark parity errors
#define IFLAG_INPCK 0x0010 // Input parity check
#define IFLAG_ISTRIP 0x0020 // Stript input characters
#define IFLAG_ITOSS 0x0040 // Toss IXANY characters
#define IFLAG_IXON 0x0400 // Enable start/stop output
#define IFLAG_IXANY 0x0800 // Restart output on any char
#define IFLAG_IXOFF 0x1000 // Enable start/stop input
#define IFLAG_IXONA 0x2000 // Enable start/stop output Auxillary
#define IFLAG_DOSMODE 0x8000 // Enable 16450 error reporting
//
// Break related values
//
#define INFINITE_FEP_BREAK 0xFFFF
#define DEFAULT_FEP_BREAK 2 // in TICS
//
// This define gives the default Object directory
// that we should use to insert the symbolic links
// between the NT device name and namespace used by
// that object directory.
#define DEFAULT_DIRECTORY L"DosDevices"
#define DEFAULT_DIRECTORY_PATH L"\\DosDevices\\"
//
// 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_SUFFIX1 L"DigiBoard"
#define DEFAULT_NT_SUFFIX2 L"Port"
#define DEFAULT_DIGI_DEVICEMAP L"DigiBoard"
#define DEFAULT_NT_DEVICEMAP L"SERIALCOMM"
#define DEFAULT_XON_CHAR 0x11
#define DEFAULT_XOFF_CHAR 0x13
//****************************************************************************
//
// Typedefs & structs
//
//****************************************************************************
// Indeces into the ModemSignalTable in the controller extension.
typedef enum _SERIAL_SIGNALS_
{
DTR_SIGNAL = 0,
RTS_SIGNAL,
RES1_SIGNAL,
RES2_SIGNAL,
CTS_SIGNAL,
DSR_SIGNAL,
RI_SIGNAL,
DCD_SIGNAL,
NUMBER_OF_SIGNALS
} SERIAL_SIGNALS;
// Indeces into the BaudTable in the controller extension.
typedef enum _SERIAL_BAUD_RATES
{
SerialBaud50,
SerialBaud75,
SerialBaud110,
SerialBaud135_5,
SerialBaud150,
SerialBaud200,
SerialBaud300,
SerialBaud600,
SerialBaud1200,
SerialBaud1800,
SerialBaud2000,
SerialBaud2400,
SerialBaud3600,
SerialBaud4800,
SerialBaud7200,
SerialBaud9600,
SerialBaud14400,
SerialBaud19200,
SerialBaud28800,
SerialBaud38400,
SerialBaud56000,
SerialBaud57600,
SerialBaud115200,
SerialBaud128000,
SerialBaud256000,
SerialBaud512000,
NUMBER_OF_BAUD_RATES
} SERIAL_BAUD_RATES;
typedef struct _DIGI_XFLAG
{
USHORT Mask;
USHORT Src;
UCHAR Command;
} DIGI_XFLAG, *PDIGI_XFLAG;
typedef struct _FEPOS5_ADDRESS_
{
USHORT Window; // Window # on controller.
USHORT Offset; // Offset within window to address.
} FEPOS5_ADDRESS, *PFEPOS5_ADDRESS;
typedef struct _COMMAND_STRUCT_
{
USHORT cmHead;
USHORT cmTail;
USHORT cmStart;
USHORT cmMax;
} COMMAND_STRUCT, *PCOMMAND_STRUCT;
typedef struct _FEP_COMMAND_
{
UCHAR Command;
UCHAR Port;
USHORT Word;
} FEP_COMMAND, *PFEP_COMMAND;
typedef struct _FEP_EVENT_
{
UCHAR Channel;
UCHAR Flags;
UCHAR CurrentModem;
UCHAR PreviousModem;
} FEP_EVENT, *PFEP_EVENT;
typedef struct _FEP_CHANNEL_STRUCTURE_
{
USHORT tpjmp; // Transmit poll state jump address
USHORT tcjmp; // Transmit procedure jump address
USHORT NotUsed1; // Not used
USHORT ppjmp; // Receive poll state jump address
USHORT tseg; // Transmit segment (80186 segment)
USHORT tin; // Transmit in point (data in)
USHORT tout; // Transmit out pointer (data out)
USHORT tmax; // Transmit pointer max (size-1)
USHORT rseg; // Receive segment (80186 segment)
USHORT rin; // Recieve in pointer (data in)
USHORT rout; // Receive out pointer (data out)
USHORT rmax; // Receive pointer max (size-1)
USHORT tlow; // Transmit buffer low-water level
USHORT rlow; // Receive buffer low-water level
USHORT rhigh; // Recieve buffer high-water level
USHORT incr; // Increment to next channel
USHORT dev; // Uart device address
USHORT edelay; // Receive Event Delay
USHORT blen; // Transmit break len in 10microsec units
USHORT btime; // Transmit break timer
USHORT iflag; // UNIX-style input flags
USHORT oflag; // UNIX-style output flags
USHORT cflag; // UNIX-styel control flags
USHORT gmask; // Ring indicator mask
USHORT col; // Cooked mode column number
USHORT delay; // Cooked mode delay temp
USHORT imask; // Input character mask
USHORT tflush; // transmit buffer flush point
USHORT resv1[8]; // Reserved
UCHAR num; // Channel number
UCHAR ract; // Receive active counter
UCHAR bstat; // Break status flags
UCHAR tbusy; // Transmitter busy
UCHAR iempty; // Enable transmit empty event
UCHAR ilow; // Enable transmit low water event
UCHAR idata; // Enable receive data event
UCHAR eflag; // Host event flag
UCHAR tflag; // Transmit flags
UCHAR rflag; // Receive flags
UCHAR xmask; // Transmit ready mask
UCHAR xval; // Transmit read value
UCHAR mstat; // Current modem status
UCHAR mchange; // Recent modem changes
UCHAR mint; // Modem signals which cause events
UCHAR lstat; // Last prev different modem status
UCHAR mtran; // Saved modem transitions
UCHAR orun; // Receive buffer overflow occurred
UCHAR startca; // XON start character, Auxillary
UCHAR stopca; // XOFF stop character, Auxillary
UCHAR startc; // XON start character
UCHAR stopc; // XOFF stop character
UCHAR vnext; // VNEXT escape character
UCHAR hflow; // Hardware flow control options
UCHAR fillc; // Padding character
UCHAR ochar; // Saved character to output
UCHAR omask; // Output character mask
UCHAR resv2[29]; // Reserved
} FEP_CHANNEL_STRUCTURE, *PFEP_CHANNEL_STRUCTURE;
#define FEP_CHANNEL_STRUCT_SIZE sizeof( FEP_CHANNEL_STRUCTURE )
//
// These masks define access to the line status register. The line
// status register contains information about the status of data
// transfer. The first five bits deal with receive data and the
// last two bits deal with transmission. An interrupt is generated
// whenever bits 1 through 4 in this register are set.
//
//
// This bit is the data ready indicator. It is set to indicate that
// a complete character has been received. This bit is cleared whenever
// the receive buffer register has been read.
//
#define SERIAL_LSR_DR 0x01
//
// This is the overrun indicator. It is set to indicate that the receive
// buffer register was not read befor a new character was transferred
// into the buffer. This bit is cleared when this register is read.
//
#define SERIAL_LSR_OE 0x02
//
// This is the parity error indicator. It is set whenever the hardware
// detects that the incoming serial data unit does not have the correct
// parity as defined by the parity select in the line control register.
// This bit is cleared by reading this register.
//
#define SERIAL_LSR_PE 0x04
//
// This is the framing error indicator. It is set whenever the hardware
// detects that the incoming serial data unit does not have a valid
// stop bit. This bit is cleared by reading this register.
//
#define SERIAL_LSR_FE 0x08
//
// This is the break interrupt indicator. It is set whenever the data
// line is held to logic 0 for more than the amount of time it takes
// to send one serial data unit. This bit is cleared whenever the
// this register is read.
//
#define SERIAL_LSR_BI 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
//
// These masks are used to access the modem status register.
// Whenever one of the first four bits in the modem status
// register changes state a modem status interrupt is generated.
//
//
// This bit is the delta clear to send. It is used to indicate
// that the clear to send bit (in this register) has *changed*
// since this register was last read by the CPU.
//
#define SERIAL_MSR_DCTS 0x01
//
// This bit is the delta data set ready. It is used to indicate
// that the data set ready bit (in this register) has *changed*
// since this register was last read by the CPU.
//
#define SERIAL_MSR_DDSR 0x02
//
// This is the trailing edge ring indicator. It is used to indicate
// that the ring indicator input has changed from a low to high state.
//
#define SERIAL_MSR_TERI 0x04
//
// This bit is the delta data carrier detect. It is used to indicate
// that the data carrier bit (in this register) has *changed*
// since this register was last read by the CPU.
//
#define SERIAL_MSR_DDCD 0x08
//
// This bit contains the (complemented) state of the clear to send
// (CTS) line.
//
#define SERIAL_MSR_CTS 0x10
//
// This bit contains the (complemented) state of the data set ready
// (DSR) line.
//
#define SERIAL_MSR_DSR 0x20
//
// This bit contains the (complemented) state of the ring indicator
// (RI) line.
//
#define SERIAL_MSR_RI 0x40
//
// This bit contains the (complemented) state of the data carrier detect
// (DCD) line.
//
#define SERIAL_MSR_DCD 0x80
//
// Config Structure used during initialization
//
typedef struct _DIGI_CONFIG_INFO
{
//
// Symbolic link name that is used to access the port
//
UNICODE_STRING SymbolicLinkName;
//
// The device name assigned in the NT name space.
//
UNICODE_STRING NtNameForPort;
//
// Used to keep track of the different config info structures.
//
LIST_ENTRY ListEntry;
} DIGI_CONFIG_INFO, *PDIGI_CONFIG_INFO;
//
// The following macros define what state the device or controller can be in
// at any given time.
//
#define DIGI_DEVICE_STATE_CREATED 0
#define DIGI_DEVICE_STATE_INITIALIZED 1
#define DIGI_DEVICE_STATE_OPEN 2
#define DIGI_DEVICE_STATE_CLOSED 3
#define DIGI_DEVICE_STATE_UNLOADING 4
#define DIGI_DEVICE_STATE_CLEANUP 5
//
// Special flags
//
#define DIGI_SPECIAL_FLAG_FAST_RAS 0x00000001
//
// The following defines are used to determine what kind of controller
// is being used for any given controller extension.
//
// To distinguish between different controllers which can have memory
// enabled at both base and base + 1, we reserve the high bit to indicate
// which. e.g. a PC/2e would be 0x00000001, while an old PC/8e would
// be 0x80000001
//
#define BASE_ENABLE_MEMORY 0x80000000
#define CONTROLLER_TYPE_PCXE 0x00000001
#define CONTROLLER_TYPE_PCXI 0x00000002
#define CONTROLLER_TYPE_CX 0x00000004
#define CONTROLLER_TYPE_MC2XI 0x00000008
/*
** Structures for returning performance data.
*/
typedef struct
{
ULONG OpenPorts;
ULONG OpenRequests;
ULONG CloseRequests;
ULONG ReadRequests;
ULONG WriteRequests;
ULONG IoctlRequests;
ULONG BytesRead;
ULONG BytesWritten;
} CONTROLLER_PERF_DATA;
typedef struct
{
ULONG ReadRequests;
ULONG WriteRequests;
ULONG IoctlRequests;
ULONG BytesRead;
ULONG BytesWritten;
ULONG SendBufferSize;
ULONG BytesInSendBuffer;
ULONG ParityErrorCount;
ULONG FrameErrorCount;
ULONG BufferOverrunErrorCount;
ULONG SerialOverrunErrorCount;
} PORT_PERF_DATA;
typedef struct
{
ULONG State;
ULONG Type;
ULONG NumberOfPorts;
} CONTROLLER_DATA;
#if 0
#ifndef SERIALPERF_STATS
typedef struct _SERIALPERF_STATS {
ULONG ReceivedCount;
ULONG TransmittedCount;
ULONG FrameErrorCount;
ULONG SerialOverrunErrorCount;
ULONG BufferOverrunErrorCount;
ULONG ParityErrorCount;
} SERIALPERF_STATS, *PSERIALPERF_STATS;
#endif
#endif
//
// Define empty typedefs for the _DIGI_CONTROLLER_EXTENSION
// structures so they may be referenced by function types before they are
// actually defined.
//
struct _DIGI_CONTROLLER_EXTENSION;
typedef NTSTATUS (*PDIGI_XXPREPINIT)(
IN struct _DIGI_CONTROLLER_EXTENSION *ControllerExt,
IN PUNICODE_STRING ControllerPath );
typedef NTSTATUS (*PDIGI_XXINIT)(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING ControllerPath,
IN struct _DIGI_CONTROLLER_EXTENSION *ControllerExt );
typedef VOID (*PDIGI_XXDOWNLOAD)(
IN struct _DIGI_CONTROLLER_EXTENSION *ControllerExt );
typedef VOID (*PDIGI_ENABLEWINDOW)(
IN struct _DIGI_CONTROLLER_EXTENSION *ControllerExt,
IN USHORT Window );
typedef VOID (*PDIGI_DISABLEWINDOW)(
IN struct _DIGI_CONTROLLER_EXTENSION *ControllerExt );
typedef NTSTATUS (*PDIGI_BOARD2FEP5ADDRESS)(
IN struct _DIGI_CONTROLLER_EXTENSION *ControllerExt,
IN USHORT ControllerAddress,
IN PFEPOS5_ADDRESS FepAddress );
typedef LARGE_INTEGER (*PDIGI_DIAGNOSE)(
IN struct _DIGI_CONTROLLER_EXTENSION *ControllerExt);
typedef struct _DIGI_MINIPORT_ENTRY_POINTS
{
PDIGI_XXPREPINIT XXPrepInit;
PDIGI_XXINIT XXInit;
PDIGI_ENABLEWINDOW EnableWindow;
PDIGI_DISABLEWINDOW DisableWindow;
PDIGI_XXDOWNLOAD XXDownload;
PDIGI_BOARD2FEP5ADDRESS Board2Fep5Address;
PDIGI_DIAGNOSE Diagnose;
} DIGI_MINIPORT_ENTRY_POINTS, *PDIGI_MINIPORT_ENTRY_POINTS;
typedef struct _DIGI_MEMORY_ACCESS
{
KSPIN_LOCK Lock;
KIRQL OldIrql;
#if DBG
BOOLEAN LockBusy;
ULONG LockContention;
#endif
} DIGI_MEMORY_ACCESS, *PDIGI_MEMORY_ACCESS;
typedef struct _DIGI_CONTROLLER_EXTENSION
{
//
// Space for naming our Controller.
// Note: This is placed at the beginning of the structure
// for easy debugging identification.
//
WCHAR ControllerNameString[64];
UNICODE_STRING ControllerName;
// NT specific information to keep track of things.
PCONTROLLER_OBJECT ControllerObject; // pointer to this ctrl'er object
PDRIVER_OBJECT DriverObject;
// link the extensions together
struct _DIGI_CONTROLLER_EXTENSION *NextControllerExtension;
PDEVICE_OBJECT HeadDeviceObject; // ptr to head of Device Objects
KDPC PollDpc;
KTIMER PollTimer;
LARGE_INTEGER PollTimerLength;
//
// Keep track of where the Bios and FEP image paths are.
//
UNICODE_STRING BiosImagePath;
UNICODE_STRING FEPImagePath;
//
// Keep track of what state the controller is currently in.
//
ULONG ControllerState;
//
// This lock is used to protect accessing controller memory. Since
// DigiBoards controllers can use the same memory address, we need
// to make sure only one controller is turned on at one time.
//
PDIGI_MEMORY_ACCESS MemoryAccess;
// Control access to this controller extension.
KSPIN_LOCK ControlAccess;
// Controller specific information
// The following is provided by the FEP driver during initialization.
ULONG ControllerType; // What kind of controller??
PHYSICAL_ADDRESS PhysicalMemoryAddress;// physical memory address
PHYSICAL_ADDRESS PhysicalIOPort; // phyical IO port address
ULONG nCount; // # of devices on this controller
ULONG IOSpan; // # of IO ports to map
PUCHAR VirtualAddress; // virtual memory base address
PUCHAR VirtualIO; // virtual IO base
BOOLEAN UnMapVirtualAddress;
BOOLEAN UnMapVirtualIO;
BOOLEAN DoubleIO; // This is to fix some systems that reorder PCI/EISA accesses
BOOLEAN ShortRasTimeout; // This is for folks trying to use BitSURFR with Xem on a RAS server
INTERFACE_TYPE BusType;
ULONG BusNumber;
ULONG WindowSize; // Size of the Window on this ctrl'er
// Some error information
ULONG WindowFailureCount;
LARGE_INTEGER LastErrorLogTime;
//
// If we are running on an MCA bus, then we will use the following
// entries for access the POS information.
//
PHYSICAL_ADDRESS PhysicalPOSBasePort; // physical I/O address for
// turning on the POS registers
PHYSICAL_ADDRESS PhysicalPOSInfoPort; // physical I/O address for
// retrieving POS information.
PUCHAR VirtualPOSBaseAddress; // Virtual address
PUCHAR VirtualPOSInfoAddress; // Virtual address
BOOLEAN UnMapVirtualPOSBaseAddress;
BOOLEAN UnMapVirtualPOSInfoAddress;
// The following are the structures which should be filled out by the
// individual controller modules during initialization.
//
// A Configuration list used during initialization. The NT name
// space name and DosDevices name are included.
//
LIST_ENTRY ConfigList;
// Total number of ports determined to be on this controller
LONG NumberOfPorts;
// Global data area on the controller.
FEPOS5_ADDRESS Global;
// Event Queue data area on the controller.
FEPOS5_ADDRESS EventQueue;
// Command Queue data area on the controller.
FEPOS5_ADDRESS CommandQueue;
// Baud Table to indicate what baud rates are supported.
const SHORT *BaudTable;
//
// This table's values express the bit value for each modem signal
// because modem signal bits vary by hardware.
//
const UCHAR *ModemSignalTable;
//
// MiniportDeviceObject is a pointer to the hardware dependent device object.
// It is used to communicate with the hardware dependent drivers, when
// it is appropriate.
//
PDEVICE_OBJECT MiniportDeviceObject;
PFILE_OBJECT MiniportFileObject;
//
// Points to the name of the device of the miniport associated with
// this controller object.
//
UNICODE_STRING MiniportDeviceName;
//
// This structure is passed into each miniport driver where it will
// place the appropriate entry points into the structure for
// use by the FEP5 driver.
//
DIGI_MINIPORT_ENTRY_POINTS EntryPoints;
PDEVICE_OBJECT *DeviceObjectArray;
//
// We need a device object particular to the controller, so that it
// can receive IOCTLs from user apps (perfmon)
//
PDEVICE_OBJECT ControllerDeviceObject;
KSPIN_LOCK PerfLock;
CONTROLLER_PERF_DATA PerfData;
} DIGI_CONTROLLER_EXTENSION, *PDIGI_CONTROLLER_EXTENSION;
typedef struct _DIGI_DEVICE_EXTENSION
{
#if DBG
//
// Debugging string to help Identify our Device Object
//
WCHAR DeviceDbgString[81];
UNICODE_STRING DeviceDbg;
#endif
//
// Keep track of the state of the device at any given time.
//
ULONG DeviceState;
//
// The Controller Extension for this device.
//
PDIGI_CONTROLLER_EXTENSION ParentControllerExt;
//
// A linked list of Device Objects for this devices ParentControllerExt.
// This needs to be separate from the Driver Objects linked list.
//
PDEVICE_OBJECT NextDeviceObject;
//
// This points to the device name for this device
// sans device prefix.
//
UNICODE_STRING NtNameForPort;
//
// This points to the symbolic link name that will be
// linked to the actual nt device name.
//
UNICODE_STRING SymbolicLinkName;
// Control access to this device extension.
KSPIN_LOCK ControlAccess;
// To prevent new irps at the wrong time.
KSPIN_LOCK NewIrpLock;
// Transmit buffer information regarding this device.
FEPOS5_ADDRESS TxSeg;
// Receive buffer information regarding this device.
FEPOS5_ADDRESS RxSeg;
// This device's Channel Data structure
FEPOS5_ADDRESS ChannelInfo;
//
// This device's channel number associated with ParentControllerExt.
//
ULONG ChannelNumber;
//
// This list head is used to contain the time ordered list
// of write requests. Access to this list is protected by
// the global cancel spinlock.
//
LIST_ENTRY WriteQueue;
//
// If the head of the WriteQueue is an IOCTL_SERIAL_XOFF_COUNTER,
// then this value will point to Irp->AssociatedIrp.SystemBuffer.
// Otherwise, the value will be NULL.
//
PSERIAL_XOFF_COUNTER pXoffCounter;
//
// XcPreview is the number of bytes we have decremented XcCounter when
// the ReadQueue is empty, but bytes are present in the receive buffer.
// This prevents us from counting read bytes twice...
//
USHORT XcPreview;
//
// ReceiveNotificationLimit is the number of bytes which need to be present
// in the receive buffer before we notify AsyncMac (RAS) via EV_RX80FULL.
// This number should be calculated so that we can avoid engaging flow control.
//
USHORT ReceiveNotificationLimit;
//
// This list head is used to contain the time ordered list
// of read requests. Access to this list is protected by
// the global cancel spinlock.
//
LIST_ENTRY ReadQueue;
//
// This list head is used to contain the time ordered list
// of set/wait event requests. Access to this list is protected by
// the global cancel spinlock.
//
LIST_ENTRY WaitQueue;
//
// This mask holds the bitmask sent down via the set mask ioctl. It is
// used to determine if the occurence of "events" should be noted.
//
ULONG WaitMask;
//
// This mask the bitmask of "events" which have occurred from
// the SET_WAIT_MASK to the actual WAIT_ON_MASK IRP.
//
ULONG HistoryWait;
//
// Holds the timeout controls for the device. This value
// is set by the Ioctl processing.
//
// It should only be accessed under protection of the control
// lock since more than one request can be in the control dispatch
// routine at one time.
//
SERIAL_TIMEOUTS Timeouts;
//
// This is the kernel timer structure used to handle
// total read request timing.
//
KTIMER ReadRequestTotalTimer;
KDPC TotalReadTimeoutDpc;
//
// This value is set by the read code to hold the delta time value
// used for read interval timing. We keep it in the extension
// so that the interval timer dpc routine can resubmit itself.
//
LARGE_INTEGER IntervalTime;
//
// This is the kernel timer structure used to handle
// interval read request timing.
//
// If no more characters have been read then the
// dpc routine will cause the read to complete. However, if
// more characters have been read then the dpc routine will
// resubmit the timer.
//
KTIMER ReadRequestIntervalTimer;
KDPC IntervalReadTimeoutDpc;
//
// This holds the system time when we last
// checked that we had actually read characters. Used
// for interval timing.
//
LARGE_INTEGER LastReadTime;
//
// This is the kernel timer structure used to handle
// total time request timing.
//
KTIMER WriteRequestTotalTimer;
KDPC TotalWriteTimeoutDpc;
//
// Timer for draining the transmit queue for FlushFileBuffers.
//
KTIMER FlushBuffersTimer;
KDPC FlushBuffersDpc;
//
// This is used to keep track of the state of the current Irp
// operation.
//
LONG ReadStatus;
ULONG PreviousReadCount;
//
// We keep track of the ControlHandShake, and FlowReplace values from
// the SERIAL_HANDFLOW structure because they need to be remembered
// across opens and closes.
//
ULONG ControlHandShake;
ULONG FlowReplace;
LONG XonLimit;
LONG XoffLimit;
//
// The application can turn on a mode,via the
// IOCTL_SERIAL_LSRMST_INSERT ioctl, that will cause the
// serial driver to insert the line status or the modem
// status into the RX stream. The parameter with the ioctl
// is a pointer to a UCHAR. If the value of the UCHAR is
// zero, then no insertion will ever take place. If the
// value of the UCHAR is non-zero (and not equal to the
// xon/xoff characters), then the serial driver will insert.
//
UCHAR EscapeChar;
//
// This holds the reasons that the driver thinks it is in
// an error state.
//
// This is only written from interrupt level.
//
ULONG ErrorWord;
//
// This keeps a total of the number of characters that
// are in all of the "write" irps that the driver knows
// about. It is only accessed with the device spinlock
// held.
//
ULONG TotalCharsQueued;
//
// A variable that in theory should always represent the current BEST
// value of the modem signals.
//
UCHAR CurrentModemSignals; // best current value of the modem signals
UCHAR WriteOnlyModemSignalMask; // These are the lines we have absolute
// control over
UCHAR WriteOnlyModemSignalValue; // This is what we told the port to set.
//
// This structure is used to set and retrieve the special characters
// used by the nt serial driver.
//
// Note that the driver will return an error if xonchar == xoffchar.
//
SERIAL_CHARS SpecialChars;
//
// This is a temporary hack to try an help make the LSRMST ioctl
// work a little better. If this driver ever does receive double
// buffering, this should be placed in that buffer.
//
ULONG PreviousMSRByte;
//
// Keep track of where the last character came in.
//
// This is used to help better support EV_RXCHAR
//
ULONG PreviousRxChar;
//
// Keep track of where the last special character was received.
//
// This is used to help better support EV_RXFLAG
//
ULONG UnscannedRXFLAGPosition;
//
// Keep track of the queue size requested
//
SERIAL_QUEUE_SIZE RequestedQSize;
// Last requested port speed
ULONG BaudRate;
//
// Special flags for various things
//
ULONG SpecialFlags;
//
// This device's COM port number
//
ULONG ComPort;
// Performance data variables
KSPIN_LOCK PerfLock;
PORT_PERF_DATA PerfData;
SERIALPERF_STATS SerialPerfStats;
} DIGI_DEVICE_EXTENSION, *PDIGI_DEVICE_EXTENSION;
#define IOCTL_DIGI_GET_ENTRY_POINTS CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x1000,METHOD_BUFFERED,FILE_ANY_ACCESS)
//****************************************************************************
//
// Prototypes
//
//****************************************************************************
#define XXPrepInit( ControllerExt, ControllerPath ) \
(ControllerExt)->EntryPoints.XXPrepInit( ControllerExt, ControllerPath )
#define XXInit( DriverObject, ControllerPath, ControllerExt ) \
(ControllerExt)->EntryPoints.XXInit( DriverObject, ControllerPath, ControllerExt )
#define EnableWindow( ControllerExt, Window ) \
do { \
DigiDump( DIGIWINDOWTRACK, ("Before EnableWindow (busy = %d) <%s:%d>\n", \
(ControllerExt)->MemoryAccess->LockBusy, __FILE__, __LINE__) ); \
(ControllerExt)->EntryPoints.EnableWindow( ControllerExt, Window ); \
DigiDump( DIGIWINDOWTRACK, ("After EnableWindow <%s:%d>\n", \
__FILE__, __LINE__) ); \
} while (0)
#define DisableWindow( ControllerExt ) \
do { \
DigiDump( DIGIWINDOWTRACK, ("Before DisableWindow <%s:%d>\n", \
__FILE__, __LINE__) ); \
(ControllerExt)->EntryPoints.DisableWindow( ControllerExt ); \
DigiDump( DIGIWINDOWTRACK, ("After DisableWindow (contention = %d) <%s:%d>\n", \
(ControllerExt)->MemoryAccess->LockContention, __FILE__, __LINE__) ); \
} while (0)
#define XXDownload( ControllerExt ) \
(ControllerExt)->EntryPoints.XXDownload( ControllerExt )
#define Board2Fep5Address( ControllerExt, ControllerAddress, FepAddress ) \
(ControllerExt)->EntryPoints.Board2Fep5Address( ControllerExt, \
ControllerAddress, \
FepAddress )
#define Diagnose( ControllerExt ) \
(ControllerExt)->EntryPoints.Diagnose( ControllerExt )
typedef enum _DIGI_MEM_COMPARES
{
AddressesAreEqual,
AddressesOverlap,
AddressesAreDisjoint
} DIGI_MEM_COMPARES,*PDIGI_MEM_COMPARES;