Saveliy Tretiakov <saveliyt(a)mail.ru>
- Only one file may be open on a port at any given time
- Implemented IOCTL_SERIAL_GET_STATS and IOCTL_SERIAL_CLEAR_STATS
Modified: trunk/reactos/drivers/dd/serial/close.c
Modified: trunk/reactos/drivers/dd/serial/create.c
Modified: trunk/reactos/drivers/dd/serial/devctrl.c
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/close.c
--- trunk/reactos/drivers/dd/serial/close.c 2005-03-16 17:30:11 UTC
(rev 14138)
+++ trunk/reactos/drivers/dd/serial/close.c 2005-03-16 19:24:41 UTC
(rev 14139)
@@ -16,7 +16,14 @@
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
+ PSERIAL_DEVICE_EXTENSION pDeviceExtension;
+
DPRINT("Serial: IRP_MJ_CLOSE\n");
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ pDeviceExtension =
(PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ pDeviceExtension->IsOpened = FALSE;
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
_____
Modified: trunk/reactos/drivers/dd/serial/create.c
--- trunk/reactos/drivers/dd/serial/create.c 2005-03-16 17:30:11 UTC
(rev 14138)
+++ trunk/reactos/drivers/dd/serial/create.c 2005-03-16 19:24:41 UTC
(rev 14139)
@@ -41,7 +41,15 @@
goto ByeBye;
}
+ if(DeviceExtension->IsOpened)
+ {
+ DPRINT("Serial: COM%lu is already opened",
DeviceExtension->ComPort);
+ Status = STATUS_ACCESS_DENIED;
+ goto ByeBye;
+ }
+
DPRINT("Serial: open COM%lu: successfull\n",
DeviceExtension->ComPort);
+ DeviceExtension->IsOpened = TRUE;
Status = STATUS_SUCCESS;
ByeBye:
_____
Modified: trunk/reactos/drivers/dd/serial/devctrl.c
--- trunk/reactos/drivers/dd/serial/devctrl.c 2005-03-16 17:30:11 UTC
(rev 14138)
+++ trunk/reactos/drivers/dd/serial/devctrl.c 2005-03-16 19:24:41 UTC
(rev 14139)
@@ -145,6 +145,32 @@
return Status;
}
+BOOL
+SerialClearPerfStats(
+ IN PSERIALPERF_STATS pSerialPerfStats)
+{
+ RtlZeroMemory(pSerialPerfStats, sizeof(SERIALPERF_STATS));
+ return TRUE;
+}
+
+BOOL
+SerialGetPerfStats(IN PIRP pIrp)
+{
+ PSERIAL_DEVICE_EXTENSION pDeviceExtension;
+ pDeviceExtension = (PSERIAL_DEVICE_EXTENSION)
+
IoGetCurrentIrpStackLocation(pIrp)->DeviceObject->DeviceExtension;
+ /*
+ * we assume buffer is big enough to hold SerialPerfStats
structure
+ * caller must verify this
+ */
+ RtlCopyMemory(
+ pIrp->AssociatedIrp.SystemBuffer,
+ &pDeviceExtension->SerialPerfStats,
+ sizeof(SERIALPERF_STATS)
+ );
+ return TRUE;
+}
+
NTSTATUS STDCALL
SerialDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
@@ -175,9 +201,12 @@
{
case IOCTL_SERIAL_CLEAR_STATS:
{
- /* FIXME */
- DPRINT1("Serial: IOCTL_SERIAL_CLEAR_STATS not
implemented.\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ DPRINT("Serial: IOCTL_SERIAL_CLEAR_STATS\n");
+ KeSynchronizeExecution(
+ DeviceExtension->Interrupt,
+
(PKSYNCHRONIZE_ROUTINE)SerialClearPerfStats,
+ &DeviceExtension->SerialPerfStats);
+ Status = STATUS_SUCCESS;
break;
}
case IOCTL_SERIAL_CLR_DTR:
@@ -320,9 +349,24 @@
}
case IOCTL_SERIAL_GET_STATS:
{
- /* FIXME */
- DPRINT1("Serial: IOCTL_SERIAL_GET_STATS not
implemented.\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ DPRINT1("Serial: IOCTL_SERIAL_GET_STATS\n");
+ if (LengthOut < sizeof(SERIALPERF_STATS))
+ {
+ 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
+ {
+
KeSynchronizeExecution(DeviceExtension->Interrupt,
+
(PKSYNCHRONIZE_ROUTINE)SerialGetPerfStats, Irp);
+ Status = STATUS_SUCCESS;
+ Information =
sizeof(SERIALPERF_STATS);
+ }
break;
}
case IOCTL_SERIAL_GET_TIMEOUTS:
_____
Modified: trunk/reactos/drivers/dd/serial/misc.c
--- trunk/reactos/drivers/dd/serial/misc.c 2005-03-16 17:30:11 UTC
(rev 14138)
+++ trunk/reactos/drivers/dd/serial/misc.c 2005-03-16 19:24:41 UTC
(rev 14139)
@@ -105,6 +105,7 @@
if (READ_PORT_UCHAR(SER_LSR(ComPortBase)) &
SR_LSR_DR)
{
DPRINT1("Serial: Byte received: 0x%x\n",
READ_PORT_UCHAR(SER_RBR(ComPortBase)));
+
DeviceExtension->SerialPerfStats.ReceivedCount++;
return TRUE;
}
break;
_____
Modified: trunk/reactos/drivers/dd/serial/pnp.c
--- trunk/reactos/drivers/dd/serial/pnp.c 2005-03-16 17:30:11 UTC
(rev 14138)
+++ trunk/reactos/drivers/dd/serial/pnp.c 2005-03-16 19:24:41 UTC
(rev 14139)
@@ -219,6 +219,7 @@
{
ULONG MinorFunction;
PIO_STACK_LOCATION Stack;
+ ULONG Information = 0;
PDEVICE_OBJECT LowerDevice;
NTSTATUS Status;
@@ -236,8 +237,6 @@
Status = ForwardIrpAndWait(DeviceObject, Irp);
if (NT_SUCCESS(Status))
Status =
SerialPnpStartDevice(DeviceObject, Irp);
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
}
/* IRP_MN_QUERY_STOP_DEVICE (FIXME: required) */
@@ -270,6 +269,9 @@
break;
}
}
-
+
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
_____
Modified: trunk/reactos/drivers/dd/serial/rw.c
--- trunk/reactos/drivers/dd/serial/rw.c 2005-03-16 17:30:11 UTC
(rev 14138)
+++ trunk/reactos/drivers/dd/serial/rw.c 2005-03-16 19:24:41 UTC
(rev 14139)
@@ -80,6 +80,7 @@
while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) &
SR_LSR_TBE) == 0)
;
WRITE_PORT_UCHAR(SER_THR(ComPortBase), Buffer[i]);
+ DeviceExtension->SerialPerfStats.TransmittedCount++;
}
IoReleaseRemoveLock(&DeviceExtension->RemoveLock,
(PVOID)DeviceExtension->ComPort);
_____
Modified: trunk/reactos/drivers/dd/serial/serial.h
--- trunk/reactos/drivers/dd/serial/serial.h 2005-03-16 17:30:11 UTC
(rev 14138)
+++ trunk/reactos/drivers/dd/serial/serial.h 2005-03-16 19:24:41 UTC
(rev 14139)
@@ -67,6 +67,9 @@
SERIAL_LINE_CONTROL SerialLineControl;
ULONG WaitMask;
+ SERIALPERF_STATS SerialPerfStats;
+ BOOL IsOpened;
+
/* Current values */
UCHAR IER; /* Base+1, Interrupt Enable Register */
UCHAR MCR; /* Base+4, Modem Control Register */