Modified: trunk/reactos/drivers/dd/serial/circularbuffer.c
Modified: trunk/reactos/drivers/dd/serial/devctrl.c
Modified: trunk/reactos/drivers/dd/serial/pnp.c
Modified: trunk/reactos/drivers/dd/serial/serial.h
--- trunk/reactos/drivers/dd/serial/circularbuffer.c 2005-03-22 20:15:04 UTC (rev 14272)
+++ trunk/reactos/drivers/dd/serial/circularbuffer.c 2005-03-22 22:10:44 UTC (rev 14273)
@@ -8,7 +8,7 @@
* PROGRAMMERS: HervÚ Poussineau (poussine@freesurf.fr)
*/
-//#define NDEBUG
+#define NDEBUG
#include "serial.h"
NTSTATUS
@@ -16,7 +16,8 @@
IN PCIRCULAR_BUFFER pBuffer,
IN ULONG BufferSize)
{
- pBuffer->Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize * sizeof(UCHAR), SERIAL_TAG);
+ DPRINT("Serial: InitializeCircularBuffer(pBuffer %p, BufferSize %lu)\n", pBuffer, BufferSize);
+ pBuffer->Buffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, BufferSize * sizeof(UCHAR), SERIAL_TAG);
if (!pBuffer->Buffer)
return STATUS_INSUFFICIENT_RESOURCES;
pBuffer->Length = BufferSize;
@@ -28,6 +29,7 @@
FreeCircularBuffer(
IN PCIRCULAR_BUFFER pBuffer)
{
+ DPRINT("Serial: FreeCircularBuffer(pBuffer %p)\n", pBuffer);
ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);
return STATUS_SUCCESS;
}
@@ -36,6 +38,7 @@
IsCircularBufferEmpty(
IN PCIRCULAR_BUFFER pBuffer)
{
+ DPRINT("Serial: IsCircularBufferEmpty(pBuffer %p)\n", pBuffer);
return (pBuffer->ReadPosition == pBuffer->WritePosition);
}
@@ -44,6 +47,7 @@
IN PCIRCULAR_BUFFER pBuffer,
IN UCHAR Entry)
{
+ DPRINT("Serial: PushCircularBufferEntry(pBuffer %p, Entry 0x%x)\n", pBuffer, Entry);
ASSERT(pBuffer->Length);
ULONG NextPosition = (pBuffer->WritePosition + 1) % pBuffer->Length;
if (NextPosition == pBuffer->ReadPosition)
@@ -58,6 +62,7 @@
IN PCIRCULAR_BUFFER pBuffer,
OUT PUCHAR Entry)
{
+ DPRINT("Serial: PopCircularBufferEntry(pBuffer %p)\n", pBuffer);
ASSERT(pBuffer->Length);
if (IsCircularBufferEmpty(pBuffer))
return STATUS_ARRAY_BOUNDS_EXCEEDED;
@@ -65,3 +70,27 @@
pBuffer->ReadPosition = (pBuffer->ReadPosition + 1) % pBuffer->Length;
return STATUS_SUCCESS;
}
+
+NTSTATUS
+IncreaseCircularBufferSize(
+ IN PCIRCULAR_BUFFER pBuffer,
+ IN ULONG NewBufferSize)
+{
+ PUCHAR NewBuffer;
+
+ DPRINT("Serial: IncreaseCircularBufferSize(pBuffer %p, NewBufferSize %lu)\n", pBuffer, NewBufferSize);
+ ASSERT(pBuffer->Length);
+ if (pBuffer->Length > NewBufferSize)
+ return STATUS_INVALID_PARAMETER;
+ else if (pBuffer->Length == NewBufferSize)
+ return STATUS_SUCCESS;
+
+ NewBuffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, NewBufferSize * sizeof(UCHAR), SERIAL_TAG);
+ if (!NewBuffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ RtlCopyMemory(NewBuffer, pBuffer->Buffer, pBuffer->Length * sizeof(UCHAR));
+ ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);
+ pBuffer->Buffer = NewBuffer;
+ pBuffer->Length = NewBufferSize;
+ return STATUS_SUCCESS;
+}
--- trunk/reactos/drivers/dd/serial/devctrl.c 2005-03-22 20:15:04 UTC (rev 14272)
+++ trunk/reactos/drivers/dd/serial/devctrl.c 2005-03-22 22:10:44 UTC (rev 14273)
@@ -60,16 +60,13 @@
{
UCHAR Lcr;
DPRINT("Serial: SerialSetBaudRate(COM%lu, %lu Bauds)\n", DeviceExtension->ComPort, BaudRate);
- /* FIXME: update DeviceExtension->LowerDevice when modifying LCR? */
/* Set Bit 7 of LCR to expose baud registers */
Lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase));
- Lcr |= SR_LCR_DLAB;
- WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr);
+ WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr | SR_LCR_DLAB);
/* Write the baud rate */
WRITE_PORT_UCHAR(SER_DLL(ComPortBase), divisor & 0xff);
WRITE_PORT_UCHAR(SER_DLM(ComPortBase), divisor >> 8);
/* Switch back to normal registers */
- Lcr ^= SR_LCR_DLAB;
WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr);
IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
@@ -77,7 +74,7 @@
}
if (NT_SUCCESS(Status))
- DeviceExtension->BaudRate = NewBaudRate;
+ DeviceExtension->BaudRate = BaudRate;
return Status;
}
@@ -213,6 +210,25 @@
return STATUS_SUCCESS;
}
+NTSTATUS
+SerialGetCommStatus(
+ OUT PSERIAL_STATUS pSerialStatus,
+ IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
+{
+ RtlZeroMemory(pSerialStatus, sizeof(SERIAL_STATUS));
+
+ pSerialStatus->Errors = 0; /* FIXME */
+ pSerialStatus->HoldReasons = 0; /* FIXME */
+ pSerialStatus->AmountInInQueue = (DeviceExtension->InputBuffer.WritePosition + DeviceExtension->InputBuffer.Length
+ - DeviceExtension->InputBuffer.ReadPosition) % DeviceExtension->InputBuffer.Length;
+ pSerialStatus->AmountInOutQueue = (DeviceExtension->OutputBuffer.WritePosition + DeviceExtension->OutputBuffer.Length
+ - DeviceExtension->OutputBuffer.ReadPosition) % DeviceExtension->OutputBuffer.Length;
+ pSerialStatus->EofReceived = FALSE; /* FIXME */
+ pSerialStatus->WaitForImmediate = FALSE; /* FIXME */
+
+ return STATUS_SUCCESS;
+}
+
NTSTATUS STDCALL
SerialDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
@@ -289,6 +305,8 @@
case IOCTL_SERIAL_GET_BAUD_RATE:
{
DPRINT("Serial: IOCTL_SERIAL_GET_BAUD_RATE\n");
+ /* FIXME: HACK!!! following line MUST NOT be here! */
+ Buffer = Irp->UserBuffer;
if (LengthOut < sizeof(SERIAL_BAUD_RATE))
Status = STATUS_BUFFER_TOO_SMALL;
else if (Buffer == NULL)
@@ -309,9 +327,22 @@
}
case IOCTL_SERIAL_GET_COMMSTATUS:
{
- /* FIXME */
- DPRINT1("Serial: IOCTL_SERIAL_GET_COMMSTATUS not implemented.\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ DPRINT("Serial: IOCTL_SERIAL_GET_COMMSTATUS\n");
+ if (LengthOut < sizeof(SERIAL_STATUS))
+ {
+ DPRINT("Serial: return STATUS_BUFFER_TOO_SMALL\n");
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else if (Buffer == NULL)
+ {
+ DPRINT("Serial: return STATUS_INVALID_PARAMETER\n");
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ Status = SerialGetCommStatus((PSERIAL_STATUS)Buffer, DeviceExtension);
+ Information = sizeof(SERIAL_STATUS);
+ }
break;
}
case IOCTL_SERIAL_GET_DTRRTS:
@@ -466,9 +497,18 @@
}
case IOCTL_SERIAL_PURGE:
{
- /* FIXME */
- DPRINT1("Serial: IOCTL_SERIAL_PURGE not implemented.\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ DPRINT("Serial: IOCTL_SERIAL_PURGE\n");
+ /* FIXME: lock input and output queues */
+ DeviceExtension->InputBuffer.ReadPosition = DeviceExtension->InputBuffer.WritePosition = 0;
+ DeviceExtension->OutputBuffer.ReadPosition = DeviceExtension->OutputBuffer.WritePosition = 0;
+ /* Clear receive/transmit buffers */
+ if (DeviceExtension->UartType >= Uart16550)
+ {
+ WRITE_PORT_UCHAR(SER_FCR(ComPortBase),
+ SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT);
+ }
+ /* FIXME: unlock input and output queues */
+ Status = STATUS_SUCCESS;
break;
}
case IOCTL_SERIAL_RESET_DEVICE:
@@ -572,9 +612,26 @@
}
case IOCTL_SERIAL_SET_QUEUE_SIZE:
{
- /* FIXME */
- DPRINT1("Serial: IOCTL_SERIAL_SET_QUEUE_SIZE not implemented.\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ if (LengthIn < sizeof(SERIAL_QUEUE_SIZE ))
+ return STATUS_BUFFER_TOO_SMALL;
+ else if (Buffer == NULL)
+ return STATUS_INVALID_PARAMETER;
+ else
+ {
+ Status = STATUS_SUCCESS;
+ if (((PSERIAL_QUEUE_SIZE)Buffer)->InSize > DeviceExtension->InputBuffer.Length)
+ {
+ /* FIXME: lock input queue */
+ Status = IncreaseCircularBufferSize(&DeviceExtension->InputBuffer, ((PSERIAL_QUEUE_SIZE)Buffer)->InSize);
+ /* FIXME: unlock input queue */
+ }
+ if (NT_SUCCESS(Status) && ((PSERIAL_QUEUE_SIZE)Buffer)->OutSize > DeviceExtension->OutputBuffer.Length)
+ {
+ /* FIXME: lock output queue */
+ Status = IncreaseCircularBufferSize(&DeviceExtension->OutputBuffer, ((PSERIAL_QUEUE_SIZE)Buffer)->OutSize);
+ /* FIXME: unlock output queue */
+ }
+ }
break;
}
case IOCTL_SERIAL_SET_RTS:
--- trunk/reactos/drivers/dd/serial/pnp.c 2005-03-22 20:15:04 UTC (rev 14272)
+++ trunk/reactos/drivers/dd/serial/pnp.c 2005-03-22 22:10:44 UTC (rev 14273)
@@ -83,6 +83,7 @@
DPRINT("Serial: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08x\n", Status);
goto ByeBye;
}
+ Fdo->Flags |= DO_BUFFERED_IO;
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
if (pFdo)
{
--- trunk/reactos/drivers/dd/serial/serial.h 2005-03-22 20:15:04 UTC (rev 14272)
+++ trunk/reactos/drivers/dd/serial/serial.h 2005-03-22 22:10:44 UTC (rev 14273)
@@ -178,6 +178,11 @@
IN PCIRCULAR_BUFFER pBuffer,
OUT PUCHAR Entry);
+NTSTATUS
+IncreaseCircularBufferSize(
+ IN PCIRCULAR_BUFFER pBuffer,
+ IN ULONG NewBufferSize);
+
/************************************ cleanup.c */
NTSTATUS STDCALL