mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
eol-style native
svn path=/trunk/; revision=14086
This commit is contained in:
parent
f9279fd739
commit
e7005a9352
10 changed files with 1499 additions and 1499 deletions
|
@ -1,22 +1,22 @@
|
|||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/cleanup.c
|
||||
* PURPOSE: Serial IRP_MJ_CLEANUP operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialCleanup(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_CLEANUP\n");
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/cleanup.c
|
||||
* PURPOSE: Serial IRP_MJ_CLEANUP operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialCleanup(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_CLEANUP\n");
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/close.c
|
||||
* PURPOSE: Serial IRP_MJ_CLOSE operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialClose(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_CLOSE\n");
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/close.c
|
||||
* PURPOSE: Serial IRP_MJ_CLOSE operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialClose(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_CLOSE\n");
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,52 +1,52 @@
|
|||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/create.c
|
||||
* PURPOSE: Serial IRP_MJ_CREATE operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialCreate(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PFILE_OBJECT FileObject;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Serial: IRP_MJ_CREATE\n");
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FileObject = Stack->FileObject;
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
|
||||
{
|
||||
CHECKPOINT;
|
||||
Status = STATUS_NOT_A_DIRECTORY;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
if (FileObject->FileName.Length != 0 ||
|
||||
FileObject->RelatedFileObject != NULL)
|
||||
{
|
||||
CHECKPOINT;
|
||||
Status = STATUS_ACCESS_DENIED;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
DPRINT("Serial: open COM%lu: successfull\n", DeviceExtension->ComPort);
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
ByeBye:
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/create.c
|
||||
* PURPOSE: Serial IRP_MJ_CREATE operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialCreate(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PFILE_OBJECT FileObject;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Serial: IRP_MJ_CREATE\n");
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FileObject = Stack->FileObject;
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
|
||||
{
|
||||
CHECKPOINT;
|
||||
Status = STATUS_NOT_A_DIRECTORY;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
if (FileObject->FileName.Length != 0 ||
|
||||
FileObject->RelatedFileObject != NULL)
|
||||
{
|
||||
CHECKPOINT;
|
||||
Status = STATUS_ACCESS_DENIED;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
DPRINT("Serial: open COM%lu: successfull\n", DeviceExtension->ComPort);
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
ByeBye:
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,79 +1,79 @@
|
|||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/info.c
|
||||
* PURPOSE: Serial IRP_MJ_QUERY_INFORMATION operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG2
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialQueryInformation(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PVOID SystemBuffer;
|
||||
ULONG BufferLength;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
BufferLength = Stack->Parameters.QueryFile.Length;
|
||||
|
||||
switch (Stack->Parameters.QueryFile.FileInformationClass)
|
||||
{
|
||||
case FileStandardInformation:
|
||||
{
|
||||
PFILE_STANDARD_INFORMATION StandardInfo = (PFILE_STANDARD_INFORMATION)SystemBuffer;
|
||||
|
||||
DPRINT("Serial: IRP_MJ_QUERY_INFORMATION / FileStandardInformation\n");
|
||||
if (BufferLength < sizeof(FILE_STANDARD_INFORMATION))
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
else
|
||||
{
|
||||
StandardInfo->AllocationSize.QuadPart = 0;
|
||||
StandardInfo->EndOfFile.QuadPart = 0;
|
||||
StandardInfo->Directory = FALSE;
|
||||
StandardInfo->NumberOfLinks = 0;
|
||||
StandardInfo->DeletePending = FALSE; /* FIXME: should be TRUE sometimes */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
break;
|
||||
}
|
||||
case FilePositionInformation:
|
||||
{
|
||||
PFILE_POSITION_INFORMATION PositionInfo = (PFILE_POSITION_INFORMATION)SystemBuffer;
|
||||
|
||||
DPRINT("Serial: IRP_MJ_QUERY_INFORMATION / FilePositionInformation\n");
|
||||
if (BufferLength < sizeof(PFILE_POSITION_INFORMATION))
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
else
|
||||
{
|
||||
PositionInfo->CurrentByteOffset.QuadPart = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_QUERY_INFORMATION: Unexpected file information class 0x%02x\n", Stack->Parameters.QueryFile.FileInformationClass);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/info.c
|
||||
* PURPOSE: Serial IRP_MJ_QUERY_INFORMATION operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG2
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialQueryInformation(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PVOID SystemBuffer;
|
||||
ULONG BufferLength;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
BufferLength = Stack->Parameters.QueryFile.Length;
|
||||
|
||||
switch (Stack->Parameters.QueryFile.FileInformationClass)
|
||||
{
|
||||
case FileStandardInformation:
|
||||
{
|
||||
PFILE_STANDARD_INFORMATION StandardInfo = (PFILE_STANDARD_INFORMATION)SystemBuffer;
|
||||
|
||||
DPRINT("Serial: IRP_MJ_QUERY_INFORMATION / FileStandardInformation\n");
|
||||
if (BufferLength < sizeof(FILE_STANDARD_INFORMATION))
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
else
|
||||
{
|
||||
StandardInfo->AllocationSize.QuadPart = 0;
|
||||
StandardInfo->EndOfFile.QuadPart = 0;
|
||||
StandardInfo->Directory = FALSE;
|
||||
StandardInfo->NumberOfLinks = 0;
|
||||
StandardInfo->DeletePending = FALSE; /* FIXME: should be TRUE sometimes */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
break;
|
||||
}
|
||||
case FilePositionInformation:
|
||||
{
|
||||
PFILE_POSITION_INFORMATION PositionInfo = (PFILE_POSITION_INFORMATION)SystemBuffer;
|
||||
|
||||
DPRINT("Serial: IRP_MJ_QUERY_INFORMATION / FilePositionInformation\n");
|
||||
if (BufferLength < sizeof(PFILE_POSITION_INFORMATION))
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
else
|
||||
{
|
||||
PositionInfo->CurrentByteOffset.QuadPart = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_QUERY_INFORMATION: Unexpected file information class 0x%02x\n", Stack->Parameters.QueryFile.FileInformationClass);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -1,175 +1,175 @@
|
|||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/misc.c
|
||||
* PURPOSE: Misceallenous operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS
|
||||
ForwardIrpAndWaitCompletion(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
if (Irp->PendingReturned)
|
||||
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ForwardIrpAndWait(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PDEVICE_OBJECT LowerDevice = ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
DPRINT("Serial: Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName);
|
||||
IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
|
||||
|
||||
Status = IoCallDriver(LowerDevice, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
BOOLEAN STDCALL
|
||||
SerialInterruptService(
|
||||
IN PKINTERRUPT Interrupt,
|
||||
IN OUT PVOID ServiceContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
PUCHAR ComPortBase;
|
||||
UCHAR Iir;
|
||||
|
||||
DeviceObject = (PDEVICE_OBJECT)ServiceContext;
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
|
||||
|
||||
DPRINT1("Serial: Maybe our interrupt?\n"); /* FIXME */
|
||||
|
||||
Iir = READ_PORT_UCHAR(SER_IIR(ComPortBase));
|
||||
#if 0
|
||||
if (Iir == 0xff)
|
||||
return TRUE;
|
||||
CHECKPOINT1;
|
||||
Iir &= SR_IIR_ID_MASK;
|
||||
if (!(Iir & SR_IIR_SELF)) { return FALSE; }
|
||||
CHECKPOINT1;
|
||||
#else
|
||||
Iir &= SR_IIR_ID_MASK;
|
||||
Iir |= SR_IIR_SELF;
|
||||
#endif
|
||||
DPRINT1("Serial: Iir = 0x%x\n", Iir);
|
||||
|
||||
switch (Iir)
|
||||
{
|
||||
case SR_IIR_MSR_CHANGE:
|
||||
{
|
||||
DPRINT1("Serial: SR_IIR_MSR_CHANGE\n");
|
||||
DeviceExtension->MSR = READ_PORT_UCHAR(SER_MSR(ComPortBase));
|
||||
/* FIXME: what to do? */
|
||||
//return KeInsertQueueDpc (&Self->MsrChangeDpc, Self, 0);
|
||||
//return TRUE;
|
||||
break;
|
||||
}
|
||||
case SR_IIR_THR_EMPTY:
|
||||
{
|
||||
DPRINT1("Serial: SR_IIR_THR_EMPTY\n");
|
||||
break;
|
||||
/*if (!Self->WaitingSendBytes.Empty() &&
|
||||
(READ_PORT_UCHAR( Self->Port + UART_LSR ) & LSR_THR_EMPTY) )
|
||||
WRITE_PORT_UCHAR( Self->Port + UART_THR,
|
||||
Self->WaitingSendBytes.PopFront() );
|
||||
return KeInsertQueueDpc( &Self->TransmitDpc, Self, 0 );*/
|
||||
}
|
||||
case SR_IIR_DATA_RECEIVED:
|
||||
{
|
||||
DPRINT1("Serial: SR_IIR_DATA_RECEIVED\n");
|
||||
if (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR)
|
||||
{
|
||||
DPRINT1("Serial: Byte received: 0x%x\n", READ_PORT_UCHAR(SER_RBR(ComPortBase)));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
/*if( READ_PORT_UCHAR( Self->Port + UART_LSR ) & LSR_DATA_RECEIVED )
|
||||
Self->WaitingReadBytes.PushBack
|
||||
( READ_PORT_UCHAR( Self->Port + UART_RDR ) );
|
||||
return KeInsertQueueDpc( &Self->DataInDpc, Self, 0 );*/
|
||||
}
|
||||
case SR_IIR_ERROR:
|
||||
{
|
||||
DPRINT1("Serial: SR_IIR_ERROR\n");
|
||||
break;
|
||||
/*Error = READ_PORT_UCHAR( Self->Port + UART_LSR );
|
||||
if( Error & LSR_OVERRUN )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::OVERRUN );
|
||||
if( Error & LSR_PARITY_ERROR )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::PARITY );
|
||||
if( Error & LSR_FRAMING_ERROR )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::FRAMING );
|
||||
if( Error & LSR_BREAK )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::BREAK );
|
||||
if( Error & LSR_TIMEOUT )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::TIMEOUT );
|
||||
return KeInsertQueueDpc( &Self->DataInDpc, Self, 0 );*/
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
#if 0
|
||||
InterruptId = READ_PORT_UCHAR(SER_IIR(ComPortBase)) & SR_IIR_IID;
|
||||
DPRINT1("Serial: Interrupt catched: id = %x\n", InterruptId);
|
||||
/* FIXME: sometimes, update DeviceExtension->IER */
|
||||
/* FIXME: sometimes, update DeviceExtension->MCR */
|
||||
/* FIXME: sometimes, update DeviceExtension->MSR */
|
||||
switch (InterruptId)
|
||||
{
|
||||
case 3 << 1:
|
||||
{
|
||||
/* line status changed */
|
||||
DPRINT("Serial: Line status changed\n");
|
||||
break;
|
||||
}
|
||||
case 2 << 1:
|
||||
{
|
||||
/* data available */
|
||||
UCHAR ReceivedByte = READ_PORT_UCHAR(ComPortBase);
|
||||
DPRINT("Serial: Data available\n");
|
||||
DPRINT1("Serial: received %d\n", ReceivedByte);
|
||||
//Buffer[Information++] = ReceivedByte;
|
||||
}
|
||||
case 1 << 1:
|
||||
{
|
||||
/* transmit register empty */
|
||||
DPRINT("Serial: Transmit register empty\n");
|
||||
}
|
||||
case 0 << 1:
|
||||
{
|
||||
/* modem status change */
|
||||
UCHAR ReceivedByte = READ_PORT_UCHAR(SER_MSR(ComPortBase));
|
||||
DPRINT("Serial: Modem status change\n");
|
||||
DPRINT1("Serial: new status = 0x%02x\n", ReceivedByte);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/misc.c
|
||||
* PURPOSE: Misceallenous operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS
|
||||
ForwardIrpAndWaitCompletion(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
if (Irp->PendingReturned)
|
||||
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ForwardIrpAndWait(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PDEVICE_OBJECT LowerDevice = ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
DPRINT("Serial: Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName);
|
||||
IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
|
||||
|
||||
Status = IoCallDriver(LowerDevice, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
BOOLEAN STDCALL
|
||||
SerialInterruptService(
|
||||
IN PKINTERRUPT Interrupt,
|
||||
IN OUT PVOID ServiceContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
PUCHAR ComPortBase;
|
||||
UCHAR Iir;
|
||||
|
||||
DeviceObject = (PDEVICE_OBJECT)ServiceContext;
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
|
||||
|
||||
DPRINT1("Serial: Maybe our interrupt?\n"); /* FIXME */
|
||||
|
||||
Iir = READ_PORT_UCHAR(SER_IIR(ComPortBase));
|
||||
#if 0
|
||||
if (Iir == 0xff)
|
||||
return TRUE;
|
||||
CHECKPOINT1;
|
||||
Iir &= SR_IIR_ID_MASK;
|
||||
if (!(Iir & SR_IIR_SELF)) { return FALSE; }
|
||||
CHECKPOINT1;
|
||||
#else
|
||||
Iir &= SR_IIR_ID_MASK;
|
||||
Iir |= SR_IIR_SELF;
|
||||
#endif
|
||||
DPRINT1("Serial: Iir = 0x%x\n", Iir);
|
||||
|
||||
switch (Iir)
|
||||
{
|
||||
case SR_IIR_MSR_CHANGE:
|
||||
{
|
||||
DPRINT1("Serial: SR_IIR_MSR_CHANGE\n");
|
||||
DeviceExtension->MSR = READ_PORT_UCHAR(SER_MSR(ComPortBase));
|
||||
/* FIXME: what to do? */
|
||||
//return KeInsertQueueDpc (&Self->MsrChangeDpc, Self, 0);
|
||||
//return TRUE;
|
||||
break;
|
||||
}
|
||||
case SR_IIR_THR_EMPTY:
|
||||
{
|
||||
DPRINT1("Serial: SR_IIR_THR_EMPTY\n");
|
||||
break;
|
||||
/*if (!Self->WaitingSendBytes.Empty() &&
|
||||
(READ_PORT_UCHAR( Self->Port + UART_LSR ) & LSR_THR_EMPTY) )
|
||||
WRITE_PORT_UCHAR( Self->Port + UART_THR,
|
||||
Self->WaitingSendBytes.PopFront() );
|
||||
return KeInsertQueueDpc( &Self->TransmitDpc, Self, 0 );*/
|
||||
}
|
||||
case SR_IIR_DATA_RECEIVED:
|
||||
{
|
||||
DPRINT1("Serial: SR_IIR_DATA_RECEIVED\n");
|
||||
if (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR)
|
||||
{
|
||||
DPRINT1("Serial: Byte received: 0x%x\n", READ_PORT_UCHAR(SER_RBR(ComPortBase)));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
/*if( READ_PORT_UCHAR( Self->Port + UART_LSR ) & LSR_DATA_RECEIVED )
|
||||
Self->WaitingReadBytes.PushBack
|
||||
( READ_PORT_UCHAR( Self->Port + UART_RDR ) );
|
||||
return KeInsertQueueDpc( &Self->DataInDpc, Self, 0 );*/
|
||||
}
|
||||
case SR_IIR_ERROR:
|
||||
{
|
||||
DPRINT1("Serial: SR_IIR_ERROR\n");
|
||||
break;
|
||||
/*Error = READ_PORT_UCHAR( Self->Port + UART_LSR );
|
||||
if( Error & LSR_OVERRUN )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::OVERRUN );
|
||||
if( Error & LSR_PARITY_ERROR )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::PARITY );
|
||||
if( Error & LSR_FRAMING_ERROR )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::FRAMING );
|
||||
if( Error & LSR_BREAK )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::BREAK );
|
||||
if( Error & LSR_TIMEOUT )
|
||||
Self->WaitingReadBytes.PushBack( SerialFifo::TIMEOUT );
|
||||
return KeInsertQueueDpc( &Self->DataInDpc, Self, 0 );*/
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
#if 0
|
||||
InterruptId = READ_PORT_UCHAR(SER_IIR(ComPortBase)) & SR_IIR_IID;
|
||||
DPRINT1("Serial: Interrupt catched: id = %x\n", InterruptId);
|
||||
/* FIXME: sometimes, update DeviceExtension->IER */
|
||||
/* FIXME: sometimes, update DeviceExtension->MCR */
|
||||
/* FIXME: sometimes, update DeviceExtension->MSR */
|
||||
switch (InterruptId)
|
||||
{
|
||||
case 3 << 1:
|
||||
{
|
||||
/* line status changed */
|
||||
DPRINT("Serial: Line status changed\n");
|
||||
break;
|
||||
}
|
||||
case 2 << 1:
|
||||
{
|
||||
/* data available */
|
||||
UCHAR ReceivedByte = READ_PORT_UCHAR(ComPortBase);
|
||||
DPRINT("Serial: Data available\n");
|
||||
DPRINT1("Serial: received %d\n", ReceivedByte);
|
||||
//Buffer[Information++] = ReceivedByte;
|
||||
}
|
||||
case 1 << 1:
|
||||
{
|
||||
/* transmit register empty */
|
||||
DPRINT("Serial: Transmit register empty\n");
|
||||
}
|
||||
case 0 << 1:
|
||||
{
|
||||
/* modem status change */
|
||||
UCHAR ReceivedByte = READ_PORT_UCHAR(SER_MSR(ComPortBase));
|
||||
DPRINT("Serial: Modem status change\n");
|
||||
DPRINT1("Serial: new status = 0x%02x\n", ReceivedByte);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,275 +1,275 @@
|
|||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/pnp.c
|
||||
* PURPOSE: Serial IRP_MJ_PNP operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
/* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo)
|
||||
{
|
||||
PDEVICE_OBJECT Fdo;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
WCHAR DeviceNameBuffer[32];
|
||||
UNICODE_STRING DeviceName;
|
||||
static ULONG DeviceNumber = 0;
|
||||
|
||||
DPRINT("Serial: SerialAddDevice called\n");
|
||||
|
||||
/* Create new device object */
|
||||
swprintf(DeviceNameBuffer, L"\\Device\\Serial%lu", DeviceNumber);
|
||||
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(SERIAL_DEVICE_EXTENSION),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_SERIAL_PORT,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&Fdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: IoCreateDevice() failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Register device interface */
|
||||
/* FIXME */
|
||||
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
||||
RtlZeroMemory(DeviceExtension, sizeof(SERIAL_DEVICE_EXTENSION));
|
||||
DeviceExtension->SerialPortNumber = DeviceNumber++;
|
||||
DeviceExtension->Pdo = Pdo;
|
||||
DeviceExtension->PnpState = dsStopped;
|
||||
IoInitializeRemoveLock(&DeviceExtension->RemoveLock, SERIAL_TAG, 0, 0);
|
||||
//Fdo->Flags |= DO_POWER_PAGEABLE (or DO_POWER_INRUSH?)
|
||||
Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08x\n", Status);
|
||||
IoDeleteDevice(Fdo);
|
||||
return Status;
|
||||
}
|
||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPnpStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PCM_RESOURCE_LIST ResourceList;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
WCHAR DeviceNameBuffer[32];
|
||||
UNICODE_STRING DeviceName;
|
||||
WCHAR LinkNameBuffer[32];
|
||||
UNICODE_STRING LinkName;
|
||||
ULONG Vector;
|
||||
KIRQL Dirql;
|
||||
KAFFINITY Affinity;
|
||||
NTSTATUS Status;
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
ResourceList = Stack->Parameters.StartDevice.AllocatedResources/*Translated*/;
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* FIXME: actually, IRP_MN_START_DEVICE is sent twice to each serial device:
|
||||
* - one when loading serial.sys
|
||||
* - one when loading attached upper filter serenum.sys
|
||||
* This behaviour MUST NOT exist.
|
||||
* As PnP handling isn't right anyway, I didn't search how to correct this.
|
||||
*/
|
||||
if (DeviceExtension->PnpState == dsStarted) return STATUS_SUCCESS;
|
||||
|
||||
if (ResourceList == NULL)
|
||||
{
|
||||
/* FIXME: PnP isn't correctly implemented and doesn't give us a list
|
||||
* of our own resources. Use default values instead.
|
||||
*/
|
||||
switch (DeviceExtension->SerialPortNumber)
|
||||
{
|
||||
case 0:
|
||||
DPRINT("Serial: creating COM1:\n");
|
||||
DeviceExtension->ComPort = 3;
|
||||
DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
|
||||
DeviceExtension->BaseAddress = 0x3F8;
|
||||
DeviceExtension->Irq = 4;
|
||||
break;
|
||||
case 1:
|
||||
DPRINT("Serial: creating COM2:\n");
|
||||
DeviceExtension->ComPort = 4;
|
||||
DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
|
||||
DeviceExtension->BaseAddress = 0x2F8;
|
||||
DeviceExtension->Irq = 3;
|
||||
break;
|
||||
default:
|
||||
DPRINT1("Serial: unknown port?\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
DPRINT1("ResourceList %p, ResourceListTranslated %p\n", Stack->Parameters.StartDevice.AllocatedResources, Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
|
||||
for (i = 0; i < ResourceList->Count; i++)
|
||||
{
|
||||
DPRINT1("Interface type = 0x%x\n", ResourceList->List[i].InterfaceType);
|
||||
DPRINT1("Bus number = 0x%x\n", ResourceList->List[i].BusNumber);
|
||||
for (j = 0; i < ResourceList->List[i].PartialResourceList.Count; j++)
|
||||
{
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->List[i].PartialResourceList.PartialDescriptors[j];
|
||||
DPRINT1("Type 0x%x, Share disposition 0x%x, Flags 0x%x\n",
|
||||
PartialDescriptor->Type,
|
||||
PartialDescriptor->ShareDisposition,
|
||||
PartialDescriptor->Flags);
|
||||
switch (PartialDescriptor->Type)
|
||||
{
|
||||
case CmResourceTypePort:
|
||||
DeviceExtension->BaseAddress = PartialDescriptor->u.Port.Start.u.LowPart;
|
||||
break;
|
||||
case CmResourceTypeInterrupt:
|
||||
/* FIXME: Detect if interrupt is shareable and/or latched */
|
||||
/* FIXME: use also ->u.Interrupt.Vector and ->u.Interrupt.Affinity
|
||||
* to remove call to HalGetInterruptVector(...) */
|
||||
DeviceExtension->Irq = PartialDescriptor->u.Interrupt.Level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* FIXME: use polling if no interrupt was found? */
|
||||
DeviceExtension->ComPort = 5; /* FIXME: use incremental value, or find it in resource list*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get current settings */
|
||||
DeviceExtension->IER = READ_PORT_UCHAR(SER_IER((PUCHAR)DeviceExtension->BaseAddress));
|
||||
DeviceExtension->MCR = READ_PORT_UCHAR(SER_MCR((PUCHAR)DeviceExtension->BaseAddress));
|
||||
DeviceExtension->MSR = READ_PORT_UCHAR(SER_MSR((PUCHAR)DeviceExtension->BaseAddress));
|
||||
DeviceExtension->SerialLineControl.StopBits = STOP_BIT_1;
|
||||
DeviceExtension->SerialLineControl.Parity = NO_PARITY;
|
||||
DeviceExtension->SerialLineControl.WordLength = 8;
|
||||
DeviceExtension->WaitMask = 0;
|
||||
|
||||
/* Set baud rate */
|
||||
Status = SerialSetBaudRate(DeviceExtension, 19200 | SERIAL_BAUD_USER); /* FIXME: real default value? */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: SerialSetBaudRate() failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set line control */
|
||||
Status = SerialSetLineControl(DeviceExtension, &DeviceExtension->SerialLineControl);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: SerialSetLineControl() failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create link \DosDevices\COMX -> \Device\SerialX */
|
||||
swprintf(DeviceNameBuffer, L"\\Device\\Serial%lu", DeviceExtension->SerialPortNumber);
|
||||
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
|
||||
swprintf(LinkNameBuffer, L"\\DosDevices\\COM%lu", DeviceExtension->ComPort);
|
||||
RtlInitUnicodeString(&LinkName, LinkNameBuffer);
|
||||
Status = IoCreateSymbolicLink(&LinkName, &DeviceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: IoCreateSymbolicLink() failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Connect interrupt and enable them */
|
||||
Vector = HalGetInterruptVector(Internal, 0, 0, DeviceExtension->Irq, &Dirql, &Affinity);
|
||||
Status = IoConnectInterrupt(
|
||||
&DeviceExtension->Interrupt, SerialInterruptService,
|
||||
DeviceObject, NULL, Vector, Dirql, Dirql, Latched,
|
||||
FALSE /* FIXME: or TRUE to share interrupt on PCI bus? */,
|
||||
Affinity, FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: IoConnectInterrupt() failed with status 0x%08x\n", Status);
|
||||
IoDeleteSymbolicLink(&LinkName);
|
||||
return Status;
|
||||
}
|
||||
DeviceExtension->IER |= 0x1; /* Activate interrupt mode */
|
||||
WRITE_PORT_UCHAR(SER_IER((PUCHAR)DeviceExtension->BaseAddress), DeviceExtension->IER);
|
||||
|
||||
DeviceExtension->PnpState = dsStarted;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPnp(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
ULONG MinorFunction;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
NTSTATUS Status;
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
MinorFunction = Stack->MinorFunction;
|
||||
LowerDevice = ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||
|
||||
switch (MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
|
||||
|
||||
/* Call lower driver */
|
||||
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) */
|
||||
/* IRP_MN_STOP_DEVICE (FIXME: required) */
|
||||
/* IRP_MN_CANCEL_STOP_DEVICE (FIXME: required) */
|
||||
/* IRP_MN_QUERY_REMOVE_DEVICE (FIXME: required) */
|
||||
/* case IRP_MN_REMOVE_DEVICE (FIXME: required) */
|
||||
/*{
|
||||
DPRINT("Serial: IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
|
||||
IoAcquireRemoveLock
|
||||
IoReleaseRemoveLockAndWait
|
||||
pass request to DeviceExtension-LowerDriver
|
||||
IoDeleteDevice(Fdo) and/or IoDetachDevice
|
||||
break;
|
||||
}*/
|
||||
/* IRP_MN_CANCEL_REMOVE_DEVICE (FIXME: required) */
|
||||
/* IRP_MN_SURPRISE_REMOVAL (FIXME: required) */
|
||||
/* IRP_MN_QUERY_CAPABILITIES (optional) */
|
||||
/* IRP_MN_QUERY_PNP_DEVICE_STATE (optional) */
|
||||
/* IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional) */
|
||||
/* IRP_MN_DEVICE_USAGE_NOTIFICATION (FIXME: required or optional ???) */
|
||||
/* IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations (optional) */
|
||||
/* IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) */
|
||||
/* IRP_MN_QUERY_INTERFACE (optional) */
|
||||
default:
|
||||
{
|
||||
DPRINT1("Serial: unknown minor function 0x%x\n", MinorFunction);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(LowerDevice, Irp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/pnp.c
|
||||
* PURPOSE: Serial IRP_MJ_PNP operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
/* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo)
|
||||
{
|
||||
PDEVICE_OBJECT Fdo;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
WCHAR DeviceNameBuffer[32];
|
||||
UNICODE_STRING DeviceName;
|
||||
static ULONG DeviceNumber = 0;
|
||||
|
||||
DPRINT("Serial: SerialAddDevice called\n");
|
||||
|
||||
/* Create new device object */
|
||||
swprintf(DeviceNameBuffer, L"\\Device\\Serial%lu", DeviceNumber);
|
||||
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(SERIAL_DEVICE_EXTENSION),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_SERIAL_PORT,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&Fdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: IoCreateDevice() failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Register device interface */
|
||||
/* FIXME */
|
||||
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
||||
RtlZeroMemory(DeviceExtension, sizeof(SERIAL_DEVICE_EXTENSION));
|
||||
DeviceExtension->SerialPortNumber = DeviceNumber++;
|
||||
DeviceExtension->Pdo = Pdo;
|
||||
DeviceExtension->PnpState = dsStopped;
|
||||
IoInitializeRemoveLock(&DeviceExtension->RemoveLock, SERIAL_TAG, 0, 0);
|
||||
//Fdo->Flags |= DO_POWER_PAGEABLE (or DO_POWER_INRUSH?)
|
||||
Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08x\n", Status);
|
||||
IoDeleteDevice(Fdo);
|
||||
return Status;
|
||||
}
|
||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPnpStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PCM_RESOURCE_LIST ResourceList;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
WCHAR DeviceNameBuffer[32];
|
||||
UNICODE_STRING DeviceName;
|
||||
WCHAR LinkNameBuffer[32];
|
||||
UNICODE_STRING LinkName;
|
||||
ULONG Vector;
|
||||
KIRQL Dirql;
|
||||
KAFFINITY Affinity;
|
||||
NTSTATUS Status;
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
ResourceList = Stack->Parameters.StartDevice.AllocatedResources/*Translated*/;
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* FIXME: actually, IRP_MN_START_DEVICE is sent twice to each serial device:
|
||||
* - one when loading serial.sys
|
||||
* - one when loading attached upper filter serenum.sys
|
||||
* This behaviour MUST NOT exist.
|
||||
* As PnP handling isn't right anyway, I didn't search how to correct this.
|
||||
*/
|
||||
if (DeviceExtension->PnpState == dsStarted) return STATUS_SUCCESS;
|
||||
|
||||
if (ResourceList == NULL)
|
||||
{
|
||||
/* FIXME: PnP isn't correctly implemented and doesn't give us a list
|
||||
* of our own resources. Use default values instead.
|
||||
*/
|
||||
switch (DeviceExtension->SerialPortNumber)
|
||||
{
|
||||
case 0:
|
||||
DPRINT("Serial: creating COM1:\n");
|
||||
DeviceExtension->ComPort = 3;
|
||||
DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
|
||||
DeviceExtension->BaseAddress = 0x3F8;
|
||||
DeviceExtension->Irq = 4;
|
||||
break;
|
||||
case 1:
|
||||
DPRINT("Serial: creating COM2:\n");
|
||||
DeviceExtension->ComPort = 4;
|
||||
DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
|
||||
DeviceExtension->BaseAddress = 0x2F8;
|
||||
DeviceExtension->Irq = 3;
|
||||
break;
|
||||
default:
|
||||
DPRINT1("Serial: unknown port?\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
DPRINT1("ResourceList %p, ResourceListTranslated %p\n", Stack->Parameters.StartDevice.AllocatedResources, Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
|
||||
for (i = 0; i < ResourceList->Count; i++)
|
||||
{
|
||||
DPRINT1("Interface type = 0x%x\n", ResourceList->List[i].InterfaceType);
|
||||
DPRINT1("Bus number = 0x%x\n", ResourceList->List[i].BusNumber);
|
||||
for (j = 0; i < ResourceList->List[i].PartialResourceList.Count; j++)
|
||||
{
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->List[i].PartialResourceList.PartialDescriptors[j];
|
||||
DPRINT1("Type 0x%x, Share disposition 0x%x, Flags 0x%x\n",
|
||||
PartialDescriptor->Type,
|
||||
PartialDescriptor->ShareDisposition,
|
||||
PartialDescriptor->Flags);
|
||||
switch (PartialDescriptor->Type)
|
||||
{
|
||||
case CmResourceTypePort:
|
||||
DeviceExtension->BaseAddress = PartialDescriptor->u.Port.Start.u.LowPart;
|
||||
break;
|
||||
case CmResourceTypeInterrupt:
|
||||
/* FIXME: Detect if interrupt is shareable and/or latched */
|
||||
/* FIXME: use also ->u.Interrupt.Vector and ->u.Interrupt.Affinity
|
||||
* to remove call to HalGetInterruptVector(...) */
|
||||
DeviceExtension->Irq = PartialDescriptor->u.Interrupt.Level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* FIXME: use polling if no interrupt was found? */
|
||||
DeviceExtension->ComPort = 5; /* FIXME: use incremental value, or find it in resource list*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get current settings */
|
||||
DeviceExtension->IER = READ_PORT_UCHAR(SER_IER((PUCHAR)DeviceExtension->BaseAddress));
|
||||
DeviceExtension->MCR = READ_PORT_UCHAR(SER_MCR((PUCHAR)DeviceExtension->BaseAddress));
|
||||
DeviceExtension->MSR = READ_PORT_UCHAR(SER_MSR((PUCHAR)DeviceExtension->BaseAddress));
|
||||
DeviceExtension->SerialLineControl.StopBits = STOP_BIT_1;
|
||||
DeviceExtension->SerialLineControl.Parity = NO_PARITY;
|
||||
DeviceExtension->SerialLineControl.WordLength = 8;
|
||||
DeviceExtension->WaitMask = 0;
|
||||
|
||||
/* Set baud rate */
|
||||
Status = SerialSetBaudRate(DeviceExtension, 19200 | SERIAL_BAUD_USER); /* FIXME: real default value? */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: SerialSetBaudRate() failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set line control */
|
||||
Status = SerialSetLineControl(DeviceExtension, &DeviceExtension->SerialLineControl);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: SerialSetLineControl() failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create link \DosDevices\COMX -> \Device\SerialX */
|
||||
swprintf(DeviceNameBuffer, L"\\Device\\Serial%lu", DeviceExtension->SerialPortNumber);
|
||||
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
|
||||
swprintf(LinkNameBuffer, L"\\DosDevices\\COM%lu", DeviceExtension->ComPort);
|
||||
RtlInitUnicodeString(&LinkName, LinkNameBuffer);
|
||||
Status = IoCreateSymbolicLink(&LinkName, &DeviceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: IoCreateSymbolicLink() failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Connect interrupt and enable them */
|
||||
Vector = HalGetInterruptVector(Internal, 0, 0, DeviceExtension->Irq, &Dirql, &Affinity);
|
||||
Status = IoConnectInterrupt(
|
||||
&DeviceExtension->Interrupt, SerialInterruptService,
|
||||
DeviceObject, NULL, Vector, Dirql, Dirql, Latched,
|
||||
FALSE /* FIXME: or TRUE to share interrupt on PCI bus? */,
|
||||
Affinity, FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Serial: IoConnectInterrupt() failed with status 0x%08x\n", Status);
|
||||
IoDeleteSymbolicLink(&LinkName);
|
||||
return Status;
|
||||
}
|
||||
DeviceExtension->IER |= 0x1; /* Activate interrupt mode */
|
||||
WRITE_PORT_UCHAR(SER_IER((PUCHAR)DeviceExtension->BaseAddress), DeviceExtension->IER);
|
||||
|
||||
DeviceExtension->PnpState = dsStarted;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPnp(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
ULONG MinorFunction;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
NTSTATUS Status;
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
MinorFunction = Stack->MinorFunction;
|
||||
LowerDevice = ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||
|
||||
switch (MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
|
||||
|
||||
/* Call lower driver */
|
||||
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) */
|
||||
/* IRP_MN_STOP_DEVICE (FIXME: required) */
|
||||
/* IRP_MN_CANCEL_STOP_DEVICE (FIXME: required) */
|
||||
/* IRP_MN_QUERY_REMOVE_DEVICE (FIXME: required) */
|
||||
/* case IRP_MN_REMOVE_DEVICE (FIXME: required) */
|
||||
/*{
|
||||
DPRINT("Serial: IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
|
||||
IoAcquireRemoveLock
|
||||
IoReleaseRemoveLockAndWait
|
||||
pass request to DeviceExtension-LowerDriver
|
||||
IoDeleteDevice(Fdo) and/or IoDetachDevice
|
||||
break;
|
||||
}*/
|
||||
/* IRP_MN_CANCEL_REMOVE_DEVICE (FIXME: required) */
|
||||
/* IRP_MN_SURPRISE_REMOVAL (FIXME: required) */
|
||||
/* IRP_MN_QUERY_CAPABILITIES (optional) */
|
||||
/* IRP_MN_QUERY_PNP_DEVICE_STATE (optional) */
|
||||
/* IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional) */
|
||||
/* IRP_MN_DEVICE_USAGE_NOTIFICATION (FIXME: required or optional ???) */
|
||||
/* IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations (optional) */
|
||||
/* IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) */
|
||||
/* IRP_MN_QUERY_INTERFACE (optional) */
|
||||
default:
|
||||
{
|
||||
DPRINT1("Serial: unknown minor function 0x%x\n", MinorFunction);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(LowerDevice, Irp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/power.c
|
||||
* PURPOSE: Serial IRP_MJ_POWER operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPower(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_POWER dispatch\n");
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/power.c
|
||||
* PURPOSE: Serial IRP_MJ_POWER operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPower(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("Serial: IRP_MJ_POWER dispatch\n");
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,93 +1,93 @@
|
|||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/create.c
|
||||
* PURPOSE: Serial IRP_MJ_READ/IRP_MJ_WRITE operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
/* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
static PVOID
|
||||
SerialGetUserBuffer(IN PIRP Irp)
|
||||
{
|
||||
ASSERT(Irp);
|
||||
|
||||
if (Irp->MdlAddress)
|
||||
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
else
|
||||
/* FIXME: try buffer */
|
||||
return Irp->UserBuffer;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialRead(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
ULONG Information = 0;
|
||||
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
DPRINT1("Serial: IRP_MJ_READ unimplemented\n");
|
||||
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialWrite(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Length;
|
||||
ULONG Information = 0;
|
||||
PUCHAR Buffer;
|
||||
PUCHAR ComPortBase;
|
||||
ULONG i;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("Serial: IRP_MJ_WRITE\n");
|
||||
|
||||
/* FIXME: pend operation if possible */
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
Length = Stack->Parameters.Write.Length;
|
||||
Buffer = SerialGetUserBuffer(Irp);
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
|
||||
|
||||
if (Stack->Parameters.Write.ByteOffset.QuadPart != 0 || Buffer == NULL)
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto ByeBye;
|
||||
|
||||
for (i = 0; i < Length; i++)
|
||||
{
|
||||
/* verify if output buffer is not full */
|
||||
while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
|
||||
;
|
||||
WRITE_PORT_UCHAR(SER_THR(ComPortBase), Buffer[i]);
|
||||
}
|
||||
IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
|
||||
|
||||
Information = Length;
|
||||
|
||||
ByeBye:
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
/* $Id:
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/dd/serial/create.c
|
||||
* PURPOSE: Serial IRP_MJ_READ/IRP_MJ_WRITE operations
|
||||
*
|
||||
* PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
|
||||
*/
|
||||
/* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */
|
||||
|
||||
#define NDEBUG
|
||||
#include "serial.h"
|
||||
|
||||
static PVOID
|
||||
SerialGetUserBuffer(IN PIRP Irp)
|
||||
{
|
||||
ASSERT(Irp);
|
||||
|
||||
if (Irp->MdlAddress)
|
||||
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
else
|
||||
/* FIXME: try buffer */
|
||||
return Irp->UserBuffer;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialRead(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
ULONG Information = 0;
|
||||
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
DPRINT1("Serial: IRP_MJ_READ unimplemented\n");
|
||||
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialWrite(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Length;
|
||||
ULONG Information = 0;
|
||||
PUCHAR Buffer;
|
||||
PUCHAR ComPortBase;
|
||||
ULONG i;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("Serial: IRP_MJ_WRITE\n");
|
||||
|
||||
/* FIXME: pend operation if possible */
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
Length = Stack->Parameters.Write.Length;
|
||||
Buffer = SerialGetUserBuffer(Irp);
|
||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
|
||||
|
||||
if (Stack->Parameters.Write.ByteOffset.QuadPart != 0 || Buffer == NULL)
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto ByeBye;
|
||||
|
||||
for (i = 0; i < Length; i++)
|
||||
{
|
||||
/* verify if output buffer is not full */
|
||||
while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
|
||||
;
|
||||
WRITE_PORT_UCHAR(SER_THR(ComPortBase), Buffer[i]);
|
||||
}
|
||||
IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
|
||||
|
||||
Information = Length;
|
||||
|
||||
ByeBye:
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -1,208 +1,208 @@
|
|||
#if defined(__GNUC__)
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntddser.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
/* FIXME: this prototype MUST NOT be here! */
|
||||
NTSTATUS STDCALL
|
||||
IoAttachDeviceToDeviceStackSafe(
|
||||
IN PDEVICE_OBJECT SourceDevice,
|
||||
IN PDEVICE_OBJECT TargetDevice,
|
||||
OUT PDEVICE_OBJECT *AttachedToDeviceObject);
|
||||
#elif defined(_MSC_VER)
|
||||
#include <ntddk.h>
|
||||
#include <ntddser.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define STDCALL
|
||||
|
||||
#define DPRINT1 DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
|
||||
#define CHECKPOINT1 DbgPrint("(%s:%d)\n")
|
||||
|
||||
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IoAttachDeviceToDeviceStackSafe(
|
||||
IN PDEVICE_OBJECT SourceDevice,
|
||||
IN PDEVICE_OBJECT TargetDevice,
|
||||
OUT PDEVICE_OBJECT *AttachedToDeviceObject);
|
||||
|
||||
#ifdef NDEBUG2
|
||||
#define DPRINT
|
||||
#define CHECKPOINT
|
||||
#else
|
||||
#define DPRINT DPRINT1
|
||||
#define CHECKPOINT CHECKPOINT1
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#else
|
||||
#error Unknown compiler!
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
dsStopped,
|
||||
dsStarted,
|
||||
dsPaused,
|
||||
dsRemoved,
|
||||
dsSurpriseRemoved
|
||||
} SERIAL_DEVICE_STATE;
|
||||
|
||||
typedef struct _SERIAL_DEVICE_EXTENSION
|
||||
{
|
||||
PDEVICE_OBJECT Pdo;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
SERIAL_DEVICE_STATE PnpState;
|
||||
IO_REMOVE_LOCK RemoveLock;
|
||||
|
||||
ULONG SerialPortNumber;
|
||||
|
||||
ULONG ComPort; /* FIXME: move to serenum */
|
||||
ULONG BaudRate;
|
||||
ULONG BaseAddress;
|
||||
ULONG Irq;
|
||||
PKINTERRUPT Interrupt;
|
||||
|
||||
SERIAL_LINE_CONTROL SerialLineControl;
|
||||
ULONG WaitMask;
|
||||
|
||||
/* Current values */
|
||||
UCHAR IER; /* Base+1, Interrupt Enable Register */
|
||||
UCHAR MCR; /* Base+4, Modem Control Register */
|
||||
UCHAR MSR; /* Base+6, Modem Status Register */
|
||||
} SERIAL_DEVICE_EXTENSION, *PSERIAL_DEVICE_EXTENSION;
|
||||
|
||||
#define SERIAL_TAG TAG('S', 'e', 'r', 'l')
|
||||
|
||||
/* Baud master clock */
|
||||
#define BAUD_CLOCK 1843200
|
||||
#define CLOCKS_PER_BIT 16
|
||||
|
||||
/* UART registers and bits */
|
||||
#define SER_RBR(x) ((x)+0)
|
||||
#define SER_THR(x) ((x)+0)
|
||||
#define SER_DLL(x) ((x)+0)
|
||||
#define SER_IER(x) ((x)+1)
|
||||
#define SER_DLM(x) ((x)+1)
|
||||
#define SER_FCR(x) ((x)+1)
|
||||
#define SER_IIR(x) ((x)+2)
|
||||
#define SR_IIR_SELF 0x01
|
||||
#define SR_IIR_ID_MASK 0x07
|
||||
#define SR_IIR_MSR_CHANGE SR_IIR_SELF
|
||||
#define SR_IIR_THR_EMPTY (SR_IIR_SELF | 2)
|
||||
#define SR_IIR_DATA_RECEIVED (SR_IIR_SELF | 4)
|
||||
#define SR_IIR_ERROR (SR_IIR_SELF | 6)
|
||||
#define SER_LCR(x) ((x)+3)
|
||||
#define SR_LCR_CS5 0x00
|
||||
#define SR_LCR_CS6 0x01
|
||||
#define SR_LCR_CS7 0x02
|
||||
#define SR_LCR_CS8 0x03
|
||||
#define SR_LCR_ST1 0x00
|
||||
#define SR_LCR_ST2 0x04
|
||||
#define SR_LCR_PNO 0x00
|
||||
#define SR_LCR_POD 0x08
|
||||
#define SR_LCR_PEV 0x18
|
||||
#define SR_LCR_PMK 0x28
|
||||
#define SR_LCR_PSP 0x38
|
||||
#define SR_LCR_BRK 0x40
|
||||
#define SR_LCR_DLAB 0x80
|
||||
#define SER_MCR(x) ((x)+4)
|
||||
#define SR_MCR_DTR 0x01
|
||||
#define SR_MCR_RTS 0x02
|
||||
#define SER_LSR(x) ((x)+5)
|
||||
#define SR_LSR_DR 0x01
|
||||
#define SR_LSR_TBE 0x20
|
||||
#define SER_MSR(x) ((x)+6)
|
||||
#define SR_MSR_CTS 0x10
|
||||
#define SR_MSR_DSR 0x20
|
||||
#define SER_SCR(x) ((x)+7)
|
||||
|
||||
/************************************ cleanup.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialCleanup(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ close.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialClose(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ create.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialCreate(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ devctrl.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialSetBaudRate(
|
||||
IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
|
||||
IN ULONG NewBaudRate);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialSetLineControl(
|
||||
IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
|
||||
IN PSERIAL_LINE_CONTROL NewSettings);
|
||||
|
||||
/************************************ info.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialQueryInformation(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ misc.c */
|
||||
|
||||
NTSTATUS
|
||||
ForwardIrpAndWait(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
BOOLEAN STDCALL
|
||||
SerialInterruptService(
|
||||
IN PKINTERRUPT Interrupt,
|
||||
IN OUT PVOID ServiceContext);
|
||||
|
||||
/************************************ pnp.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPnp(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ power.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPower(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ rw.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialRead(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialWrite(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntddser.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
/* FIXME: this prototype MUST NOT be here! */
|
||||
NTSTATUS STDCALL
|
||||
IoAttachDeviceToDeviceStackSafe(
|
||||
IN PDEVICE_OBJECT SourceDevice,
|
||||
IN PDEVICE_OBJECT TargetDevice,
|
||||
OUT PDEVICE_OBJECT *AttachedToDeviceObject);
|
||||
#elif defined(_MSC_VER)
|
||||
#include <ntddk.h>
|
||||
#include <ntddser.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define STDCALL
|
||||
|
||||
#define DPRINT1 DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
|
||||
#define CHECKPOINT1 DbgPrint("(%s:%d)\n")
|
||||
|
||||
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IoAttachDeviceToDeviceStackSafe(
|
||||
IN PDEVICE_OBJECT SourceDevice,
|
||||
IN PDEVICE_OBJECT TargetDevice,
|
||||
OUT PDEVICE_OBJECT *AttachedToDeviceObject);
|
||||
|
||||
#ifdef NDEBUG2
|
||||
#define DPRINT
|
||||
#define CHECKPOINT
|
||||
#else
|
||||
#define DPRINT DPRINT1
|
||||
#define CHECKPOINT CHECKPOINT1
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#else
|
||||
#error Unknown compiler!
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
dsStopped,
|
||||
dsStarted,
|
||||
dsPaused,
|
||||
dsRemoved,
|
||||
dsSurpriseRemoved
|
||||
} SERIAL_DEVICE_STATE;
|
||||
|
||||
typedef struct _SERIAL_DEVICE_EXTENSION
|
||||
{
|
||||
PDEVICE_OBJECT Pdo;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
SERIAL_DEVICE_STATE PnpState;
|
||||
IO_REMOVE_LOCK RemoveLock;
|
||||
|
||||
ULONG SerialPortNumber;
|
||||
|
||||
ULONG ComPort; /* FIXME: move to serenum */
|
||||
ULONG BaudRate;
|
||||
ULONG BaseAddress;
|
||||
ULONG Irq;
|
||||
PKINTERRUPT Interrupt;
|
||||
|
||||
SERIAL_LINE_CONTROL SerialLineControl;
|
||||
ULONG WaitMask;
|
||||
|
||||
/* Current values */
|
||||
UCHAR IER; /* Base+1, Interrupt Enable Register */
|
||||
UCHAR MCR; /* Base+4, Modem Control Register */
|
||||
UCHAR MSR; /* Base+6, Modem Status Register */
|
||||
} SERIAL_DEVICE_EXTENSION, *PSERIAL_DEVICE_EXTENSION;
|
||||
|
||||
#define SERIAL_TAG TAG('S', 'e', 'r', 'l')
|
||||
|
||||
/* Baud master clock */
|
||||
#define BAUD_CLOCK 1843200
|
||||
#define CLOCKS_PER_BIT 16
|
||||
|
||||
/* UART registers and bits */
|
||||
#define SER_RBR(x) ((x)+0)
|
||||
#define SER_THR(x) ((x)+0)
|
||||
#define SER_DLL(x) ((x)+0)
|
||||
#define SER_IER(x) ((x)+1)
|
||||
#define SER_DLM(x) ((x)+1)
|
||||
#define SER_FCR(x) ((x)+1)
|
||||
#define SER_IIR(x) ((x)+2)
|
||||
#define SR_IIR_SELF 0x01
|
||||
#define SR_IIR_ID_MASK 0x07
|
||||
#define SR_IIR_MSR_CHANGE SR_IIR_SELF
|
||||
#define SR_IIR_THR_EMPTY (SR_IIR_SELF | 2)
|
||||
#define SR_IIR_DATA_RECEIVED (SR_IIR_SELF | 4)
|
||||
#define SR_IIR_ERROR (SR_IIR_SELF | 6)
|
||||
#define SER_LCR(x) ((x)+3)
|
||||
#define SR_LCR_CS5 0x00
|
||||
#define SR_LCR_CS6 0x01
|
||||
#define SR_LCR_CS7 0x02
|
||||
#define SR_LCR_CS8 0x03
|
||||
#define SR_LCR_ST1 0x00
|
||||
#define SR_LCR_ST2 0x04
|
||||
#define SR_LCR_PNO 0x00
|
||||
#define SR_LCR_POD 0x08
|
||||
#define SR_LCR_PEV 0x18
|
||||
#define SR_LCR_PMK 0x28
|
||||
#define SR_LCR_PSP 0x38
|
||||
#define SR_LCR_BRK 0x40
|
||||
#define SR_LCR_DLAB 0x80
|
||||
#define SER_MCR(x) ((x)+4)
|
||||
#define SR_MCR_DTR 0x01
|
||||
#define SR_MCR_RTS 0x02
|
||||
#define SER_LSR(x) ((x)+5)
|
||||
#define SR_LSR_DR 0x01
|
||||
#define SR_LSR_TBE 0x20
|
||||
#define SER_MSR(x) ((x)+6)
|
||||
#define SR_MSR_CTS 0x10
|
||||
#define SR_MSR_DSR 0x20
|
||||
#define SER_SCR(x) ((x)+7)
|
||||
|
||||
/************************************ cleanup.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialCleanup(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ close.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialClose(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ create.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialCreate(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ devctrl.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialSetBaudRate(
|
||||
IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
|
||||
IN ULONG NewBaudRate);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialSetLineControl(
|
||||
IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
|
||||
IN PSERIAL_LINE_CONTROL NewSettings);
|
||||
|
||||
/************************************ info.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialQueryInformation(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ misc.c */
|
||||
|
||||
NTSTATUS
|
||||
ForwardIrpAndWait(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
BOOLEAN STDCALL
|
||||
SerialInterruptService(
|
||||
IN PKINTERRUPT Interrupt,
|
||||
IN OUT PVOID ServiceContext);
|
||||
|
||||
/************************************ pnp.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPnp(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ power.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPower(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ rw.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialRead(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialWrite(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
|
|
Loading…
Reference in a new issue