[NTFS] - Fix increasing the mft size, to keep chkdsk happy.
[reactos.git] / drivers / serial / serial / legacy.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Serial port driver
4 * FILE: drivers/bus/serial/legacy.c
5 * PURPOSE: Legacy serial port enumeration
6 *
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
8 * Mark Junker (mjscod@gmx.de)
9 */
10
11 #include "serial.h"
12
13 #include <debug.h>
14
15 UART_TYPE
16 SerialDetectUartType(
17 IN PUCHAR BaseAddress)
18 {
19 UCHAR Lcr, TestLcr;
20 UCHAR OldScr, Scr5A, ScrA5;
21 BOOLEAN FifoEnabled;
22 UCHAR NewFifoStatus;
23
24 Lcr = READ_PORT_UCHAR(SER_LCR(BaseAddress));
25 WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr ^ 0xFF);
26 TestLcr = READ_PORT_UCHAR(SER_LCR(BaseAddress)) ^ 0xFF;
27 WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr);
28
29 /* Accessing the LCR must work for a usable serial port */
30 if (TestLcr != Lcr)
31 return UartUnknown;
32
33 /* Ensure that all following accesses are done as required */
34 READ_PORT_UCHAR(SER_RBR(BaseAddress));
35 READ_PORT_UCHAR(SER_IER(BaseAddress));
36 READ_PORT_UCHAR(SER_IIR(BaseAddress));
37 READ_PORT_UCHAR(SER_LCR(BaseAddress));
38 READ_PORT_UCHAR(SER_MCR(BaseAddress));
39 READ_PORT_UCHAR(SER_LSR(BaseAddress));
40 READ_PORT_UCHAR(SER_MSR(BaseAddress));
41 READ_PORT_UCHAR(SER_SCR(BaseAddress));
42
43 /* Test scratch pad */
44 OldScr = READ_PORT_UCHAR(SER_SCR(BaseAddress));
45 WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0x5A);
46 Scr5A = READ_PORT_UCHAR(SER_SCR(BaseAddress));
47 WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0xA5);
48 ScrA5 = READ_PORT_UCHAR(SER_SCR(BaseAddress));
49 WRITE_PORT_UCHAR(SER_SCR(BaseAddress), OldScr);
50
51 /* When non-functional, we have a 8250 */
52 if (Scr5A != 0x5A || ScrA5 != 0xA5)
53 return Uart8250;
54
55 /* Test FIFO type */
56 FifoEnabled = (READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0x80) != 0;
57 WRITE_PORT_UCHAR(SER_FCR(BaseAddress), SR_FCR_ENABLE_FIFO);
58 NewFifoStatus = READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0xC0;
59 if (!FifoEnabled)
60 WRITE_PORT_UCHAR(SER_FCR(BaseAddress), 0);
61 switch (NewFifoStatus)
62 {
63 case 0x00:
64 return Uart16450;
65 case 0x40:
66 case 0x80:
67 /* Not sure about this but the documentation says that 0x40
68 * indicates an unusable FIFO but my tests only worked
69 * with 0x80 */
70 return Uart16550;
71 }
72
73 /* FIFO is only functional for 16550A+ */
74 return Uart16550A;
75 }