Replace polling mode in IRP_MJ_READ by an interrupt mode.
It is a lot less CPU consuming...
Modified: trunk/reactos/drivers/dd/serial/misc.c
Modified: trunk/reactos/drivers/dd/serial/pnp.c
Modified: trunk/reactos/drivers/dd/serial/rw.c
Modified: trunk/reactos/drivers/dd/serial/serial.h

Modified: trunk/reactos/drivers/dd/serial/misc.c
--- trunk/reactos/drivers/dd/serial/misc.c	2005-04-03 21:31:41 UTC (rev 14484)
+++ trunk/reactos/drivers/dd/serial/misc.c	2005-04-03 21:36:15 UTC (rev 14485)
@@ -64,29 +64,37 @@
 SerialReceiveByte(
 	IN PKDPC Dpc,
 	IN PVOID pDeviceExtension, // real type PSERIAL_DEVICE_EXTENSION
-	IN PVOID pByte,            // real type UCHAR
-	IN PVOID Unused)
+	IN PVOID Unused1,
+	IN PVOID Unused2)
 {
 	PSERIAL_DEVICE_EXTENSION DeviceExtension;
+	PUCHAR ComPortBase;
 	UCHAR Byte;
 	KIRQL Irql;
+	UCHAR IER;
 	NTSTATUS Status;
 	
 	DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension;
-	Byte = (UCHAR)(ULONG_PTR)pByte;
-	DPRINT1("Serial: received byte on COM%lu: 0x%02x (%c)\n",
-		DeviceExtension->ComPort, Byte, Byte);
+	ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
 	
 	KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
-	Status = PushCircularBufferEntry(&DeviceExtension->InputBuffer, Byte);
-	if (!NT_SUCCESS(Status))
+	while (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR)
 	{
-		/* FIXME: count buffer overflow */
-		return;
+		Byte = READ_PORT_UCHAR(SER_RBR(ComPortBase));
+		DPRINT("Serial: Byte received on COM%lu: 0x%02x\n",
+			DeviceExtension->ComPort, Byte);
+		Status = PushCircularBufferEntry(&DeviceExtension->InputBuffer, Byte);
+		if (NT_SUCCESS(Status))
+			DeviceExtension->SerialPerfStats.ReceivedCount++;
+		else
+			DeviceExtension->SerialPerfStats.BufferOverrunErrorCount++;
 	}
-	DPRINT1("Serial: push to buffer done\n");
+	KeSetEvent(&DeviceExtension->InputBufferNotEmpty, 0, FALSE);
 	KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
-	InterlockedIncrement(&DeviceExtension->SerialPerfStats.ReceivedCount);
+	
+	/* allow new interrupts */
+	IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
+	WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_DATA_RECEIVED);
 }
 
 VOID STDCALL
@@ -100,6 +108,7 @@
 	PUCHAR ComPortBase;
 	UCHAR Byte;
 	KIRQL Irql;
+	UCHAR IER;
 	NTSTATUS Status;
 	
 	DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension;
@@ -113,9 +122,15 @@
 		if (!NT_SUCCESS(Status))
 			break;
 		WRITE_PORT_UCHAR(SER_THR(ComPortBase), Byte);
+		DPRINT("Serial: Byte sent to COM%lu: 0x%02x\n",
+			DeviceExtension->ComPort, Byte);
 		DeviceExtension->SerialPerfStats.TransmittedCount++;
-	}	
+	}
 	KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
+	
+	/* allow new interrupts */
+	IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
+	WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_THR_EMPTY);
 }
 
 BOOLEAN STDCALL
