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