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:
Hervé Poussineau 2005-03-16 19:24:41 +00:00
parent ba0f1263e4
commit 4d47498931
7 changed files with 76 additions and 10 deletions

View file

@ -16,7 +16,14 @@ SerialClose(
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;
}

View file

@ -41,7 +41,15 @@ SerialCreate(
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:

View file

@ -145,6 +145,32 @@ SerialSetLineControl(
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 @@ SerialDeviceControl(
{
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 @@ SerialDeviceControl(
}
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:

View file

@ -105,6 +105,7 @@ SerialInterruptService(
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;

View file

@ -219,6 +219,7 @@ SerialPnp(
{
ULONG MinorFunction;
PIO_STACK_LOCATION Stack;
ULONG Information = 0;
PDEVICE_OBJECT LowerDevice;
NTSTATUS Status;
@ -236,8 +237,6 @@ SerialPnp(
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 @@ SerialPnp(
break;
}
}
Irp->IoStatus.Information = Information;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}

View file

@ -80,6 +80,7 @@ SerialWrite(
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);

View file

@ -67,6 +67,9 @@ typedef struct _SERIAL_DEVICE_EXTENSION
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 */