@@ -125,7 +140,6 @@
 {
 	PDEVICE_OBJECT DeviceObject;
 	PSERIAL_DEVICE_EXTENSION DeviceExtension;
-	UCHAR Byte;
 	PUCHAR ComPortBase;
 	UCHAR Iir;
 	
@@ -139,32 +153,32 @@
 	Iir &= SR_IIR_ID_MASK;
 	if ((Iir & SR_IIR_SELF) != 0) { return FALSE; }
 	
-	/* FIXME: sometimes, update DeviceExtension->IER */
 	/* FIXME: sometimes, update DeviceExtension->MCR */
 	switch (Iir)
 	{
 		case SR_IIR_MSR_CHANGE:
 		{
+			UCHAR IER;
 			DPRINT1("Serial: SR_IIR_MSR_CHANGE\n");
+			
 			DeviceExtension->MSR = READ_PORT_UCHAR(SER_MSR(ComPortBase));
 			/* FIXME: what to do? */
+			IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
+			WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_MSR_CHANGE);
 			return TRUE;
 		}
 		case SR_IIR_THR_EMPTY:
 		{
 			DPRINT("Serial: SR_IIR_THR_EMPTY\n");
-			return KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL);
+			
+			KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL);
+			return TRUE;
 		}
 		case SR_IIR_DATA_RECEIVED:
 		{
-			DPRINT1("Serial: SR_IIR_DATA_RECEIVED\n");
-			while (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR)
-			{
-				Byte = READ_PORT_UCHAR(SER_RBR(ComPortBase));
-				DPRINT1("Serial: Byte received: 0x%02x (%c)\n", Byte, Byte);
-				if (!KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, (PVOID)(ULONG_PTR)Byte, NULL))
-					break;
-			}
+			DPRINT("Serial: SR_IIR_DATA_RECEIVED\n");
+			
+			KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, NULL, NULL);
 			return TRUE;
 		}
 		case SR_IIR_ERROR:

Modified: trunk/reactos/drivers/dd/serial/pnp.c
--- trunk/reactos/drivers/dd/serial/pnp.c	2005-04-03 21:31:41 UTC (rev 14484)
+++ trunk/reactos/drivers/dd/serial/pnp.c	2005-04-03 21:36:15 UTC (rev 14485)
@@ -78,6 +78,7 @@
 	IoInitializeRemoveLock(&DeviceExtension->RemoveLock, SERIAL_TAG, 0, 0);
 	KeInitializeSpinLock(&DeviceExtension->InputBufferLock);
 	KeInitializeSpinLock(&DeviceExtension->OutputBufferLock);
+	KeInitializeEvent(&DeviceExtension->InputBufferNotEmpty, NotificationEvent, FALSE);
 	KeInitializeDpc(&DeviceExtension->ReceivedByteDpc, SerialReceiveByte, DeviceExtension);
 	KeInitializeDpc(&DeviceExtension->SendByteDpc, SerialSendByte, DeviceExtension);
 	Fdo->Flags |= DO_POWER_PAGABLE;
@@ -144,6 +145,7 @@
 	UNICODE_STRING ComPort;
 	ULONG Vector = 0;
 	ULONG i, j;
+	UCHAR IER;
 	KIRQL Dirql;
 	KAFFINITY Affinity = 0;
 	KINTERRUPT_MODE InterruptMode = Latched;
@@ -195,8 +197,6 @@
 		DeviceExtension->BaseAddress, Dirql);
 	if (!DeviceExtension->BaseAddress)
 		return STATUS_INSUFFICIENT_RESOURCES;
-	/* FIXME: we should be able to continue and use polling method
-	 * for read/write if we don't have an interrupt */
 	if (!Dirql)
 		return STATUS_INSUFFICIENT_RESOURCES;
 	ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
@@ -205,7 +205,6 @@
 		DeviceExtension->UartType = SerialDetectUartType(ComPortBase);
 	
 	/* Get current settings */
-	DeviceExtension->IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
 	DeviceExtension->MCR = READ_PORT_UCHAR(SER_MCR(ComPortBase));
 	DeviceExtension->MSR = READ_PORT_UCHAR(SER_MSR(ComPortBase));
 	DeviceExtension->WaitMask = 0;
