mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:53:06 +00:00
Saveliy Tretiakov <saveliyt@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 svn path=/trunk/; revision=14139
This commit is contained in:
parent
ba0f1263e4
commit
4d47498931
7 changed files with 76 additions and 10 deletions
|
@ -16,7 +16,14 @@ SerialClose(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
|
PSERIAL_DEVICE_EXTENSION pDeviceExtension;
|
||||||
|
|
||||||
DPRINT("Serial: IRP_MJ_CLOSE\n");
|
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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,15 @@ SerialCreate(
|
||||||
goto ByeBye;
|
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);
|
DPRINT("Serial: open COM%lu: successfull\n", DeviceExtension->ComPort);
|
||||||
|
DeviceExtension->IsOpened = TRUE;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
ByeBye:
|
ByeBye:
|
||||||
|
|
|
@ -145,6 +145,32 @@ SerialSetLineControl(
|
||||||
return Status;
|
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
|
NTSTATUS STDCALL
|
||||||
SerialDeviceControl(
|
SerialDeviceControl(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -175,9 +201,12 @@ SerialDeviceControl(
|
||||||
{
|
{
|
||||||
case IOCTL_SERIAL_CLEAR_STATS:
|
case IOCTL_SERIAL_CLEAR_STATS:
|
||||||
{
|
{
|
||||||
/* FIXME */
|
DPRINT("Serial: IOCTL_SERIAL_CLEAR_STATS\n");
|
||||||
DPRINT1("Serial: IOCTL_SERIAL_CLEAR_STATS not implemented.\n");
|
KeSynchronizeExecution(
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
DeviceExtension->Interrupt,
|
||||||
|
(PKSYNCHRONIZE_ROUTINE)SerialClearPerfStats,
|
||||||
|
&DeviceExtension->SerialPerfStats);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_SERIAL_CLR_DTR:
|
case IOCTL_SERIAL_CLR_DTR:
|
||||||
|
@ -320,9 +349,24 @@ SerialDeviceControl(
|
||||||
}
|
}
|
||||||
case IOCTL_SERIAL_GET_STATS:
|
case IOCTL_SERIAL_GET_STATS:
|
||||||
{
|
{
|
||||||
/* FIXME */
|
DPRINT1("Serial: IOCTL_SERIAL_GET_STATS\n");
|
||||||
DPRINT1("Serial: IOCTL_SERIAL_GET_STATS not implemented.\n");
|
if (LengthOut < sizeof(SERIALPERF_STATS))
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
{
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_SERIAL_GET_TIMEOUTS:
|
case IOCTL_SERIAL_GET_TIMEOUTS:
|
||||||
|
|
|
@ -105,6 +105,7 @@ SerialInterruptService(
|
||||||
if (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR)
|
if (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR)
|
||||||
{
|
{
|
||||||
DPRINT1("Serial: Byte received: 0x%x\n", READ_PORT_UCHAR(SER_RBR(ComPortBase)));
|
DPRINT1("Serial: Byte received: 0x%x\n", READ_PORT_UCHAR(SER_RBR(ComPortBase)));
|
||||||
|
DeviceExtension->SerialPerfStats.ReceivedCount++;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -219,6 +219,7 @@ SerialPnp(
|
||||||
{
|
{
|
||||||
ULONG MinorFunction;
|
ULONG MinorFunction;
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
|
ULONG Information = 0;
|
||||||
PDEVICE_OBJECT LowerDevice;
|
PDEVICE_OBJECT LowerDevice;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -236,8 +237,6 @@ SerialPnp(
|
||||||
Status = ForwardIrpAndWait(DeviceObject, Irp);
|
Status = ForwardIrpAndWait(DeviceObject, Irp);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
Status = SerialPnpStartDevice(DeviceObject, Irp);
|
Status = SerialPnpStartDevice(DeviceObject, Irp);
|
||||||
Irp->IoStatus.Status = Status;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* IRP_MN_QUERY_STOP_DEVICE (FIXME: required) */
|
/* IRP_MN_QUERY_STOP_DEVICE (FIXME: required) */
|
||||||
|
@ -270,6 +269,9 @@ SerialPnp(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = Information;
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ SerialWrite(
|
||||||
while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
|
while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
|
||||||
;
|
;
|
||||||
WRITE_PORT_UCHAR(SER_THR(ComPortBase), Buffer[i]);
|
WRITE_PORT_UCHAR(SER_THR(ComPortBase), Buffer[i]);
|
||||||
|
DeviceExtension->SerialPerfStats.TransmittedCount++;
|
||||||
}
|
}
|
||||||
IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
|
IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,9 @@ typedef struct _SERIAL_DEVICE_EXTENSION
|
||||||
SERIAL_LINE_CONTROL SerialLineControl;
|
SERIAL_LINE_CONTROL SerialLineControl;
|
||||||
ULONG WaitMask;
|
ULONG WaitMask;
|
||||||
|
|
||||||
|
SERIALPERF_STATS SerialPerfStats;
|
||||||
|
BOOL IsOpened;
|
||||||
|
|
||||||
/* Current values */
|
/* Current values */
|
||||||
UCHAR IER; /* Base+1, Interrupt Enable Register */
|
UCHAR IER; /* Base+1, Interrupt Enable Register */
|
||||||
UCHAR MCR; /* Base+4, Modem Control Register */
|
UCHAR MCR; /* Base+4, Modem Control Register */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue