Annotation of ntddk/src/input/sermouse/uart.c, revision 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.