Annotation of ntddk/src/input/sermouse/uart.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993  Microsoft Corporation
                      4: Copyright (c) 1993  Logitech Inc.
                      5: 
                      6: Module Name:
                      7: 
                      8:     uart.c
                      9: 
                     10: Abstract:
                     11: 
                     12: Environment:
                     13: 
                     14:     Kernel mode only.
                     15: 
                     16: Notes:
                     17: 
                     18: Revision History:
                     19: 
                     20: --*/
                     21: 
                     22: #include "ntddk.h"
                     23: #include "uart.h"
                     24: #include "sermouse.h"
                     25: #include "debug.h"
                     26: 
                     27: #ifdef ALLOC_PRAGMA
                     28: #pragma alloc_text(init,UARTSetFifo)
                     29: #pragma alloc_text(init,UARTGetInterruptCtrl)
                     30: #pragma alloc_text(init,UARTSetInterruptCtrl)
                     31: #pragma alloc_text(init,UARTGetLineCtrl)
                     32: #pragma alloc_text(init,UARTSetLineCtrl)
                     33: #pragma alloc_text(init,UARTGetModemCtrl)
                     34: #pragma alloc_text(init,UARTSetModemCtrl)
                     35: #pragma alloc_text(init,UARTSetDlab)
                     36: #pragma alloc_text(init,UARTGetBaudRate)
                     37: #pragma alloc_text(init,UARTSetBaudRate)
                     38: #pragma alloc_text(init,UARTGetState)
                     39: #pragma alloc_text(init,UARTSetState)
                     40: #pragma alloc_text(init,UARTReadChar)
                     41: #pragma alloc_text(init,UARTIsTransmitEmpty)
                     42: #pragma alloc_text(init,UARTWriteChar)
                     43: #pragma alloc_text(init,UARTWriteString)
                     44: #endif // ALLOC_PRAGMA
                     45: 
                     46: //
                     47: // Constants
                     48: //
                     49: 
                     50: 
                     51: VOID
                     52: UARTSetFifo(
                     53:     PUCHAR Port,
                     54:     UCHAR Value
                     55:     )
                     56: /*++
                     57: 
                     58: Routine Description:
                     59: 
                     60:     Set the FIFO register.
                     61: 
                     62: Arguments:
                     63: 
                     64:     Port - Pointer to the serial port.
                     65: 
                     66:     Value - The FIFO control mask.
                     67: 
                     68: Return Value:
                     69: 
                     70:     None.
                     71: 
                     72: --*/
                     73: {
                     74:     WRITE_PORT_UCHAR(Port + ACE_IIDR, Value);
                     75: }
                     76: UCHAR
                     77: UARTGetInterruptCtrl(
                     78:     PUCHAR Port
                     79:     )
                     80: /*++
                     81: 
                     82: Routine Description:
                     83: 
                     84:     Get the serial port interrupt control register.
                     85: 
                     86: Arguments:
                     87: 
                     88:     Port - Pointer to the serial port.
                     89: 
                     90: Return Value:
                     91: 
                     92:     Serial port interrupt control register value.
                     93: 
                     94: --*/
                     95: {
                     96:     return READ_PORT_UCHAR(Port + ACE_IER);
                     97: }
                     98: 
                     99: UCHAR
                    100: UARTSetInterruptCtrl(
                    101:     PUCHAR Port,
                    102:     UCHAR Value
                    103:     )
                    104: /*++
                    105: 
                    106: Routine Description:
                    107: 
                    108:     Set the interrupt control register.
                    109: 
                    110: Arguments:
                    111: 
                    112:     Port - Pointer to the serial port.
                    113: 
                    114:     Value - The interrupt control mask.
                    115: 
                    116: Return Value:
                    117: 
                    118:     Previous interrupt control value.
                    119: 
                    120: --*/
                    121: {
                    122:     UCHAR oldValue = UARTGetInterruptCtrl(Port);
                    123:     WRITE_PORT_UCHAR(Port + ACE_IER, Value);
                    124: 
                    125:     return oldValue;
                    126: }
                    127: 
                    128: 
                    129: UCHAR
                    130: UARTGetLineCtrl(
                    131:     PUCHAR Port
                    132:     )
                    133: /*++
                    134: 
                    135: Routine Description:
                    136: 
                    137:     Get the serial port line control register.
                    138: 
                    139: Arguments:
                    140: 
                    141:     Port - Pointer to the serial port.
                    142: 
                    143: Return Value:
                    144: 
                    145:     Serial port line control value.
                    146: 
                    147: --*/
                    148: {
                    149:     return READ_PORT_UCHAR(Port + ACE_LCR);
                    150: }
                    151: 
                    152: UCHAR
                    153: UARTSetLineCtrl(
                    154:     PUCHAR Port,
                    155:     UCHAR Value
                    156:     )
                    157: /*++
                    158: 
                    159: Routine Description:
                    160: 
                    161:     Set the serial port line control register.
                    162: 
                    163: Arguments:
                    164: 
                    165:     Port - Pointer to the serial port.
                    166: 
                    167:     Value - New line control value.
                    168: 
                    169: Return Value:
                    170: 
                    171:     Previous serial line control register value.
                    172: 
                    173: --*/
                    174: {
                    175:     UCHAR oldValue = UARTGetLineCtrl(Port);
                    176:     WRITE_PORT_UCHAR(Port + ACE_LCR, Value);
                    177: 
                    178:     return oldValue;
                    179: }
                    180: 
                    181: 
                    182: UCHAR
                    183: UARTGetModemCtrl(
                    184:     PUCHAR Port
                    185:     )
                    186: /*++
                    187: 
                    188: Routine Description:
                    189: 
                    190:     Get the serial port modem control register.
                    191: 
                    192: Arguments:
                    193: 
                    194:     Port - Pointer to the serial port.
                    195: 
                    196: Return Value:
                    197: 
                    198:     Serial port modem control register value.
                    199: 
                    200: --*/
                    201: {
                    202:     return READ_PORT_UCHAR(Port + ACE_MCR);
                    203: }
                    204: 
                    205: UCHAR
                    206: UARTSetModemCtrl(
                    207:     PUCHAR Port,
                    208:     UCHAR Value
                    209:     )
                    210: /*++
                    211: 
                    212: Routine Description:
                    213: 
                    214:     Set the serial port modem control register.
                    215: 
                    216: Arguments:
                    217: 
                    218:     Port - Pointer to the serial port.
                    219: 
                    220: Return Value:
                    221: 
                    222:     Previous modem control register value.
                    223: 
                    224: --*/
                    225: {
                    226: 
                    227:     UCHAR oldValue = UARTGetModemCtrl(Port);
                    228:     WRITE_PORT_UCHAR(Port + ACE_MCR, Value);
                    229: 
                    230:     return oldValue;
                    231: }
                    232: 
                    233: 
                    234: BOOLEAN
                    235: UARTSetDlab(
                    236:     PUCHAR Port,
                    237:     BOOLEAN Set
                    238:     )
                    239: /*++
                    240: 
                    241: Routine Description:
                    242: 
                    243:     Set/reset the baud rate access bit.
                    244: 
                    245: Arguments:
                    246: 
                    247:     Port - Pointer to the serial port.
                    248: 
                    249:     Set - Set or Reset (TRUE/FALSE) the baud rate access bit.
                    250: 
                    251: Return Value:
                    252: 
                    253:     The previous baud rate access bit setting.
                    254: 
                    255: --*/
                    256: {
                    257:     UCHAR lineControl = UARTGetLineCtrl(Port);
                    258:     UCHAR newLineControl = Set ? lineControl | ACE_DLAB :
                    259:                                  lineControl & ~ACE_DLAB;
                    260: 
                    261:     WRITE_PORT_UCHAR(Port + ACE_LCR, newLineControl);
                    262: 
                    263:     return lineControl & ACE_DLAB;
                    264: }
                    265: 
                    266: ULONG
                    267: UARTGetBaudRate(
                    268:     PUCHAR Port,
                    269:     ULONG BaudClock
                    270:     )
                    271: /*++
                    272: 
                    273: Routine Description:
                    274: 
                    275:     Get the serial port baud rate setting.
                    276: 
                    277: Arguments:
                    278: 
                    279:     Port - Pointer to the serial port.
                    280: 
                    281:     BaudClock - The external frequency driving the serial chip.
                    282: 
                    283: Return Value:
                    284: 
                    285:     Serial port baud rate.
                    286: 
                    287: --*/
                    288: {
                    289:     USHORT baudRateDivisor;
                    290:     ULONG  baudRateFactor = BaudClock/BAUD_GENERATOR_DIVISOR;
                    291: 
                    292:     //
                    293:     // Set the baud rate access bit.
                    294:     //
                    295: 
                    296:     UARTSetDlab(Port, TRUE);
                    297: 
                    298:     //
                    299:     // Read the baud rate factor.
                    300:     //
                    301: 
                    302:     baudRateDivisor = READ_PORT_UCHAR(Port + ACE_DLL);
                    303:     baudRateDivisor |= READ_PORT_UCHAR(Port + ACE_DLM) << 8;
                    304: 
                    305:     //
                    306:     // Reset the baud rate bit for normal data access.
                    307:     //
                    308: 
                    309:     UARTSetDlab(Port, FALSE);
                    310: 
                    311:     //
                    312:     // Make sure the divisor is not zero.
                    313:     //
                    314: 
                    315:     if (baudRateDivisor == 0) {
                    316:         baudRateDivisor = 1;
                    317:     }
                    318: 
                    319:     return baudRateFactor / baudRateDivisor;
                    320: }
                    321: 
                    322: VOID
                    323: UARTSetBaudRate(
                    324:     PUCHAR Port,
                    325:     ULONG BaudRate,
                    326:     ULONG BaudClock
                    327:     )
                    328: /*++
                    329: 
                    330: Routine Description:
                    331: 
                    332:     Set the serial port baud rate.
                    333: 
                    334: Arguments:
                    335: 
                    336:     Port - Pointer to the serial port.
                    337: 
                    338:     BaudRate - New serial port baud rate.
                    339: 
                    340:     BaudClock - The external frequency driving the serial chip.
                    341: 
                    342: Return Value:
                    343: 
                    344:     None.
                    345: 
                    346: --*/
                    347: {
                    348:    
                    349:     ULONG  baudRateFactor = BaudClock/BAUD_GENERATOR_DIVISOR;
                    350:     USHORT baudRateDivisor;
                    351: 
                    352:     SerMouPrint((2, "SERMOUSE-SetBaudRate: Enter\n"));
                    353: 
                    354:     baudRateDivisor = baudRateFactor / BaudRate;
                    355:     UARTSetDlab(Port, TRUE);
                    356:     WRITE_PORT_UCHAR(Port + ACE_DLL, (UCHAR)baudRateDivisor);
                    357:     WRITE_PORT_UCHAR(Port + ACE_DLM, (UCHAR)(baudRateDivisor >> 8));
                    358:     UARTSetDlab(Port, FALSE);
                    359:     SerMouPrint((2, "SERMOUSE-New BaudRate: %u\n", BaudRate));
                    360: 
                    361:     SerMouPrint((2, "SERMOUSE-SetBaudRate: Exit\n"));
                    362: 
                    363:     return;
                    364: }
                    365: 
                    366: 
                    367: VOID
                    368: UARTGetState(
                    369:     PUCHAR Port,
                    370:     PUART Uart,
                    371:     ULONG BaudClock
                    372:     )
                    373: /*++
                    374: 
                    375: Routine Description:
                    376: 
                    377:     Get the complete state of the serial port. May be used for save/restore.
                    378: 
                    379: Arguments:
                    380: 
                    381:     Port - Pointer to the serial port.
                    382: 
                    383:     Uart - Pointer to a serial port structure.
                    384: 
                    385:     BaudClock - The external frequency driving the serial chip.
                    386: 
                    387: Return Value:
                    388: 
                    389:     None.
                    390: 
                    391: --*/
                    392: {
                    393:     Uart->LineCtrl = UARTGetLineCtrl(Port);
                    394:     Uart->ModemCtrl = UARTGetModemCtrl(Port);
                    395:     Uart->InterruptCtrl = UARTGetInterruptCtrl(Port);
                    396:     Uart->BaudRate = UARTGetBaudRate(Port, BaudClock);
                    397: 
                    398:     return;
                    399: }
                    400: 
                    401: VOID
                    402: UARTSetState(
                    403:     PUCHAR Port,
                    404:     PUART Uart,
                    405:     ULONG BaudClock
                    406:     )
                    407: /*++
                    408: 
                    409: Routine Description:
                    410: 
                    411:     Set the complete state of a serial port.
                    412: 
                    413: Arguments:
                    414: 
                    415:     Port - Pointer to the serial port.
                    416: 
                    417:     Uart - Pointer to a serial port structure.
                    418: 
                    419:     BaudClock - The external frequency driving the serial chip.
                    420: 
                    421: Return Value:
                    422: 
                    423:     None.
                    424: 
                    425: --*/
                    426: {
                    427:     UARTSetLineCtrl(Port, Uart->LineCtrl);
                    428:     UARTSetModemCtrl(Port, Uart->ModemCtrl);
                    429:     UARTSetInterruptCtrl(Port, Uart->InterruptCtrl);
                    430:     UARTSetBaudRate(Port, Uart->BaudRate, BaudClock);
                    431: 
                    432:     return;
                    433: }
                    434: 
                    435: 
                    436: BOOLEAN
                    437: UARTIsReceiveBufferFull(
                    438:     PUCHAR Port
                    439:     )
                    440: /*++
                    441: 
                    442: Routine Description:
                    443: 
                    444:     Check whether the serial port input buffer is full.
                    445: 
                    446: Arguments:
                    447: 
                    448:     Port - Pointer to the serial port.
                    449: 
                    450: Return Value:
                    451: 
                    452:     TRUE if a character is present in the input buffer, otherwise FALSE.
                    453: 
                    454: --*/
                    455: {
                    456:     return READ_PORT_UCHAR(Port + ACE_LSR) & ACE_DR;
                    457: }
                    458: 
                    459: 
                    460: BOOLEAN
                    461: UARTReadCharNoWait(
                    462:     PUCHAR Port,
                    463:     PUCHAR Value
                    464:     )
                    465: /*++
                    466: 
                    467: Routine Description:
                    468: 
                    469:     Read a character from the serial port and return immediately.
                    470: 
                    471: Arguments:
                    472: 
                    473:     Port - Pointer to the serial port.
                    474: 
                    475:     Value - The character read from the serial port input buffer.
                    476: 
                    477: Return Value:
                    478: 
                    479:     TRUE if character has been read, FALSE otherwise.
                    480: 
                    481: --*/
                    482: {
                    483:     BOOLEAN charReady = FALSE;
                    484: 
                    485:     if ( UARTIsReceiveBufferFull(Port) ) {
                    486:         *Value = READ_PORT_UCHAR(Port + ACE_RBR);
                    487:         charReady = TRUE;
                    488:     }
                    489: 
                    490:     return charReady;
                    491: }
                    492: 
                    493: BOOLEAN
                    494: UARTReadChar(
                    495:     PUCHAR Port,
                    496:     PUCHAR Value,
                    497:     ULONG Timeout
                    498:     )
                    499: /*++
                    500: 
                    501: Routine Description:
                    502: 
                    503:     Read a character from the serial port.  Waits until a character has 
                    504:     been read or the timeout value is reached.
                    505: 
                    506: Arguments:
                    507: 
                    508:     Port - Pointer to the serial port.
                    509: 
                    510:     Value  - The character read from the serial port input buffer.
                    511: 
                    512:     Timeout - The timeout value in milliseconds for the read.
                    513: 
                    514: Return Value:
                    515: 
                    516:     TRUE if a character has been read, FALSE if a timeout occured.
                    517: 
                    518: --*/
                    519: {
                    520: 
                    521:     ULONG i, j;
                    522:     BOOLEAN returnValue = FALSE;
                    523: 
                    524: 
                    525:     //
                    526:     // Exit when a character is found or the timeout value is reached.
                    527:     //
                    528: 
                    529:     for (i = 0; i < Timeout; i++) {
                    530:         for (j = 0; j < MS_TO_MICROSECONDS; j++) {
                    531:             if ((returnValue = UARTReadCharNoWait(Port, Value)) == TRUE) {
                    532:     
                    533:                 //
                    534:                 // Got a character.
                    535:                 //
                    536:     
                    537:                 break;
                    538:             } else {
                    539:     
                    540:                 //
                    541:                 // Stall 1 microsecond and then try to read again.
                    542:                 //
                    543:     
                    544:                 KeStallExecutionProcessor(1);
                    545:             }
                    546:         }
                    547:         if (returnValue) {
                    548:             break;
                    549:         }
                    550:     }
                    551: 
                    552:     return(returnValue);
                    553: }
                    554: 
                    555: BOOLEAN
                    556: UARTFlushReadBuffer(
                    557:     PUCHAR Port
                    558:     )
                    559: /*++
                    560: 
                    561: Routine Description:
                    562: 
                    563:     Flush the serial port input buffer.
                    564: 
                    565: Arguments:
                    566: 
                    567:     Port - Pointer to the serial port.
                    568: 
                    569: Return Value:
                    570: 
                    571:     TRUE.
                    572: 
                    573: --*/
                    574: {
                    575:     UCHAR value;
                    576: 
                    577:     SerMouPrint((4, "SERMOUSE-UARTFlushReadBuffer: Enter\n"));
                    578:     while (UARTReadCharNoWait(Port, &value)) {
                    579:         /* Nothing */
                    580:     }
                    581:     SerMouPrint((4, "SERMOUSE-UARTFlushReadBuffer: Exit\n"));
                    582: 
                    583:     return TRUE;
                    584: }
                    585: 
                    586: 
                    587: BOOLEAN
                    588: UARTIsTransmitEmpty(
                    589:     PUCHAR Port
                    590:     )
                    591: /*++
                    592: 
                    593: Routine Description:
                    594: 
                    595:      Check whether the serial port transmit buffer is empty.
                    596: 
                    597:      Note: We also check whether the shift register is empty. This is 
                    598:      not critical in our case, but allows some more delay between characters
                    599:      sent to a device. (Safe, safe...)
                    600: 
                    601: Arguments:
                    602: 
                    603:     Port - Pointer to the serial port.
                    604: 
                    605: Return Value:
                    606: 
                    607:     TRUE if the serial port transmit buffer is empty.
                    608: 
                    609: --*/
                    610: {
                    611:     return ((READ_PORT_UCHAR((PUCHAR) (Port + ACE_LSR)) &
                    612:                 (ACE_TSRE | ACE_THRE)) == (ACE_THRE | ACE_TSRE));
                    613: }
                    614: 
                    615: 
                    616: BOOLEAN
                    617: UARTWriteChar(
                    618:     PUCHAR Port,
                    619:     UCHAR Value
                    620:     )
                    621: /*++
                    622: 
                    623: Routine Description:
                    624: 
                    625:      Write a character to a serial port. Make sure the transmit buffer 
                    626:      is empty before we write there.
                    627: 
                    628: Arguments:
                    629: 
                    630:     Port - Pointer to the serial port.
                    631: 
                    632:     Value - Value to write to the serial port.
                    633: 
                    634: Return Value:
                    635: 
                    636:     TRUE.
                    637: 
                    638: --*/
                    639: {
                    640:     while (!UARTIsTransmitEmpty(Port)) {
                    641:         /* Nothing */
                    642:     }
                    643:     WRITE_PORT_UCHAR(Port + ACE_THR, Value);
                    644: 
                    645:     return TRUE;
                    646: }
                    647: 
                    648: BOOLEAN
                    649: UARTWriteString(
                    650:     PUCHAR Port,
                    651:     PSZ Buffer
                    652:     )
                    653: /*++
                    654: 
                    655: Routine Description:
                    656: 
                    657:     Write a zero-terminated string to the serial port.
                    658: 
                    659: Arguments:
                    660: 
                    661:     Port - Pointer to the serial port.
                    662: 
                    663:     Buffer - Pointer to a zero terminated string to write to 
                    664:         the serial port.
                    665: 
                    666: Return Value:
                    667: 
                    668:     TRUE.
                    669: 
                    670: --*/
                    671: {
                    672:     PSZ current = Buffer;
                    673: 
                    674:     while (*current) {
                    675:         UARTWriteChar(Port, *current++);
                    676:     }
                    677: 
                    678:     return TRUE;
                    679: }

unix.superglobalmegacorp.com

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