@@ -279,11 +278,13 @@
 	
 	DeviceExtension->PnpState = dsStarted;
 	
-	DeviceExtension->IER |= 0x1f; /* Activate interrupt mode */
-	DeviceExtension->IER &= ~1; /* FIXME: Disable receive byte interrupt */
-	WRITE_PORT_UCHAR(SER_IER(ComPortBase), DeviceExtension->IER);
+	/* Activate interrupt modes */
+	IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
+	IER |= SR_IER_DATA_RECEIVED | SR_IER_THR_EMPTY | SR_IER_LSR_CHANGE | SR_IER_MSR_CHANGE;
+	WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER);
 	
-	DeviceExtension->MCR |= 0x03; /* Activate DTR, RTS */
+	/* Activate DTR, RTS */
+	DeviceExtension->MCR |= SR_MCR_DTR | SR_MCR_RTS;
 	WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
 	
 	return STATUS_SUCCESS;
@@ -331,11 +332,19 @@
 				ULONG Irq;
 				
 				DPRINT1("Serial: no allocated resources for this device! Creating fake list\n");
-				/* These values are resources of the ONLY serial
-				 * port that will be managed by this driver
-				 * (default is COM2) */
-				ComPortBase = 0x2f8;
-				Irq = 3;
+				switch (((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->SerialPortNumber)
+				{
+					case 0:
+						ComPortBase = 0x3f8;
+						Irq = 4;
+						break;
+					case 1:
+						ComPortBase = 0x2f8;
+						Irq = 3;
+						break;
+					default:
+						ComPortBase = Irq = 0;
+				}
 				
 				/* Create resource list */
 				ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);

Modified: trunk/reactos/drivers/dd/serial/rw.c
--- trunk/reactos/drivers/dd/serial/rw.c	2005-04-03 21:31:41 UTC (rev 14484)
+++ trunk/reactos/drivers/dd/serial/rw.c	2005-04-03 21:36:15 UTC (rev 14485)
@@ -7,7 +7,6 @@
  * 
  * PROGRAMMERS:     HervÚ Poussineau (poussine@freesurf.fr)
  */
-/* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */
 
 #define NDEBUG
 #include "serial.h"
@@ -30,84 +29,81 @@
 	PUCHAR ComPortBase;
 	ULONG Length;
 	PUCHAR Buffer;
-	ULONG Information = 0;
-	LARGE_INTEGER SystemTime, ByteTimeoutTime;
 	UCHAR ReceivedByte;
-	BOOLEAN IsByteReceived;
-	//KIRQL Irql;
+	KTIMER TotalTimeoutTimer;
+	KIRQL Irql;
+	ULONG ObjectCount;
+	PVOID ObjectsArray[2];
+	ULONG Information = 0;
+	NTSTATUS Status;
 	
-	DPRINT("Serial: ReadBytes() called\n");
-	
 	DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 	ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
 	Length = IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length;
 	Buffer = SerialGetUserBuffer(Irp);
 	
-	/* FIXME: remove disabling interrupts */
-	WRITE_PORT_UCHAR(SER_IER(ComPortBase), DeviceExtension->IER & ~1);
+	DPRINT("Serial: UseIntervalTimeout = %s, IntervalTimeout = %lu\n",
+		WorkItemData->UseIntervalTimeout ? "YES" : "NO",
+		WorkItemData->UseIntervalTimeout ? WorkItemData->IntervalTimeout.QuadPart : 0);
+	DPRINT("Serial: UseTotalTimeout = %s\n",
+		WorkItemData->UseTotalTimeout ? "YES" : "NO");
+	
+	ObjectCount = 1;
+	ObjectsArray[0] = &DeviceExtension->InputBufferNotEmpty;
+	if (WorkItemData->UseTotalTimeout)
+	{
+		KeInitializeTimer(&TotalTimeoutTimer);
+		KeSetTimer(&TotalTimeoutTimer, WorkItemData->TotalTimeoutTime, NULL);
+		ObjectsArray[ObjectCount] = &TotalTimeoutTimer;
+		ObjectCount++;
+	}
+	
+	/* while buffer is not fully filled */
 	while (Length > 0)
 	{
-		/* Calculate dead line to receive the next byte */
-		KeQuerySystemTime(&SystemTime);
-		ByteTimeoutTime.QuadPart = SystemTime.QuadPart +
-			WorkItemData->IntervalTimeout * 10000;
+		/* read already received bytes from buffer */
+		KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
+		while (!IsCircularBufferEmpty(&DeviceExtension->InputBuffer)
+			&& Length > 0)
+		{
+			PopCircularBufferEntry(&DeviceExtension->InputBuffer, &ReceivedByte);
+			DPRINT("Serial: reading byte from buffer: 0x%02x\n", ReceivedByte);
+			
+			Buffer[Information++] = ReceivedByte;
+			Length--;
+		}
+		KeClearEvent(&DeviceExtension->InputBufferNotEmpty);
+		KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
 		
-		IsByteReceived = FALSE;
-		while (TRUE)
+		if (WorkItemData->DontWait
+			&& !(WorkItemData->ReadAtLeastOneByte && Information == 0))
 		{
-#if 1
-			if ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR) != 0)
-			{
-				ReceivedByte = READ_PORT_UCHAR(ComPortBase);
-				DPRINT("Serial: received byte 0x%02x (%c)\n", ReceivedByte, ReceivedByte);
-				IsByteReceived = TRUE;
-				break;
-			}
-			else if (WorkItemData->DontWait &&
-			         !(WorkItemData->ReadAtLeastOneByte && Information == 0))
-			{
-				DPRINT("Serial: read buffer empty\n");
-				break;
-			}
-#else
-			KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
-			if (!IsCircularBufferEmpty(&DeviceExtension->InputBuffer))
-			{
-				CHECKPOINT1;
-				PopCircularBufferEntry(&DeviceExtension->InputBuffer, &ReceivedByte);
-				KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
-				DPRINT("Serial: reading byte from buffer 0x%02x (%c)\n", ReceivedByte, ReceivedByte);
-				IsByteReceived = TRUE;
-				break;
-			}
-			else if (WorkItemData->DontWait &&
-			         !(WorkItemData->ReadAtLeastOneByte && Information == 0))
-			{
-				DPRINT("Serial: read buffer empty\n");
-				break;
-			}
-			KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
-#endif
-			if (IsByteReceived) break;
-			KeQuerySystemTime(&SystemTime);
-			if (WorkItemData->UseIntervalTimeout && Information > 0)
-			{
-				if (SystemTime.QuadPart >= ByteTimeoutTime.QuadPart)
-					break;
-			}
-			if (WorkItemData->UseTotalTimeout)
-			{
-				if (SystemTime.QuadPart >= WorkItemData->TotalTimeoutTime.QuadPart)
-					break;
-			}
+			DPRINT("Serial: buffer empty. Don't wait more bytes\n");
+			break;
 		}
