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 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;
} }

View file

@ -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:

View file

@ -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:

View file

@ -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;

View file

@ -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;
} }

View file

@ -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);

View file

@ -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 */