[ros-diffs] [hpoussin] 14273: - Implement IOCTL_SERIAL_GET_COMMSTATUS, IOCTL_SERIAL_PURGE, IOCTL_SET_QUEUE_SIZE

hpoussin at svn.reactos.com hpoussin at svn.reactos.com
Tue Mar 22 23:10:46 CET 2005


- Implement IOCTL_SERIAL_GET_COMMSTATUS, IOCTL_SERIAL_PURGE,
IOCTL_SET_QUEUE_SIZE
- Add a hack in IOCTL_SERIAL_GET_BAUD_RATE to get it working with
mode.exe
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
  _____  

Modified: trunk/reactos/drivers/dd/serial/circularbuffer.c
--- 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 at 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;
+}
  _____  

Modified: trunk/reactos/drivers/dd/serial/devctrl.c
--- 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:
  _____  

Modified: trunk/reactos/drivers/dd/serial/pnp.c
--- 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)
 	{
  _____  

Modified: trunk/reactos/drivers/dd/serial/serial.h
--- 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-diffs/attachments/20050322/d000876c/attachment.html


More information about the Ros-diffs mailing list