-		if (!IsByteReceived) break;
-		Buffer[Information++] = ReceivedByte;
-		Length--;
+		
+		Status = KeWaitForMultipleObjects(
+			ObjectCount,
+			ObjectsArray,
+			WaitAny,
+			Executive,
+			KernelMode,
+			FALSE,
+			(WorkItemData->UseIntervalTimeout && Information > 0) ? &WorkItemData->IntervalTimeout : NULL,
+			NULL);
+		
+		if (Status == STATUS_TIMEOUT /* interval timeout */
+			|| Status == STATUS_WAIT_1) /* total timeout */
+		{
+			DPRINT("Serial: timeout when reading bytes. Status = 0x%08lx\n", Status);
+			break;
+		}
 	}
-	/* FIXME: remove enabling interrupts */
-	WRITE_PORT_UCHAR(SER_IER(ComPortBase), DeviceExtension->IER);
 	
+	/* stop total timeout timer */
+	if (WorkItemData->UseTotalTimeout)
+		KeCancelTimer(&TotalTimeoutTimer);
+	
 	Irp->IoStatus.Information = Information;
 	if (Information == 0)
 		Irp->IoStatus.Status = STATUS_TIMEOUT;
@@ -148,8 +144,6 @@
 	
 	DPRINT("Serial: IRP_MJ_READ\n");
 	
