mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
Replace polling mode in IRP_MJ_READ by an interrupt mode.
It is a lot less CPU consuming... svn path=/trunk/; revision=14485
This commit is contained in:
parent
ad17913046
commit
6514e33a95
4 changed files with 149 additions and 124 deletions
|
@ -64,29 +64,37 @@ VOID STDCALL
|
|||
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 @@ SerialSendByte(
|
|||
PUCHAR ComPortBase;
|
||||
UCHAR Byte;
|
||||
KIRQL Irql;
|
||||
UCHAR IER;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension;
|
||||
|
@ -113,9 +122,15 @@ SerialSendByte(
|
|||
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 @@ SerialInterruptService(
|
|||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
UCHAR Byte;
|
||||
PUCHAR ComPortBase;
|
||||
UCHAR Iir;
|
||||
|
||||
|
@ -139,32 +153,32 @@ SerialInterruptService(
|
|||
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:
|
||||
|
|
|
@ -78,6 +78,7 @@ SerialAddDeviceInternal(
|
|||
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 @@ SerialPnpStartDevice(
|
|||
UNICODE_STRING ComPort;
|
||||
ULONG Vector = 0;
|
||||
ULONG i, j;
|
||||
UCHAR IER;
|
||||
KIRQL Dirql;
|
||||
KAFFINITY Affinity = 0;
|
||||
KINTERRUPT_MODE InterruptMode = Latched;
|
||||
|
@ -195,8 +197,6 @@ SerialPnpStartDevice(
|
|||
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 @@ SerialPnpStartDevice(
|
|||
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 @@ SerialPnpStartDevice(
|
|||
|
||||
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 @@ SerialPnp(
|
|||
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);
|
||||
|
|
|
@ -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,83 +29,80 @@ ReadBytes(
|
|||
PUCHAR ComPortBase;
|
||||
ULONG Length;
|
||||
PUCHAR Buffer;
|
||||
ULONG Information = 0;
|
||||
LARGE_INTEGER SystemTime, ByteTimeoutTime;
|
||||
UCHAR ReceivedByte;
|
||||
BOOLEAN IsByteReceived;
|
||||
//KIRQL Irql;
|
||||
|
||||
DPRINT("Serial: ReadBytes() called\n");
|
||||
KTIMER TotalTimeoutTimer;
|
||||
KIRQL Irql;
|
||||
ULONG ObjectCount;
|
||||
PVOID ObjectsArray[2];
|
||||
ULONG Information = 0;
|
||||
NTSTATUS Status;
|
||||
|
||||
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;
|
||||
|
||||
IsByteReceived = FALSE;
|
||||
while (TRUE)
|
||||
/* read already received bytes from buffer */
|
||||
KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
|
||||
while (!IsCircularBufferEmpty(&DeviceExtension->InputBuffer)
|
||||
&& Length > 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;
|
||||
}
|
||||
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);
|
||||
|
||||
if (WorkItemData->DontWait
|
||||
&& !(WorkItemData->ReadAtLeastOneByte && Information == 0))
|
||||
{
|
||||
DPRINT("Serial: buffer empty. Don't wait more bytes\n");
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (!IsByteReceived) break;
|
||||
Buffer[Information++] = ReceivedByte;
|
||||
Length--;
|
||||
}
|
||||
/* 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)
|
||||
|
@ -148,8 +144,6 @@ SerialRead(
|
|||
|
||||
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 @@ SerialRead(
|
|||
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)
|
||||
|
|
|
@ -54,10 +54,12 @@ typedef enum
|
|||
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 @@ typedef struct _SERIAL_DEVICE_EXTENSION
|
|||
|
||||
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 @@ typedef struct _WORKITEM_DATA
|
|||
|
||||
BOOLEAN UseIntervalTimeout;
|
||||
BOOLEAN UseTotalTimeout;
|
||||
ULONG IntervalTimeout;
|
||||
LARGE_INTEGER IntervalTimeout;
|
||||
LARGE_INTEGER TotalTimeoutTime;
|
||||
BOOLEAN DontWait;
|
||||
BOOLEAN ReadAtLeastOneByte;
|
||||
|
@ -120,22 +122,28 @@ typedef struct _WORKITEM_DATA
|
|||
|
||||
/* 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 @@ typedef struct _WORKITEM_DATA
|
|||
#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 @@ typedef struct _WORKITEM_DATA
|
|||
#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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue