Annotation of ntddk/src/comm/serial/serial.h, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1990, 1991, 1992, 1993 Microsoft Corporation
                      4: 
                      5: Module Name :
                      6:        
                      7:     serial.h
                      8: 
                      9: Abstract:
                     10: 
                     11:     Type definitions and data for the serial port driver
                     12: 
                     13: Author:
                     14: 
                     15:     Anthony V. Ercolano                 April 8, 1991
                     16: 
                     17: Revision History:
                     18: --*/
                     19: 
                     20: 
                     21: 
                     22: 
                     23: #if DBG
                     24: #define SERDIAG1              ((ULONG)0x00000001)
                     25: #define SERDIAG2              ((ULONG)0x00000002)
                     26: #define SERDIAG3              ((ULONG)0x00000004)
                     27: #define SERDIAG4              ((ULONG)0x00000008)
                     28: #define SERDIAG5              ((ULONG)0x00000010)
                     29: #define SERIRPPATH            ((ULONG)0x00000020)
                     30: #define SERFLOW               ((ULONG)0x20000000)
                     31: #define SERERRORS             ((ULONG)0x40000000)
                     32: #define SERBUGCHECK           ((ULONG)0x80000000)
                     33: extern ULONG SerialDebugLevel;
                     34: #define SerialDump(LEVEL,STRING) \
                     35:         do { \
                     36:             ULONG _level = (LEVEL); \
                     37:             if (SerialDebugLevel & _level) { \
                     38:                 DbgPrint STRING; \
                     39:             } \
                     40:             if (_level == SERBUGCHECK) { \
                     41:                 ASSERT(FALSE); \
                     42:             } \
                     43:         } while (0)
                     44: #else
                     45: #define SerialDump(LEVEL,STRING) do {NOTHING;} while (0)
                     46: #endif
                     47: 
                     48: //
                     49: // This define gives the default Object directory
                     50: // that we should use to insert the symbolic links
                     51: // between the NT device name and namespace used by
                     52: // that object directory.
                     53: #define DEFAULT_DIRECTORY L"DosDevices"
                     54: 
                     55: //
                     56: // For the above directory, the serial port will
                     57: // use the following name as the suffix of the serial
                     58: // ports for that directory.  It will also append
                     59: // a number onto the end of the name.  That number
                     60: // will start at 1.
                     61: #define DEFAULT_SERIAL_NAME L"COM"
                     62: //
                     63: //
                     64: // This define gives the default NT name for
                     65: // for serial ports detected by the firmware.
                     66: // This name will be appended to Device prefix
                     67: // with a number following it.  The number is
                     68: // incremented each time encounter a serial
                     69: // port detected by the firmware.  Note that
                     70: // on a system with multiple busses, this means
                     71: // that the first port on a bus is not necessarily
                     72: // \Device\Serial0.
                     73: //
                     74: #define DEFAULT_NT_SUFFIX L"Serial"
                     75: 
                     76: //
                     77: // This value - which could be redefined at compile
                     78: // time, define the stride between registers
                     79: //
                     80: #if !defined(SERIAL_REGISTER_STRIDE)
                     81: #define SERIAL_REGISTER_STRIDE 1
                     82: #endif
                     83: 
                     84: //
                     85: // Offsets from the base register address of the
                     86: // various registers for the 8250 family of UARTS.
                     87: //
                     88: #define RECEIVE_BUFFER_REGISTER    ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
                     89: #define TRANSMIT_HOLDING_REGISTER  ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
                     90: #define INTERRUPT_ENABLE_REGISTER  ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
                     91: #define INTERRUPT_IDENT_REGISTER   ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
                     92: #define FIFO_CONTROL_REGISTER      ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
                     93: #define LINE_CONTROL_REGISTER      ((ULONG)((0x03)*SERIAL_REGISTER_STRIDE))
                     94: #define MODEM_CONTROL_REGISTER     ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
                     95: #define LINE_STATUS_REGISTER       ((ULONG)((0x05)*SERIAL_REGISTER_STRIDE))
                     96: #define MODEM_STATUS_REGISTER      ((ULONG)((0x06)*SERIAL_REGISTER_STRIDE))
                     97: #define DIVISOR_LATCH_LSB          ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
                     98: #define DIVISOR_LATCH_MSB          ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
                     99: #define SERIAL_REGISTER_SPAN       ((ULONG)(7*SERIAL_REGISTER_STRIDE))
                    100: 
                    101: //
                    102: // If we have an interrupt status register this is its assumed
                    103: // length.
                    104: //
                    105: #define SERIAL_STATUS_LENGTH       ((ULONG)(1*SERIAL_REGISTER_STRIDE))
                    106: 
                    107: //
                    108: // Bitmask definitions for accessing the 8250 device registers.
                    109: //
                    110: 
                    111: //
                    112: // These bits define the number of data bits trasmitted in
                    113: // the Serial Data Unit (SDU - Start,data, parity, and stop bits)
                    114: //
                    115: #define SERIAL_DATA_LENGTH_5 0x00
                    116: #define SERIAL_DATA_LENGTH_6 0x01
                    117: #define SERIAL_DATA_LENGTH_7 0x02
                    118: #define SERIAL_DATA_LENGTH_8 0x03
                    119: 
                    120: 
                    121: //
                    122: // These masks define the interrupts that can be enabled or disabled.
                    123: //
                    124: //
                    125: // This interrupt is used to notify that there is new incomming
                    126: // data available.  The SERIAL_RDA interrupt is enabled by this bit.
                    127: //
                    128: #define SERIAL_IER_RDA   0x01
                    129: 
                    130: //
                    131: // This interrupt is used to notify that there is space available
                    132: // in the transmitter for another character.  The SERIAL_THR
                    133: // interrupt is enabled by this bit.
                    134: //
                    135: #define SERIAL_IER_THR   0x02
                    136: 
                    137: //
                    138: // This interrupt is used to notify that some sort of error occured
                    139: // with the incomming data.  The SERIAL_RLS interrupt is enabled by
                    140: // this bit.
                    141: #define SERIAL_IER_RLS   0x04
                    142: 
                    143: //
                    144: // This interrupt is used to notify that some sort of change has
                    145: // taken place in the modem control line.  The SERIAL_MS interrupt is
                    146: // enabled by this bit.
                    147: //
                    148: #define SERIAL_IER_MS    0x08
                    149: 
                    150: 
                    151: //
                    152: // These masks define the values of the interrupt identification
                    153: // register.  The low bit must be clear in the interrupt identification
                    154: // register for any of these interrupts to be valid.  The interrupts
                    155: // are defined in priority order, with the highest value being most
                    156: // important.  See above for a description of what each interrupt
                    157: // implies.
                    158: //
                    159: #define SERIAL_IIR_RLS      0x06
                    160: #define SERIAL_IIR_RDA      0x04
                    161: #define SERIAL_IIR_CTI      0x0c
                    162: #define SERIAL_IIR_THR      0x02
                    163: #define SERIAL_IIR_MS       0x00
                    164: 
                    165: //
                    166: // This bit mask get the value of the high two bits of the
                    167: // interrupt id register.  If this is a 16550 class chip
                    168: // these bits will be a one if the fifo's are enbled, otherwise
                    169: // they will always be zero.
                    170: //
                    171: #define SERIAL_IIR_FIFOS_ENABLED 0xc0
                    172: 
                    173: //
                    174: // If the low bit is logic one in the interrupt identification register
                    175: // this implies that *NO* interrupts are pending on the device.
                    176: //
                    177: #define SERIAL_IIR_NO_INTERRUPT_PENDING 0x01
                    178: 
                    179: 
                    180: 
                    181: //
                    182: // These masks define access to the fifo control register.
                    183: //
                    184: 
                    185: //
                    186: // Enabling this bit in the fifo control register will turn
                    187: // on the fifos.  If the fifos are enabled then the high two
                    188: // bits of the interrupt id register will be set to one.  Note
                    189: // that this only occurs on a 16550 class chip.  If the high
                    190: // two bits in the interrupt id register are not one then
                    191: // we know we have a lower model chip.
                    192: //
                    193: //
                    194: #define SERIAL_FCR_ENABLE     ((UCHAR)0x01)
                    195: #define SERIAL_FCR_RCVR_RESET ((UCHAR)0x02)
                    196: #define SERIAL_FCR_TXMT_RESET ((UCHAR)0x04)
                    197: 
                    198: //
                    199: // This set of values define the high water marks (when the
                    200: // interrupts trip) for the receive fifo.
                    201: //
                    202: #define SERIAL_1_BYTE_HIGH_WATER   ((UCHAR)0x00)
                    203: #define SERIAL_4_BYTE_HIGH_WATER   ((UCHAR)0x40)
                    204: #define SERIAL_8_BYTE_HIGH_WATER   ((UCHAR)0x80)
                    205: #define SERIAL_14_BYTE_HIGH_WATER  ((UCHAR)0xc0)
                    206: 
                    207: //
                    208: // These masks define access to the line control register.
                    209: //
                    210: 
                    211: //
                    212: // This defines the bit used to control the definition of the "first"
                    213: // two registers for the 8250.  These registers are the input/output
                    214: // register and the interrupt enable register.  When the DLAB bit is
                    215: // enabled these registers become the least significant and most
                    216: // significant bytes of the divisor value.
                    217: //
                    218: #define SERIAL_LCR_DLAB     0x80
                    219: 
                    220: //
                    221: // This defines the bit used to control whether the device is sending
                    222: // a break.  When this bit is set the device is sending a space (logic 0).
                    223: //
                    224: // Most protocols will assume that this is a hangup.
                    225: //
                    226: #define SERIAL_LCR_BREAK    0x40
                    227: 
                    228: //
                    229: // These defines are used to set the line control register.
                    230: //
                    231: #define SERIAL_5_DATA       ((UCHAR)0x00)
                    232: #define SERIAL_6_DATA       ((UCHAR)0x01)
                    233: #define SERIAL_7_DATA       ((UCHAR)0x02)
                    234: #define SERIAL_8_DATA       ((UCHAR)0x03)
                    235: #define SERIAL_DATA_MASK    ((UCHAR)0x03)
                    236: 
                    237: #define SERIAL_1_STOP       ((UCHAR)0x00)
                    238: #define SERIAL_1_5_STOP     ((UCHAR)0x04) // Only valid for 5 data bits
                    239: #define SERIAL_2_STOP       ((UCHAR)0x04) // Not valid for 5 data bits
                    240: #define SERIAL_STOP_MASK    ((UCHAR)0x04)
                    241: 
                    242: #define SERIAL_NONE_PARITY  ((UCHAR)0x00)
                    243: #define SERIAL_ODD_PARITY   ((UCHAR)0x08)
                    244: #define SERIAL_EVEN_PARITY  ((UCHAR)0x18)
                    245: #define SERIAL_MARK_PARITY  ((UCHAR)0x28)
                    246: #define SERIAL_SPACE_PARITY ((UCHAR)0x38)
                    247: #define SERIAL_PARITY_MASK  ((UCHAR)0x38)
                    248: 
                    249: //
                    250: // These masks define access the modem control register.
                    251: //
                    252: 
                    253: //
                    254: // This bit controls the data terminal ready (DTR) line.  When
                    255: // this bit is set the line goes to logic 0 (which is then inverted
                    256: // by normal hardware).  This is normally used to indicate that
                    257: // the device is available to be used.  Some odd hardware
                    258: // protocols (like the kernel debugger) use this for handshaking
                    259: // purposes.
                    260: //
                    261: #define SERIAL_MCR_DTR      0x01
                    262: 
                    263: //
                    264: // This bit controls the ready to send (RTS) line.  When this bit
                    265: // is set the line goes to logic 0 (which is then inverted by the normal
                    266: // hardware).  This is used for hardware handshaking.  It indicates that
                    267: // the hardware is ready to send data and it is waiting for the
                    268: // receiving end to set clear to send (CTS).
                    269: //
                    270: #define SERIAL_MCR_RTS      0x02
                    271: 
                    272: //
                    273: // This bit is used for general purpose output.
                    274: //
                    275: #define SERIAL_MCR_OUT1     0x04
                    276: 
                    277: //
                    278: // This bit is used for general purpose output.
                    279: //
                    280: #define SERIAL_MCR_OUT2     0x08
                    281: 
                    282: //
                    283: // This bit controls the loopback testing mode of the device.  Basically
                    284: // the outputs are connected to the inputs (and vice versa).
                    285: //
                    286: #define SERIAL_MCR_LOOP     0x10
                    287: 
                    288: 
                    289: //
                    290: // These masks define access to the line status register.  The line
                    291: // status register contains information about the status of data
                    292: // transfer.  The first five bits deal with receive data and the
                    293: // last two bits deal with transmission.  An interrupt is generated
                    294: // whenever bits 1 through 4 in this register are set.
                    295: //
                    296: 
                    297: //
                    298: // This bit is the data ready indicator.  It is set to indicate that
                    299: // a complete character has been received.  This bit is cleared whenever
                    300: // the receive buffer register has been read.
                    301: //
                    302: #define SERIAL_LSR_DR       0x01
                    303: 
                    304: //
                    305: // This is the overrun indicator.  It is set to indicate that the receive
                    306: // buffer register was not read befor a new character was transferred
                    307: // into the buffer.  This bit is cleared when this register is read.
                    308: //
                    309: #define SERIAL_LSR_OE       0x02
                    310: 
                    311: //
                    312: // This is the parity error indicator.  It is set whenever the hardware
                    313: // detects that the incoming serial data unit does not have the correct
                    314: // parity as defined by the parity select in the line control register.
                    315: // This bit is cleared by reading this register.
                    316: //
                    317: #define SERIAL_LSR_PE       0x04
                    318: 
                    319: //
                    320: // This is the framing error indicator.  It is set whenever the hardware
                    321: // detects that the incoming serial data unit does not have a valid
                    322: // stop bit.  This bit is cleared by reading this register.
                    323: //
                    324: #define SERIAL_LSR_FE       0x08
                    325: 
                    326: //
                    327: // This is the break interrupt indicator.  It is set whenever the data
                    328: // line is held to logic 0 for more than the amount of time it takes
                    329: // to send one serial data unit.  This bit is cleared whenever the
                    330: // this register is read.
                    331: //
                    332: #define SERIAL_LSR_BI       0x10
                    333: 
                    334: //
                    335: // This is the transmit holding register empty indicator.  It is set
                    336: // to indicate that the hardware is ready to accept another character
                    337: // for transmission.  This bit is cleared whenever a character is
                    338: // written to the transmit holding register.
                    339: //
                    340: #define SERIAL_LSR_THRE     0x20
                    341: 
                    342: //
                    343: // This bit is the transmitter empty indicator.  It is set whenever the
                    344: // transmit holding buffer is empty and the transmit shift register
                    345: // (a non-software accessable register that is used to actually put
                    346: // the data out on the wire) is empty.  Basically this means that all
                    347: // data has been sent.  It is cleared whenever the transmit holding or
                    348: // the shift registers contain data.
                    349: //
                    350: #define SERIAL_LSR_TEMT     0x40
                    351: 
                    352: //
                    353: // This bit indicates that there is at least one error in the fifo.
                    354: // The bit will not be turned off until there are no more errors
                    355: // in the fifo.
                    356: //
                    357: #define SERIAL_LSR_FIFOERR  0x80
                    358: 
                    359: 
                    360: //
                    361: // These masks are used to access the modem status register.
                    362: // Whenever one of the first four bits in the modem status
                    363: // register changes state a modem status interrupt is generated.
                    364: //
                    365: 
                    366: //
                    367: // This bit is the delta clear to send.  It is used to indicate
                    368: // that the clear to send bit (in this register) has *changed*
                    369: // since this register was last read by the CPU.
                    370: //
                    371: #define SERIAL_MSR_DCTS     0x01
                    372: 
                    373: //
                    374: // This bit is the delta data set ready.  It is used to indicate
                    375: // that the data set ready bit (in this register) has *changed*
                    376: // since this register was last read by the CPU.
                    377: //
                    378: #define SERIAL_MSR_DDSR     0x02
                    379: 
                    380: //
                    381: // This is the trailing edge ring indicator.  It is used to indicate
                    382: // that the ring indicator input has changed from a low to high state.
                    383: //
                    384: #define SERIAL_MSR_TERI     0x04
                    385: 
                    386: //
                    387: // This bit is the delta data carrier detect.  It is used to indicate
                    388: // that the data carrier bit (in this register) has *changed*
                    389: // since this register was last read by the CPU.
                    390: //
                    391: #define SERIAL_MSR_DDCD     0x08
                    392: 
                    393: //
                    394: // This bit contains the (complemented) state of the clear to send
                    395: // (CTS) line.
                    396: //
                    397: #define SERIAL_MSR_CTS      0x10
                    398: 
                    399: //
                    400: // This bit contains the (complemented) state of the data set ready
                    401: // (DSR) line.
                    402: //
                    403: #define SERIAL_MSR_DSR      0x20
                    404: 
                    405: //
                    406: // This bit contains the (complemented) state of the ring indicator
                    407: // (RI) line.
                    408: //
                    409: #define SERIAL_MSR_RI       0x40
                    410: 
                    411: //
                    412: // This bit contains the (complemented) state of the data carrier detect
                    413: // (DCD) line.
                    414: //
                    415: #define SERIAL_MSR_DCD      0x80
                    416: 
                    417: //
                    418: // This should be more than enough space to hold then
                    419: // numeric suffix of the device name.
                    420: //
                    421: #define DEVICE_NAME_DELTA 20
                    422: 
                    423: 
                    424: //
                    425: // Up to 16 Ports Per card.  However for sixteen
                    426: // port cards the interrupt status register must me
                    427: // the indexing kind rather then the bitmask kind.
                    428: //
                    429: //
                    430: #define SERIAL_MAX_PORTS_INDEXED (16)
                    431: #define SERIAL_MAX_PORTS_NONINDEXED (8)
                    432: typedef struct _CONFIG_DATA {
                    433:     LIST_ENTRY ConfigList;
                    434:     LIST_ENTRY SameInterruptStatus;
                    435:     LIST_ENTRY SameInterrupt;
                    436:     UNICODE_STRING ObjectDirectory;
                    437:     UNICODE_STRING NtNameForPort;
                    438:     UNICODE_STRING SymbolicLinkName;
                    439:     PHYSICAL_ADDRESS Controller;
                    440:     PHYSICAL_ADDRESS InterruptStatus;
                    441:     ULONG SpanOfController;
                    442:     ULONG SpanOfInterruptStatus;
                    443:     ULONG PortIndex;
                    444:     ULONG ClockRate;
                    445:     ULONG BusNumber;
                    446:     ULONG AddressSpace;
                    447:     ULONG DisablePort;
                    448:     ULONG ForceFifoEnable;
                    449:     ULONG RxFIFO;
                    450:     KINTERRUPT_MODE InterruptMode;
                    451:     INTERFACE_TYPE InterfaceType;
                    452:     ULONG OriginalVector;
                    453:     ULONG OriginalIrql;
                    454:     ULONG Indexed;
                    455:     BOOLEAN Jensen;
                    456:     } CONFIG_DATA,*PCONFIG_DATA;
                    457: 
                    458: 
                    459: //
                    460: // Default xon/xoff characters.
                    461: //
                    462: #define SERIAL_DEF_XON 0x11
                    463: #define SERIAL_DEF_XOFF 0x13
                    464: 
                    465: //
                    466: // Reasons that recption may be held up.
                    467: //
                    468: #define SERIAL_RX_DTR       ((ULONG)0x01)
                    469: #define SERIAL_RX_XOFF      ((ULONG)0x02)
                    470: #define SERIAL_RX_RTS       ((ULONG)0x04)
                    471: #define SERIAL_RX_DSR       ((ULONG)0x08)
                    472: 
                    473: //
                    474: // Reasons that transmission may be held up.
                    475: //
                    476: #define SERIAL_TX_CTS       ((ULONG)0x01)
                    477: #define SERIAL_TX_DSR       ((ULONG)0x02)
                    478: #define SERIAL_TX_DCD       ((ULONG)0x04)
                    479: #define SERIAL_TX_XOFF      ((ULONG)0x08)
                    480: #define SERIAL_TX_BREAK     ((ULONG)0x10)
                    481: 
                    482: //
                    483: // These values are used by the routines that can be used
                    484: // to complete a read (other than interval timeout) to indicate
                    485: // to the interval timeout that it should complete.
                    486: //
                    487: #define SERIAL_COMPLETE_READ_CANCEL ((LONG)-1)
                    488: #define SERIAL_COMPLETE_READ_TOTAL ((LONG)-2)
                    489: #define SERIAL_COMPLETE_READ_COMPLETE ((LONG)-3)
                    490: 
                    491: 
                    492: 
                    493: typedef struct _SERIAL_DEVICE_EXTENSION {
                    494: 
                    495:     //
                    496:     // This holds the isr that should be called from our own
                    497:     // dispatching isr for "cards" that are trying to share the
                    498:     // same interrupt.
                    499:     //
                    500:     PKSERVICE_ROUTINE TopLevelOurIsr;
                    501: 
                    502:     //
                    503:     // This holds the context that should be used when we
                    504:     // call the above service routine.
                    505:     //
                    506:     PVOID TopLevelOurIsrContext;
                    507: 
                    508:     //
                    509:     // This links together all of the different "cards" that are
                    510:     // trying to share the same interrupt of a non-mca machine.
                    511:     //
                    512:     LIST_ENTRY TopLevelSharers;
                    513: 
                    514:     //
                    515:     // This circular doubly linked list links together all
                    516:     // devices that are using the same interrupt object.
                    517:     // NOTE: This does not mean that they are using the
                    518:     // same interrupt "dispatching" routine.
                    519:     //
                    520:     LIST_ENTRY CommonInterruptObject;
                    521: 
                    522:     //
                    523:     // For reporting resource usage, we keep around the physical
                    524:     // address we got from the registry.
                    525:     //
                    526:     PHYSICAL_ADDRESS OriginalController;
                    527: 
                    528:     //
                    529:     // For reporting resource usage, we keep around the physical
                    530:     // address we got from the registry.
                    531:     //
                    532:     PHYSICAL_ADDRESS OriginalInterruptStatus;
                    533: 
                    534:     //
                    535:     // This value is set by the read code to hold the time value
                    536:     // used for read interval timing.  We keep it in the extension
                    537:     // so that the interval timer dpc routine determine if the
                    538:     // interval time has passed for the IO.
                    539:     //
                    540:     LARGE_INTEGER IntervalTime;
                    541: 
                    542:     //
                    543:     // These two values hold the "constant" time that we should use
                    544:     // to delay for the read interval time.
                    545:     //
                    546:     LARGE_INTEGER ShortIntervalAmount;
                    547:     LARGE_INTEGER LongIntervalAmount;
                    548: 
                    549:     //
                    550:     // This holds the value that we use to determine if we should use
                    551:     // the long interval delay or the short interval delay.
                    552:     //
                    553:     LARGE_INTEGER CutOverAmount;
                    554: 
                    555:     //
                    556:     // This holds the system time when we last time we had
                    557:     // checked that we had actually read characters.  Used
                    558:     // for interval timing.
                    559:     //
                    560:     LARGE_INTEGER LastReadTime;
                    561: 
                    562:     //
                    563:     // We keep a pointer around to our device name for dumps
                    564:     // and for creating "external" symbolic links to this
                    565:     // device.
                    566:     //
                    567:     UNICODE_STRING DeviceName;
                    568: 
                    569:     //
                    570:     // This points to the object directory that we will place
                    571:     // a symbolic link to our device name.
                    572:     //
                    573:     UNICODE_STRING ObjectDirectory;
                    574: 
                    575:     //
                    576:     // This points to the device name for this device
                    577:     // sans device prefix.
                    578:     //
                    579:     UNICODE_STRING NtNameForPort;
                    580: 
                    581:     //
                    582:     // This points to the symbolic link name that will be
                    583:     // linked to the actual nt device name.
                    584:     //
                    585:     UNICODE_STRING SymbolicLinkName;
                    586: 
                    587:     //
                    588:     // This points the the delta time that we should use to
                    589:     // delay for interval timing.
                    590:     //
                    591:     PLARGE_INTEGER IntervalTimeToUse;
                    592: 
                    593:     //
                    594:     // Points to the device object that contains
                    595:     // this device extension.
                    596:     //
                    597:     PDEVICE_OBJECT DeviceObject;
                    598: 
                    599:     //
                    600:     // After initialization of the driver is complete, this
                    601:     // will either be NULL or point to the routine that the
                    602:     // kernel will call when an interrupt occurs.
                    603:     //
                    604:     // If the pointer is null then this is part of a list
                    605:     // of ports that are sharing an interrupt and this isn't
                    606:     // the first port that we configured for this interrupt.
                    607:     //
                    608:     // If the pointer is non-null then this routine has some
                    609:     // kind of structure that will "eventually" get us into
                    610:     // the real serial isr with a pointer to this device extension.
                    611:     //
                    612:     // NOTE: On an MCA bus (except for multiport cards) this
                    613:     // is always a pointer to the "real" serial isr.
                    614:     PKSERVICE_ROUTINE OurIsr;
                    615: 
                    616:     //
                    617:     // This will generally point right to this device extension.
                    618:     //
                    619:     // However, when the port that this device extension is
                    620:     // "managing" was the first port initialized on a chain
                    621:     // of ports that were trying to share an interrupt, this
                    622:     // will point to a structure that will enable dispatching
                    623:     // to any port on the chain of sharers of this interrupt.
                    624:     //
                    625:     PVOID OurIsrContext;
                    626: 
                    627:     //
                    628:     // The base address for the set of device registers
                    629:     // of the serial port.
                    630:     //
                    631:     PUCHAR Controller;
                    632: 
                    633:     //
                    634:     // The base address for interrupt status register.
                    635:     // This is only defined in the root extension.
                    636:     //
                    637:     PUCHAR InterruptStatus;
                    638: 
                    639:     //
                    640:     // Points to the interrupt object for used by this device.
                    641:     //
                    642:     PKINTERRUPT Interrupt;
                    643: 
                    644:     //
                    645:     // This list head is used to contain the time ordered list
                    646:     // of read requests.  Access to this list is protected by
                    647:     // the global cancel spinlock.
                    648:     //
                    649:     LIST_ENTRY ReadQueue;
                    650: 
                    651:     //
                    652:     // This list head is used to contain the time ordered list
                    653:     // of write requests.  Access to this list is protected by
                    654:     // the global cancel spinlock.
                    655:     //
                    656:     LIST_ENTRY WriteQueue;
                    657: 
                    658:     //
                    659:     // This list head is used to contain the time ordered list
                    660:     // of set and wait mask requests.  Access to this list is protected by
                    661:     // the global cancel spinlock.
                    662:     //
                    663:     LIST_ENTRY MaskQueue;
                    664: 
                    665:     //
                    666:     // Holds the serialized list of purge requests.
                    667:     //
                    668:     LIST_ENTRY PurgeQueue;
                    669: 
                    670:     //
                    671:     // This points to the irp that is currently being processed
                    672:     // for the read queue.  This field is initialized by the open to
                    673:     // NULL.
                    674:     //
                    675:     // This value is only set at dispatch level.  It may be
                    676:     // read at interrupt level.
                    677:     //
                    678:     PIRP CurrentReadIrp;
                    679: 
                    680:     //
                    681:     // This points to the irp that is currently being processed
                    682:     // for the write queue.
                    683:     //
                    684:     // This value is only set at dispatch level.  It may be
                    685:     // read at interrupt level.
                    686:     //
                    687:     PIRP CurrentWriteIrp;
                    688: 
                    689:     //
                    690:     // Points to the irp that is currently being processed to
                    691:     // affect the wait mask operations.
                    692:     //
                    693:     PIRP CurrentMaskIrp;
                    694: 
                    695:     //
                    696:     // Points to the irp that is currently being processed to
                    697:     // purge the read/write queues and buffers.
                    698:     //
                    699:     PIRP CurrentPurgeIrp;
                    700: 
                    701:     //
                    702:     // Points to the current irp that is waiting on a comm event.
                    703:     //
                    704:     PIRP CurrentWaitIrp;
                    705: 
                    706:     //
                    707:     // Points to the irp that is being used to send an immediate
                    708:     // character.
                    709:     //
                    710:     PIRP CurrentImmediateIrp;
                    711: 
                    712:     //
                    713:     // Points to the irp that is being used to count the number
                    714:     // of characters received after an xoff (as currently defined
                    715:     // by the IOCTL_SERIAL_XOFF_COUNTER ioctl) is sent.
                    716:     //
                    717:     PIRP CurrentXoffIrp;
                    718: 
                    719:     //
                    720:     // Holds the number of bytes remaining in the current write
                    721:     // irp.
                    722:     //
                    723:     // This location is only accessed while at interrupt level.
                    724:     //
                    725:     ULONG WriteLength;
                    726: 
                    727:     //
                    728:     // Holds a pointer to the current character to be sent in
                    729:     // the current write.
                    730:     //
                    731:     // This location is only accessed while at interrupt level.
                    732:     //
                    733:     PUCHAR WriteCurrentChar;
                    734: 
                    735:     //
                    736:     // This is a buffer for the read processing.
                    737:     //
                    738:     // The buffer works as a ring.  When the character is read from
                    739:     // the device it will be place at the end of the ring.
                    740:     //
                    741:     // Characters are only placed in this buffer at interrupt level
                    742:     // although character may be read at any level. The pointers
                    743:     // that manage this buffer may not be updated except at interrupt
                    744:     // level.
                    745:     //
                    746:     PUCHAR InterruptReadBuffer;
                    747: 
                    748:     //
                    749:     // This is a pointer to the first character of the buffer into
                    750:     // which the interrupt service routine is copying characters.
                    751:     //
                    752:     PUCHAR ReadBufferBase;
                    753: 
                    754:     //
                    755:     // This is a count of the number of characters in the interrupt
                    756:     // buffer.  This value is set and read at interrupt level.  Note
                    757:     // that this value is only *incremented* at interrupt level so
                    758:     // it is safe to read it at any level.  When characters are
                    759:     // copied out of the read buffer, this count is decremented by
                    760:     // a routine that synchronizes with the ISR.
                    761:     //
                    762:     ULONG CharsInInterruptBuffer;
                    763: 
                    764:     //
                    765:     // Points to the first available position for a newly received
                    766:     // character.  This variable is only accessed at interrupt level and
                    767:     // buffer initialization code.
                    768:     //
                    769:     PUCHAR CurrentCharSlot;
                    770: 
                    771:     //
                    772:     // This variable is used to contain the last available position
                    773:     // in the read buffer.  It is updated at open and at interrupt
                    774:     // level when switching between the users buffer and the interrupt
                    775:     // buffer.
                    776:     //
                    777:     PUCHAR LastCharSlot;
                    778: 
                    779:     //
                    780:     // This marks the first character that is available to satisfy
                    781:     // a read request.  Note that while this always points to valid
                    782:     // memory, it may not point to a character that can be sent to
                    783:     // the user.  This can occur when the buffer is empty.
                    784:     //
                    785:     PUCHAR FirstReadableChar;
                    786: 
                    787:     //
                    788:     // This variable holds the size of whatever buffer we are currently
                    789:     // using.
                    790:     //
                    791:     ULONG BufferSize;
                    792: 
                    793:     //
                    794:     // This variable holds .8 of BufferSize. We don't want to recalculate
                    795:     // this real often - It's needed when so that an application can be
                    796:     // "notified" that the buffer is getting full.
                    797:     //
                    798:     ULONG BufferSizePt8;
                    799: 
                    800:     //
                    801:     // This value holds the number of characters desired for a
                    802:     // particular read.  It is initially set by read length in the
                    803:     // IRP.  It is decremented each time more characters are placed
                    804:     // into the "users" buffer buy the code that reads characters
                    805:     // out of the typeahead buffer into the users buffer.  If the
                    806:     // typeahead buffer is exhausted by the read, and the reads buffer
                    807:     // is given to the isr to fill, this value is becomes meaningless.
                    808:     //
                    809:     ULONG NumberNeededForRead;
                    810: 
                    811:     //
                    812:     // This mask will hold the bitmask sent down via the set mask
                    813:     // ioctl.  It is used by the interrupt service routine to determine
                    814:     // if the occurence of "events" (in the serial drivers understanding
                    815:     // of the concept of an event) should be noted.
                    816:     //
                    817:     ULONG IsrWaitMask;
                    818: 
                    819:     //
                    820:     // This mask will always be a subset of the IsrWaitMask.  While
                    821:     // at device level, if an event occurs that is "marked" as interesting
                    822:     // in the IsrWaitMask, the driver will turn on that bit in this
                    823:     // history mask.  The driver will then look to see if there is a
                    824:     // request waiting for an event to occur.  If there is one, it
                    825:     // will copy the value of the history mask into the wait irp, zero
                    826:     // the history mask, and complete the wait irp.  If there is no
                    827:     // waiting request, the driver will be satisfied with just recording
                    828:     // that the event occured.  If a wait request should be queued,
                    829:     // the driver will look to see if the history mask is non-zero.  If
                    830:     // it is non-zero, the driver will copy the history mask into the
                    831:     // irp, zero the history mask, and then complete the irp.
                    832:     //
                    833:     ULONG HistoryMask;
                    834: 
                    835:     //
                    836:     // This is a pointer to the where the history mask should be
                    837:     // placed when completing a wait.  It is only accessed at
                    838:     // device level.
                    839:     //
                    840:     // We have a pointer here to assist us to synchronize completing a wait.
                    841:     // If this is non-zero, then we have wait outstanding, and the isr still
                    842:     // knows about it.  We make this pointer null so that the isr won't
                    843:     // attempt to complete the wait.
                    844:     //
                    845:     // We still keep a pointer around to the wait irp, since the actual
                    846:     // pointer to the wait irp will be used for the "common" irp completion
                    847:     // path.
                    848:     //
                    849:     ULONG *IrpMaskLocation;
                    850: 
                    851:     //
                    852:     // This mask holds all of the reason that transmission
                    853:     // is not proceeding.  Normal transmission can not occur
                    854:     // if this is non-zero.
                    855:     //
                    856:     // This is only written from interrupt level.
                    857:     // This could be (but is not) read at any level.
                    858:     //
                    859:     ULONG TXHolding;
                    860: 
                    861:     //
                    862:     // This mask holds all of the reason that reception
                    863:     // is not proceeding.  Normal reception can not occur
                    864:     // if this is non-zero.
                    865:     //
                    866:     // This is only written from interrupt level.
                    867:     // This could be (but is not) read at any level.
                    868:     //
                    869:     ULONG RXHolding;
                    870: 
                    871:     //
                    872:     // This holds the reasons that the driver thinks it is in
                    873:     // an error state.
                    874:     //
                    875:     // This is only written from interrupt level.
                    876:     // This could be (but is not) read at any level.
                    877:     //
                    878:     ULONG ErrorWord;
                    879: 
                    880:     //
                    881:     // This keeps a total of the number of characters that
                    882:     // are in all of the "write" irps that the driver knows
                    883:     // about.  It is only accessed with the cancel spinlock
                    884:     // held.
                    885:     //
                    886:     ULONG TotalCharsQueued;
                    887: 
                    888:     //
                    889:     // This holds a count of the number of characters read
                    890:     // the last time the interval timer dpc fired.  It
                    891:     // is a long (rather than a ulong) since the other read
                    892:     // completion routines use negative values to indicate
                    893:     // to the interval timer that it should complete the read
                    894:     // if the interval timer DPC was lurking in some DPC queue when
                    895:     // some other way to complete occurs.
                    896:     //
                    897:     LONG CountOnLastRead;
                    898: 
                    899:     //
                    900:     // This is a count of the number of characters read by the
                    901:     // isr routine.  It is *ONLY* written at isr level.  We can
                    902:     // read it at dispatch level.
                    903:     //
                    904:     ULONG ReadByIsr;
                    905: 
                    906:     //
                    907:     // This holds the current baud rate for the device.
                    908:     //
                    909:     ULONG CurrentBaud;
                    910: 
                    911:     //
                    912:     // This is the number of characters read since the XoffCounter
                    913:     // was started.  This variable is only accessed at device level.
                    914:     // If it is greater than zero, it implies that there is an
                    915:     // XoffCounter ioctl in the queue.
                    916:     //
                    917:     LONG CountSinceXoff;
                    918: 
                    919:     //
                    920:     // This ulong is incremented each time something trys to start
                    921:     // the execution path that tries to lower the RTS line when
                    922:     // doing transmit toggling.  If it "bumps" into another path
                    923:     // (indicated by a false return value from queueing a dpc
                    924:     // and a TRUE return value tring to start a timer) it will
                    925:     // decrement the count.  These increments and decrements
                    926:     // are all done at device level.  Note that in the case
                    927:     // of a bump while trying to start the timer, we have to
                    928:     // go up to device level to do the decrement.
                    929:     //
                    930:     ULONG CountOfTryingToLowerRTS;
                    931: 
                    932:     //
                    933:     // This ULONG is used to keep track of the "named" (in ntddser.h)
                    934:     // baud rates that this particular device supports.
                    935:     //
                    936:     ULONG SupportedBauds;
                    937: 
                    938:     //
                    939:     // This value holds the span (in units of bytes) of the register
                    940:     // set controlling this port.  This is constant over the life
                    941:     // of the port.
                    942:     //
                    943:     ULONG SpanOfController;
                    944: 
                    945:     //
                    946:     // This value holds the span (in units of bytes) of the interrupt
                    947:     // status register associated with this port.  This is constant
                    948:     // over the life of the port.
                    949:     //
                    950:     ULONG SpanOfInterruptStatus;
                    951: 
                    952:     //
                    953:     // Hold the clock rate input to the serial part.
                    954:     //
                    955:     ULONG ClockRate;
                    956: 
                    957:     //
                    958:     // Holds the timeout controls for the device.  This value
                    959:     // is set by the Ioctl processing.
                    960:     //
                    961:     // It should only be accessed under protection of the control
                    962:     // lock since more than one request can be in the control dispatch
                    963:     // routine at one time.
                    964:     //
                    965:     SERIAL_TIMEOUTS Timeouts;
                    966: 
                    967:     //
                    968:     // This holds the various characters that are used
                    969:     // for replacement on errors and also for flow control.
                    970:     //
                    971:     // They are only set at interrupt level.
                    972:     //
                    973:     SERIAL_CHARS SpecialChars;
                    974: 
                    975:     //
                    976:     // This structure holds the handshake and control flow
                    977:     // settings for the serial driver.
                    978:     //
                    979:     // It is only set at interrupt level.  It can be
                    980:     // be read at any level with the control lock held.
                    981:     //
                    982:     SERIAL_HANDFLOW HandFlow;
                    983: 
                    984:     //
                    985:     // This holds what we beleive to be the current value of
                    986:     // the line control register.
                    987:     //
                    988:     // It should only be accessed under protection of the control
                    989:     // lock since more than one request can be in the control dispatch
                    990:     // routine at one time.
                    991:     //
                    992:     UCHAR LineControl;
                    993: 
                    994:     //
                    995:     // We keep track of whether the somebody has the device currently
                    996:     // opened with a simple boolean.  We need to know this so that
                    997:     // spurious interrupts from the device (especially during initialization)
                    998:     // will be ignored.  This value is only accessed in the ISR and
                    999:     // is only set via synchronization routines.  We may be able
                   1000:     // to get rid of this boolean when the code is more fleshed out.
                   1001:     //
                   1002:     BOOLEAN DeviceIsOpened;
                   1003: 
                   1004:     //
                   1005:     // Set at intialization to indicate that on the current
                   1006:     // architecture we need to unmap the base register address
                   1007:     // when we unload the driver.
                   1008:     //
                   1009:     BOOLEAN UnMapRegisters;
                   1010: 
                   1011:     //
                   1012:     // Set at intialization to indicate that on the current
                   1013:     // architecture we need to unmap the interrupt status address
                   1014:     // when we unload the driver.
                   1015:     //
                   1016:     BOOLEAN UnMapStatus;
                   1017: 
                   1018:     //
                   1019:     // This is only accessed at interrupt level.  It keeps track
                   1020:     // of whether the holding register is empty.
                   1021:     //
                   1022:     BOOLEAN HoldingEmpty;
                   1023: 
                   1024:     //
                   1025:     // This variable is only accessed at interrupt level.  It
                   1026:     // indicates that we want to transmit a character immediately.
                   1027:     // That is - in front of any characters that could be transmitting
                   1028:     // from a normal write.
                   1029:     //
                   1030:     BOOLEAN TransmitImmediate;
                   1031: 
                   1032:     //
                   1033:     // This variable is only accessed at interrupt level.  Whenever
                   1034:     // a wait is initiated this variable is set to false.
                   1035:     // Whenever any kind of character is written it is set to true.
                   1036:     // Whenever the write queue is found to be empty the code that
                   1037:     // is processing that completing irp will synchonize with the interrupt.
                   1038:     // If this synchronization code finds that the variable is true and that
                   1039:     // there is a wait on the transmit queue being empty then it is
                   1040:     // certain that the queue was emptied and that it has happened since
                   1041:     // the wait was initiated.
                   1042:     //
                   1043:     BOOLEAN EmptiedTransmit;
                   1044: 
                   1045:     //
                   1046:     // This simply indicates that the port associated with this
                   1047:     // extension is part of a multiport card.
                   1048:     //
                   1049:     BOOLEAN PortOnAMultiportCard;
                   1050: 
                   1051:     //
                   1052:     // We keep the following values around so that we can connect
                   1053:     // to the interrupt and report resources after the configuration
                   1054:     // record is gone.
                   1055:     //
                   1056:     ULONG Vector;
                   1057:     KIRQL Irql;
                   1058:     ULONG OriginalVector;
                   1059:     ULONG OriginalIrql;
                   1060:     KINTERRUPT_MODE InterruptMode;
                   1061:     KAFFINITY ProcessorAffinity;
                   1062:     ULONG AddressSpace;
                   1063:     ULONG BusNumber;
                   1064:     INTERFACE_TYPE InterfaceType;
                   1065: 
                   1066:     //
                   1067:     // We hold the character that should be transmitted immediately.
                   1068:     //
                   1069:     // Note that we can't use this to determine whether there is
                   1070:     // a character to send because the character to send could be
                   1071:     // zero.
                   1072:     //
                   1073:     UCHAR ImmediateChar;
                   1074: 
                   1075:     //
                   1076:     // This holds the mask that will be used to mask off unwanted
                   1077:     // data bits of the received data (valid data bits can be 5,6,7,8)
                   1078:     // The mask will normally be 0xff.  This is set while the control
                   1079:     // lock is held since it wouldn't have adverse effects on the
                   1080:     // isr if it is changed in the middle of reading characters.
                   1081:     // (What it would do to the app is another question - but then
                   1082:     // the app asked the driver to do it.)
                   1083:     //
                   1084:     UCHAR ValidDataMask;
                   1085: 
                   1086:     //
                   1087:     // The application can turn on a mode,via the
                   1088:     // IOCTL_SERIAL_LSRMST_INSERT ioctl, that will cause the
                   1089:     // serial driver to insert the line status or the modem
                   1090:     // status into the RX stream.  The parameter with the ioctl
                   1091:     // is a pointer to a UCHAR.  If the value of the UCHAR is
                   1092:     // zero, then no insertion will ever take place.  If the
                   1093:     // value of the UCHAR is non-zero (and not equal to the
                   1094:     // xon/xoff characters), then the serial driver will insert.
                   1095:     //
                   1096:     UCHAR EscapeChar;
                   1097: 
                   1098:     //
                   1099:     // These two booleans are used to indicate to the isr transmit
                   1100:     // code that it should send the xon or xoff character.  They are
                   1101:     // only accessed at open and at interrupt level.
                   1102:     //
                   1103:     BOOLEAN SendXonChar;
                   1104:     BOOLEAN SendXoffChar;
                   1105: 
                   1106:     //
                   1107:     // This boolean will be true if a 16550 is present *and* enabled.
                   1108:     //
                   1109:     BOOLEAN FifoPresent;
                   1110: 
                   1111:     //
                   1112:     // This denotes that this particular port is an on the motherboard
                   1113:     // port for the Jensen hardware.  On these ports the OUT2 bit
                   1114:     // which is used to enable/disable interrupts is always hight.
                   1115:     //
                   1116:     BOOLEAN Jensen;
                   1117: 
                   1118:     //
                   1119:     // This is the water mark that the rxfifo should be
                   1120:     // set to when the fifo is turned on.  This is not the actual
                   1121:     // value, but the encoded value that goes into the register.
                   1122:     //
                   1123:     UCHAR RxFifoTrigger;
                   1124: 
                   1125:     //
                   1126:     // Says whether this device can share interrupts with devices
                   1127:     // other than serial devices.
                   1128:     //
                   1129:     BOOLEAN InterruptShareable;
                   1130: 
                   1131:     //
                   1132:     // Records whether we actually created the symbolic link name
                   1133:     // at driver load time.  If we didn't create it, we won't try
                   1134:     // to distry it when we unload.
                   1135:     //
                   1136:     BOOLEAN CreatedSymbolicLink;
                   1137: 
                   1138:     //
                   1139:     // We place all of the kernel and Io subsystem "opaque" structures
                   1140:     // at the end of the extension.  We don't care about their contents.
                   1141:     //
                   1142: 
                   1143:     //
                   1144:     // This lock will be used to protect various fields in
                   1145:     // the extension that are set (& read) in the extension
                   1146:     // by the io controls.
                   1147:     //
                   1148:     KSPIN_LOCK ControlLock;
                   1149: 
                   1150:     //
                   1151:     // This points to a DPC used to complete read requests.
                   1152:     //
                   1153:     KDPC CompleteWriteDpc;
                   1154: 
                   1155:     //
                   1156:     // This points to a DPC used to complete read requests.
                   1157:     //
                   1158:     KDPC CompleteReadDpc;
                   1159: 
                   1160:     //
                   1161:     // This dpc is fired off if the timer for the total timeout
                   1162:     // for the read expires.  It will execute a dpc routine that
                   1163:     // will cause the current read to complete.
                   1164:     //
                   1165:     //
                   1166:     KDPC TotalReadTimeoutDpc;
                   1167: 
                   1168:     //
                   1169:     // This dpc is fired off if the timer for the interval timeout
                   1170:     // expires.  If no more characters have been read then the
                   1171:     // dpc routine will cause the read to complete.  However, if
                   1172:     // more characters have been read then the dpc routine will
                   1173:     // resubmit the timer.
                   1174:     //
                   1175:     KDPC IntervalReadTimeoutDpc;
                   1176: 
                   1177:     //
                   1178:     // This dpc is fired off if the timer for the total timeout
                   1179:     // for the write expires.  It will execute a dpc routine that
                   1180:     // will cause the current write to complete.
                   1181:     //
                   1182:     //
                   1183:     KDPC TotalWriteTimeoutDpc;
                   1184: 
                   1185:     //
                   1186:     // This dpc is fired off if a comm error occurs.  It will
                   1187:     // execute a dpc routine that will cancel all pending reads
                   1188:     // and writes.
                   1189:     //
                   1190:     KDPC CommErrorDpc;
                   1191: 
                   1192:     //
                   1193:     // This dpc is fired off if an event occurs and there was
                   1194:     // a irp waiting on that event.  A dpc routine will execute
                   1195:     // that completes the irp.
                   1196:     //
                   1197:     KDPC CommWaitDpc;
                   1198: 
                   1199:     //
                   1200:     // This dpc is fired off when the transmit immediate char
                   1201:     // character is given to the hardware.  It will simply complete
                   1202:     // the irp.
                   1203:     //
                   1204:     KDPC CompleteImmediateDpc;
                   1205: 
                   1206:     //
                   1207:     // This dpc is fired off if the transmit immediate char
                   1208:     // character times out.  The dpc routine will "grab" the
                   1209:     // irp from the isr and time it out.
                   1210:     //
                   1211:     KDPC TotalImmediateTimeoutDpc;
                   1212: 
                   1213:     //
                   1214:     // This dpc is fired off if the timer used to "timeout" counting
                   1215:     // the number of characters received after the Xoff ioctl is started
                   1216:     // expired.
                   1217:     //
                   1218:     KDPC XoffCountTimeoutDpc;
                   1219: 
                   1220:     //
                   1221:     // This dpc is fired off if the xoff counter actually runs down
                   1222:     // to zero.
                   1223:     //
                   1224:     KDPC XoffCountCompleteDpc;
                   1225: 
                   1226:     //
                   1227:     // This dpc is fired off only from device level to start off
                   1228:     // a timer that will queue a dpc to check if the RTS line
                   1229:     // should be lowered when we are doing transmit toggling.
                   1230:     //
                   1231:     KDPC StartTimerLowerRTSDpc;
                   1232: 
                   1233:     //
                   1234:     // This dpc is fired off when a timer expires (after one
                   1235:     // character time), so that code can be invoked that will
                   1236:     // check to see if we should lower the RTS line when
                   1237:     // doing transmit toggling.
                   1238:     //
                   1239:     KDPC PerhapsLowerRTSDpc;
                   1240: 
                   1241:     //
                   1242:     // This is the kernal timer structure used to handle
                   1243:     // total read request timing.
                   1244:     //
                   1245:     KTIMER ReadRequestTotalTimer;
                   1246: 
                   1247:     //
                   1248:     // This is the kernal timer structure used to handle
                   1249:     // interval read request timing.
                   1250:     //
                   1251:     KTIMER ReadRequestIntervalTimer;
                   1252: 
                   1253:     //
                   1254:     // This is the kernal timer structure used to handle
                   1255:     // total time request timing.
                   1256:     //
                   1257:     KTIMER WriteRequestTotalTimer;
                   1258: 
                   1259:     //
                   1260:     // This is the kernal timer structure used to handle
                   1261:     // total time request timing.
                   1262:     //
                   1263:     KTIMER ImmediateTotalTimer;
                   1264: 
                   1265:     //
                   1266:     // This timer is used to timeout the xoff counter
                   1267:     // io.
                   1268:     //
                   1269:     KTIMER XoffCountTimer;
                   1270: 
                   1271:     //
                   1272:     // This timer is used to invoke a dpc one character time
                   1273:     // after the timer is set.  That dpc will be used to check
                   1274:     // whether we should lower the RTS line if we are doing
                   1275:     // transmit toggling.
                   1276:     //
                   1277:     KTIMER LowerRTSTimer;
                   1278:     } SERIAL_DEVICE_EXTENSION,*PSERIAL_DEVICE_EXTENSION;
                   1279: 
                   1280: 
                   1281: 
                   1282: //
                   1283: // When dealing with a multi-port device (that is possibly
                   1284: // daisy chained with other multi-port device), the interrupt
                   1285: // service routine will actually be a routine that determines
                   1286: // which port on which board is actually causing the interrupt.
                   1287: //
                   1288: // The following structure is used so that only one device
                   1289: // extension will actually need to connect to the interrupt.
                   1290: // The following structure which is passed to the interrupt
                   1291: // service routine contains the addresses of all of the
                   1292: // interrupt status registers (there will be multiple
                   1293: // status registers when multi-port cards are chained).  It
                   1294: // will contain the addresses of all the extensions whose
                   1295: // devices are being serviced by this interrupt.
                   1296: //
                   1297: 
                   1298: typedef struct _SERIAL_MULTIPORT_DISPATCH {
                   1299:     PUCHAR InterruptStatus;
                   1300:     PSERIAL_DEVICE_EXTENSION Extensions[SERIAL_MAX_PORTS_INDEXED];
                   1301:     UCHAR UsablePortMask;
                   1302:     } SERIAL_MULTIPORT_DISPATCH,*PSERIAL_MULTIPORT_DISPATCH;
                   1303: 
                   1304: 
                   1305: //
                   1306: // Sets the divisor latch register.  The divisor latch register
                   1307: // is used to control the baud rate of the 8250.
                   1308: //
                   1309: // As with all of these routines it is assumed that it is called
                   1310: // at a safe point to access the hardware registers.  In addition
                   1311: // it also assumes that the data is correct.
                   1312: //
                   1313: // Arguments:
                   1314: //
                   1315: // BaseAddress - A pointer to the address from which the hardware
                   1316: //               device registers are located.
                   1317: //
                   1318: // DesiredDivisor - The value to which the divisor latch register should
                   1319: //                  be set.
                   1320: //
                   1321: #define WRITE_DIVISOR_LATCH(BaseAddress,DesiredDivisor)           \
                   1322: do                                                                \
                   1323: {                                                                 \
                   1324:     PUCHAR Address = BaseAddress;                                 \
                   1325:     SHORT Divisor = DesiredDivisor;                               \
                   1326:     UCHAR LineControl;                                            \
                   1327:     LineControl = READ_PORT_UCHAR(Address+LINE_CONTROL_REGISTER); \
                   1328:     WRITE_PORT_UCHAR(                                             \
                   1329:         Address+LINE_CONTROL_REGISTER,                            \
                   1330:         (UCHAR)(LineControl | SERIAL_LCR_DLAB)                    \
                   1331:         );                                                        \
                   1332:     WRITE_PORT_UCHAR(                                             \
                   1333:         Address+DIVISOR_LATCH_LSB,                                \
                   1334:         (UCHAR)(Divisor & 0xff)                                   \
                   1335:         );                                                        \
                   1336:     WRITE_PORT_UCHAR(                                             \
                   1337:         Address+DIVISOR_LATCH_MSB,                                \
                   1338:         (UCHAR)((Divisor & 0xff00) >> 8)                          \
                   1339:         );                                                        \
                   1340:     WRITE_PORT_UCHAR(                                             \
                   1341:         Address+LINE_CONTROL_REGISTER,                            \
                   1342:         LineControl                                               \
                   1343:         );                                                        \
                   1344: } while (0)
                   1345: 
                   1346: //
                   1347: // Reads the divisor latch register.  The divisor latch register
                   1348: // is used to control the baud rate of the 8250.
                   1349: //
                   1350: // As with all of these routines it is assumed that it is called
                   1351: // at a safe point to access the hardware registers.  In addition
                   1352: // it also assumes that the data is correct.
                   1353: //
                   1354: // Arguments:
                   1355: //
                   1356: // BaseAddress - A pointer to the address from which the hardware
                   1357: //               device registers are located.
                   1358: //
                   1359: // DesiredDivisor - A pointer to the 2 byte word which will contain
                   1360: //                  the value of the divisor.
                   1361: //
                   1362: #define READ_DIVISOR_LATCH(BaseAddress,PDesiredDivisor)           \
                   1363: do                                                                \
                   1364: {                                                                 \
                   1365:     PUCHAR Address = BaseAddress;                                 \
                   1366:     PSHORT PDivisor = PDesiredDivisor;                            \
                   1367:     UCHAR LineControl;                                            \
                   1368:     UCHAR Lsb;                                                    \
                   1369:     UCHAR Msb;                                                    \
                   1370:     LineControl = READ_PORT_UCHAR(Address+LINE_CONTROL_REGISTER); \
                   1371:     WRITE_PORT_UCHAR(                                             \
                   1372:         Address+LINE_CONTROL_REGISTER,                            \
                   1373:         (UCHAR)(LineControl | SERIAL_LCR_DLAB)                    \
                   1374:         );                                                        \
                   1375:     Lsb = READ_PORT_UCHAR(Address+DIVISOR_LATCH_LSB);             \
                   1376:     Msb = READ_PORT_UCHAR(Address+DIVISOR_LATCH_MSB);             \
                   1377:     *PDivisor = Lsb;                                              \
                   1378:     *PDivisor = *PDivisor | (((USHORT)Msb) << 8);                 \
                   1379:     WRITE_PORT_UCHAR(                                             \
                   1380:         Address+LINE_CONTROL_REGISTER,                            \
                   1381:         LineControl                                               \
                   1382:         );                                                        \
                   1383: } while (0)
                   1384: 
                   1385: //
                   1386: // This macro reads the interrupt enable register.
                   1387: //
                   1388: // Arguments:
                   1389: //
                   1390: // BaseAddress - A pointer to the address from which the hardware
                   1391: //               device registers are located.
                   1392: //
                   1393: #define READ_INTERRUPT_ENABLE(BaseAddress)                     \
                   1394:     (READ_PORT_UCHAR((BaseAddress)+INTERRUPT_ENABLE_REGISTER))
                   1395: 
                   1396: //
                   1397: // This macro writes the interrupt enable register.
                   1398: //
                   1399: // Arguments:
                   1400: //
                   1401: // BaseAddress - A pointer to the address from which the hardware
                   1402: //               device registers are located.
                   1403: //
                   1404: // Values - The values to write to the interrupt enable register.
                   1405: //
                   1406: #define WRITE_INTERRUPT_ENABLE(BaseAddress,Values)                \
                   1407: do                                                                \
                   1408: {                                                                 \
                   1409:     WRITE_PORT_UCHAR(                                             \
                   1410:         BaseAddress+INTERRUPT_ENABLE_REGISTER,                    \
                   1411:         Values                                                    \
                   1412:         );                                                        \
                   1413: } while (0)
                   1414: 
                   1415: //
                   1416: // This macro disables all interrupts on the hardware.
                   1417: //
                   1418: // Arguments:
                   1419: //
                   1420: // BaseAddress - A pointer to the address from which the hardware
                   1421: //               device registers are located.
                   1422: //
                   1423: //
                   1424: #define DISABLE_ALL_INTERRUPTS(BaseAddress)       \
                   1425: do                                                \
                   1426: {                                                 \
                   1427:     WRITE_INTERRUPT_ENABLE(BaseAddress,0);        \
                   1428: } while (0)
                   1429: 
                   1430: //
                   1431: // This macro enables all interrupts on the hardware.
                   1432: //
                   1433: // Arguments:
                   1434: //
                   1435: // BaseAddress - A pointer to the address from which the hardware
                   1436: //               device registers are located.
                   1437: //
                   1438: //
                   1439: #define ENABLE_ALL_INTERRUPTS(BaseAddress)        \
                   1440: do                                                \
                   1441: {                                                 \
                   1442:                                                   \
                   1443:     WRITE_INTERRUPT_ENABLE(                       \
                   1444:         (BaseAddress),                            \
                   1445:         (UCHAR)(SERIAL_IER_RDA | SERIAL_IER_THR | \
                   1446:                 SERIAL_IER_RLS | SERIAL_IER_MS)   \
                   1447:         );                                        \
                   1448:                                                   \
                   1449: } while (0)
                   1450: 
                   1451: //
                   1452: // This macro reads the interrupt identification register
                   1453: //
                   1454: // Arguments:
                   1455: //
                   1456: // BaseAddress - A pointer to the address from which the hardware
                   1457: //               device registers are located.
                   1458: //
                   1459: // Note that this routine potententially quites a transmitter
                   1460: // empty interrupt.  This is because one way that the transmitter
                   1461: // empty interrupt is cleared is to simply read the interrupt id
                   1462: // register.
                   1463: //
                   1464: //
                   1465: #define READ_INTERRUPT_ID_REG(BaseAddress)                          \
                   1466:     (READ_PORT_UCHAR((BaseAddress)+INTERRUPT_IDENT_REGISTER))
                   1467: 
                   1468: //
                   1469: // This macro reads the modem control register
                   1470: //
                   1471: // Arguments:
                   1472: //
                   1473: // BaseAddress - A pointer to the address from which the hardware
                   1474: //               device registers are located.
                   1475: //
                   1476: //
                   1477: #define READ_MODEM_CONTROL(BaseAddress)                          \
                   1478:     (READ_PORT_UCHAR((BaseAddress)+MODEM_CONTROL_REGISTER))
                   1479: 
                   1480: //
                   1481: // This macro reads the modem status register
                   1482: //
                   1483: // Arguments:
                   1484: //
                   1485: // BaseAddress - A pointer to the address from which the hardware
                   1486: //               device registers are located.
                   1487: //
                   1488: //
                   1489: #define READ_MODEM_STATUS(BaseAddress)                          \
                   1490:     (READ_PORT_UCHAR((BaseAddress)+MODEM_STATUS_REGISTER))
                   1491: 
                   1492: //
                   1493: // This macro reads a value out of the receive buffer
                   1494: //
                   1495: // Arguments:
                   1496: //
                   1497: // BaseAddress - A pointer to the address from which the hardware
                   1498: //               device registers are located.
                   1499: //
                   1500: //
                   1501: #define READ_RECEIVE_BUFFER(BaseAddress)                          \
                   1502:     (READ_PORT_UCHAR((BaseAddress)+RECEIVE_BUFFER_REGISTER))
                   1503: 
                   1504: //
                   1505: // This macro reads the line status register
                   1506: //
                   1507: // Arguments:
                   1508: //
                   1509: // BaseAddress - A pointer to the address from which the hardware
                   1510: //               device registers are located.
                   1511: //
                   1512: //
                   1513: #define READ_LINE_STATUS(BaseAddress)                          \
                   1514:     (READ_PORT_UCHAR((BaseAddress)+LINE_STATUS_REGISTER))
                   1515: 
                   1516: //
                   1517: // This macro writes the line control register
                   1518: //
                   1519: // Arguments:
                   1520: //
                   1521: // BaseAddress - A pointer to the address from which the hardware
                   1522: //               device registers are located.
                   1523: //
                   1524: //
                   1525: #define WRITE_LINE_CONTROL(BaseAddress,NewLineControl)           \
                   1526: do                                                               \
                   1527: {                                                                \
                   1528:     WRITE_PORT_UCHAR(                                            \
                   1529:         (BaseAddress)+LINE_CONTROL_REGISTER,                     \
                   1530:         (NewLineControl)                                         \
                   1531:         );                                                       \
                   1532: } while (0)
                   1533: 
                   1534: //
                   1535: // This macro reads the line control register
                   1536: //
                   1537: // Arguments:
                   1538: //
                   1539: // BaseAddress - A pointer to the address from which the hardware
                   1540: //               device registers are located.
                   1541: //
                   1542: //
                   1543: #define READ_LINE_CONTROL(BaseAddress)           \
                   1544:     (READ_PORT_UCHAR((BaseAddress)+LINE_CONTROL_REGISTER))
                   1545: 
                   1546: 
                   1547: //
                   1548: // This macro writes to the transmit register
                   1549: //
                   1550: // Arguments:
                   1551: //
                   1552: // BaseAddress - A pointer to the address from which the hardware
                   1553: //               device registers are located.
                   1554: //
                   1555: // TransmitChar - The character to send down the wire.
                   1556: //
                   1557: //
                   1558: #define WRITE_TRANSMIT_HOLDING(BaseAddress,TransmitChar)       \
                   1559: do                                                             \
                   1560: {                                                              \
                   1561:     WRITE_PORT_UCHAR(                                          \
                   1562:         (BaseAddress)+TRANSMIT_HOLDING_REGISTER,               \
                   1563:         (TransmitChar)                                         \
                   1564:         );                                                     \
                   1565: } while (0)
                   1566: 
                   1567: //
                   1568: // This macro writes to the control register
                   1569: //
                   1570: // Arguments:
                   1571: //
                   1572: // BaseAddress - A pointer to the address from which the hardware
                   1573: //               device registers are located.
                   1574: //
                   1575: // ControlValue - The value to set the fifo control register too.
                   1576: //
                   1577: //
                   1578: #define WRITE_FIFO_CONTROL(BaseAddress,ControlValue)           \
                   1579: do                                                             \
                   1580: {                                                              \
                   1581:     WRITE_PORT_UCHAR(                                          \
                   1582:         (BaseAddress)+FIFO_CONTROL_REGISTER,                   \
                   1583:         (ControlValue)                                         \
                   1584:         );                                                     \
                   1585: } while (0)
                   1586: 
                   1587: //
                   1588: // This macro writes to the modem control register
                   1589: //
                   1590: // Arguments:
                   1591: //
                   1592: // BaseAddress - A pointer to the address from which the hardware
                   1593: //               device registers are located.
                   1594: //
                   1595: // ModemControl - The control bits to send to the modem control.
                   1596: //
                   1597: //
                   1598: #define WRITE_MODEM_CONTROL(BaseAddress,ModemControl)          \
                   1599: do                                                             \
                   1600: {                                                              \
                   1601:     WRITE_PORT_UCHAR(                                          \
                   1602:         (BaseAddress)+MODEM_CONTROL_REGISTER,                  \
                   1603:         (ModemControl)                                         \
                   1604:         );                                                     \
                   1605: } while (0)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.