-	/* FIXME: pend operation if possible */
-	
 	Stack = IoGetCurrentIrpStackLocation(Irp);
 	Length = Stack->Parameters.Read.Length;
 	Buffer = SerialGetUserBuffer(Irp);
@@ -200,7 +194,7 @@
 		if (DeviceExtension->SerialTimeOuts.ReadIntervalTimeout != 0)
 			{
 				WorkItemData->UseIntervalTimeout = TRUE;
-				WorkItemData->IntervalTimeout = DeviceExtension->SerialTimeOuts.ReadIntervalTimeout;
+				WorkItemData->IntervalTimeout.QuadPart = DeviceExtension->SerialTimeOuts.ReadIntervalTimeout;
 		}
 		if (DeviceExtension->SerialTimeOuts.ReadTotalTimeoutMultiplier != 0 ||
 			 DeviceExtension->SerialTimeOuts.ReadTotalTimeoutConstant != 0)

Modified: trunk/reactos/drivers/dd/serial/serial.h
--- trunk/reactos/drivers/dd/serial/serial.h	2005-04-03 21:31:41 UTC (rev 14484)
+++ trunk/reactos/drivers/dd/serial/serial.h	2005-04-03 21:36:15 UTC (rev 14485)
@@ -54,10 +54,12 @@
 typedef enum
 {
 	UartUnknown,
-	Uart8250,
-	Uart16450,
-	Uart16550,
-	Uart16550A
+	Uart8250,  /* initial version */
+	Uart16450, /* + 38.4 Kbps */
+	Uart16550, /* + 115 Kbps */
+	Uart16550A,/* + FIFO 16 bytes */
+	Uart16650, /* + FIFO 32 bytes, 230 Kbps, power management, auto-flow */
+	Uart16750  /* + FIFO 64 bytes, 460 Kbps */
 } UART_TYPE;
 
 typedef struct _CIRCULAR_BUFFER
@@ -90,14 +92,14 @@
 	
 	SERIALPERF_STATS SerialPerfStats;
 	SERIAL_TIMEOUTS SerialTimeOuts;
-	BOOLEAN IsOpened;	
+	BOOLEAN IsOpened;
+	KEVENT InputBufferNotEmpty;
 	CIRCULAR_BUFFER InputBuffer;
 	KSPIN_LOCK InputBufferLock;
 	CIRCULAR_BUFFER OutputBuffer;
 	KSPIN_LOCK OutputBufferLock;
 	
 	/* Current values */
-	UCHAR IER; /* Base+1, Interrupt Enable Register */
 	UCHAR MCR; /* Base+4, Modem Control Register */
 	UCHAR MSR; /* Base+6, Modem Status Register */
 } SERIAL_DEVICE_EXTENSION, *PSERIAL_DEVICE_EXTENSION;
@@ -108,7 +110,7 @@
 	
 	BOOLEAN UseIntervalTimeout;
 	BOOLEAN UseTotalTimeout;
-	ULONG IntervalTimeout;
+	LARGE_INTEGER IntervalTimeout;
 	LARGE_INTEGER TotalTimeoutTime;
 	BOOLEAN DontWait;
 	BOOLEAN ReadAtLeastOneByte;
@@ -120,22 +122,28 @@
 
 /* Baud master clock */
 #define BAUD_CLOCK      1843200
-#define CLOCKS_PER_BIT  16 
+#define CLOCKS_PER_BIT  16
 
 /* UART registers and bits */
-#define   SER_RBR(x)   ((x)+0)
-#define   SER_THR(x)   ((x)+0)
-#define   SER_DLL(x)   ((x)+0)
-#define   SER_IER(x)   ((x)+1)
-#define   SER_DLM(x)   ((x)+1)
-#define   SER_IIR(x)   ((x)+2)
+#define   SER_RBR(x)   ((x)+0) /* Receive Register */
+#define   SER_THR(x)   ((x)+0) /* Transmit Register */
+#define   SER_DLL(x)   ((x)+0) /* Baud Rate Divisor LSB */
+#define   SER_IER(x)   ((x)+1) /* Interrupt Enable Register */
+#define     SR_IER_DATA_RECEIVED 0x01
+#define     SR_IER_THR_EMPTY     0x02
+#define     SR_IER_LSR_CHANGE    0x04
+#define     SR_IER_MSR_CHANGE    0x08
+#define     SR_IER_SLEEP_MODE    0x10 /* Uart >= 16750 */
+#define     SR_IER_LOW_POWER     0x20 /* Uart >= 16750 */
+#define   SER_DLM(x)   ((x)+1) /* Baud Rate Divisor MSB */
+#define   SER_IIR(x)   ((x)+2) /* Interrupt Identification Register */
 #define     SR_IIR_SELF          0x00
 #define     SR_IIR_ID_MASK       0x07
 #define     SR_IIR_MSR_CHANGE    SR_IIR_SELF
 #define     SR_IIR_THR_EMPTY     (SR_IIR_SELF | 2)
 #define     SR_IIR_DATA_RECEIVED (SR_IIR_SELF | 4)
 #define     SR_IIR_ERROR         (SR_IIR_SELF | 6)
-#define   SER_FCR(x)   ((x)+2)
+#define   SER_FCR(x)   ((x)+2) /* FIFO Control Register (Uart >= 16550A) */
 #define     SR_FCR_ENABLE_FIFO 0x01
 #define     SR_FCR_CLEAR_RCVR  (0x02 | SR_FCR_ENABLE_FIFO)
 #define     SR_FCR_CLEAR_XMIT  (0x04 | SR_FCR_ENABLE_FIFO)
@@ -143,7 +151,7 @@
 #define     SR_FCR_4_BYTES     (0x40 | SR_FCR_ENABLE_FIFO)
 #define     SR_FCR_8_BYTES     (0x80 | SR_FCR_ENABLE_FIFO)
 #define     SR_FCR_14_BYTES    (0xC0 | SR_FCR_ENABLE_FIFO)
-#define   SER_LCR(x)   ((x)+3)
+#define   SER_LCR(x)   ((x)+3) /* Line Control Register */
 #define     SR_LCR_CS5 0x00
 #define     SR_LCR_CS6 0x01
 #define     SR_LCR_CS7 0x02
@@ -157,16 +165,16 @@
 #define     SR_LCR_PSP 0x38
 #define     SR_LCR_BRK 0x40
 #define     SR_LCR_DLAB 0x80
-#define   SER_MCR(x)   ((x)+4)
+#define   SER_MCR(x)   ((x)+4) /* Modem Control Register */
 #define     SR_MCR_DTR 0x01
 #define     SR_MCR_RTS 0x02
-#define   SER_LSR(x)   ((x)+5)
+#define   SER_LSR(x)   ((x)+5) /* Line Status Register */
 #define     SR_LSR_DR  0x01
 #define     SR_LSR_TBE 0x20
-#define   SER_MSR(x)   ((x)+6)
+#define   SER_MSR(x)   ((x)+6) /* Modem Status Register */
 #define     SR_MSR_CTS 0x10
 #define     SR_MSR_DSR 0x20
-#define   SER_SCR(x)   ((x)+7)
+#define   SER_SCR(x)   ((x)+7) /* Scratch Pad Register */
 
 /************************************ circularbuffer.c */