From e7005a93527f041ca0bcba810a31fc87cd6da616 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 15 Mar 2005 00:23:19 +0000 Subject: [PATCH] eol-style native svn path=/trunk/; revision=14086 --- reactos/drivers/dd/serial/cleanup.c | 44 +- reactos/drivers/dd/serial/close.c | 44 +- reactos/drivers/dd/serial/create.c | 104 +-- reactos/drivers/dd/serial/devctrl.c | 1102 +++++++++++++-------------- reactos/drivers/dd/serial/info.c | 158 ++-- reactos/drivers/dd/serial/misc.c | 350 ++++----- reactos/drivers/dd/serial/pnp.c | 550 ++++++------- reactos/drivers/dd/serial/power.c | 44 +- reactos/drivers/dd/serial/rw.c | 186 ++--- reactos/drivers/dd/serial/serial.h | 416 +++++----- 10 files changed, 1499 insertions(+), 1499 deletions(-) diff --git a/reactos/drivers/dd/serial/cleanup.c b/reactos/drivers/dd/serial/cleanup.c index 459318062e1..3ceee96f703 100644 --- a/reactos/drivers/dd/serial/cleanup.c +++ b/reactos/drivers/dd/serial/cleanup.c @@ -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; +} diff --git a/reactos/drivers/dd/serial/close.c b/reactos/drivers/dd/serial/close.c index efc95d9417a..2f3c16e90da 100644 --- a/reactos/drivers/dd/serial/close.c +++ b/reactos/drivers/dd/serial/close.c @@ -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; +} diff --git a/reactos/drivers/dd/serial/create.c b/reactos/drivers/dd/serial/create.c index 43c08015543..da28950135d 100644 --- a/reactos/drivers/dd/serial/create.c +++ b/reactos/drivers/dd/serial/create.c @@ -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; +} diff --git a/reactos/drivers/dd/serial/devctrl.c b/reactos/drivers/dd/serial/devctrl.c index 79d2f023e4d..e2affcd9a8d 100644 --- a/reactos/drivers/dd/serial/devctrl.c +++ b/reactos/drivers/dd/serial/devctrl.c @@ -1,551 +1,551 @@ -/* $Id: - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/dd/serial/devctrl.c - * PURPOSE: Serial IRP_MJ_DEVICE_CONTROL operations - * - * PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr) - */ -/* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */ - -#define NDEBUG -#include "serial.h" - -NTSTATUS STDCALL -SerialSetBaudRate( - IN PSERIAL_DEVICE_EXTENSION DeviceExtension, - IN ULONG NewBaudRate) -{ - USHORT divisor; - PUCHAR ComPortBase = (PUCHAR)DeviceExtension->BaseAddress; - NTSTATUS Status = STATUS_SUCCESS; - - if (NewBaudRate & SERIAL_BAUD_USER) - { - divisor = (USHORT)(BAUD_CLOCK / (CLOCKS_PER_BIT * (NewBaudRate & ~SERIAL_BAUD_USER))); - } - else - { - switch (NewBaudRate) - { - case SERIAL_BAUD_075: divisor = 0x600; break; - case SERIAL_BAUD_110: divisor = 0x400; break; - case SERIAL_BAUD_134_5: divisor = 0x360; break; - case SERIAL_BAUD_150: divisor = 0x300; break; - case SERIAL_BAUD_300: divisor = 0x180; break; - case SERIAL_BAUD_600: divisor = 0xc0; break; - case SERIAL_BAUD_1200: divisor = 0x60; break; - case SERIAL_BAUD_1800: divisor = 0x40; break; - case SERIAL_BAUD_2400: divisor = 0x30; break; - case SERIAL_BAUD_4800: divisor = 0x18; break; - case SERIAL_BAUD_7200: divisor = 0x10; break; - case SERIAL_BAUD_9600: divisor = 0xc; break; - case SERIAL_BAUD_14400: divisor = 0x8; break; - case SERIAL_BAUD_38400: divisor = 0x3; break; - case SERIAL_BAUD_57600: divisor = 0x2; break; - case SERIAL_BAUD_115200: divisor = 0x1; break; - case SERIAL_BAUD_56K: divisor = 0x2; break; - case SERIAL_BAUD_128K: divisor = 0x1; break; - default: Status = STATUS_INVALID_PARAMETER; - } - } - - if (NT_SUCCESS(Status)) - { - Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); - if (NT_SUCCESS(Status)) - { - UCHAR Lcr; - DPRINT("Serial: SerialSetBaudRate(COM%lu, %lu Bauds)\n", DeviceExtension->ComPort, BAUD_CLOCK / (CLOCKS_PER_BIT * divisor)); - /* FIXME: update DeviceExtension->LowerDevice when modifying LCR? */ - /* Set Bit 7 of LCR to expose baud registers */ - Lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase)); - Lcr |= SR_LCR_DLAB; - WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr); - /* Write the baud rate */ - WRITE_PORT_UCHAR(SER_DLL(ComPortBase), divisor & 0xff); - WRITE_PORT_UCHAR(SER_DLM(ComPortBase), divisor >> 8); - /* Switch back to normal registers */ - Lcr ^= SR_LCR_DLAB; - WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr); - - IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); - } - } - - if (NT_SUCCESS(Status)) - DeviceExtension->BaudRate = NewBaudRate; - return Status; -} - -NTSTATUS STDCALL -SerialSetLineControl( - IN PSERIAL_DEVICE_EXTENSION DeviceExtension, - IN PSERIAL_LINE_CONTROL NewSettings) -{ - UCHAR Lcr = 0; - NTSTATUS Status; - - DPRINT("Serial: SerialSetLineControl(COM%lu, Settings { %lu %lu %lu })\n", - DeviceExtension->ComPort, NewSettings->StopBits, NewSettings->Parity, NewSettings->WordLength); - - /* Verify parameters */ - switch (NewSettings->WordLength) - { - case 5: Lcr |= SR_LCR_CS5; break; - case 6: Lcr |= SR_LCR_CS6; break; - case 7: Lcr |= SR_LCR_CS7; break; - case 8: Lcr |= SR_LCR_CS8; break; - default: return STATUS_INVALID_PARAMETER; - } - - if (NewSettings->WordLength < 5 || NewSettings->WordLength > 8) - return STATUS_INVALID_PARAMETER; - - switch (NewSettings->Parity) - { - case NO_PARITY: Lcr |= SR_LCR_PNO; break; - case ODD_PARITY: Lcr |= SR_LCR_POD; break; - case EVEN_PARITY: Lcr |= SR_LCR_PEV; break; - case MARK_PARITY: Lcr |= SR_LCR_PMK; break; - case SPACE_PARITY: Lcr |= SR_LCR_PSP; break; - default: return STATUS_INVALID_PARAMETER; - } - - switch (NewSettings->StopBits) - { - case STOP_BIT_1: - Lcr |= SR_LCR_ST1; - break; - case STOP_BITS_1_5: - if (NewSettings->WordLength != 5) - return STATUS_INVALID_PARAMETER; - Lcr |= SR_LCR_ST2; - break; - case STOP_BITS_2: - if (NewSettings->WordLength < 6 || NewSettings->WordLength > 8) - return STATUS_INVALID_PARAMETER; - Lcr |= SR_LCR_ST2; - break; - default: - return STATUS_INVALID_PARAMETER; - } - - /* Update current parameters */ - Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); - if (!NT_SUCCESS(Status)) - return Status; - WRITE_PORT_UCHAR(SER_LCR((PUCHAR)DeviceExtension->BaseAddress), Lcr); - IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); - - if (NT_SUCCESS(Status)) - DeviceExtension->SerialLineControl = *NewSettings; - - return Status; -} - -NTSTATUS STDCALL -SerialDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - PSERIAL_DEVICE_EXTENSION DeviceExtension; - ULONG LengthIn, LengthOut; - ULONG Information = 0; - PUCHAR Buffer; - PUCHAR ComPortBase; - NTSTATUS Status; - - DPRINT("Serial: IRP_MJ_DEVICE_CONTROL dispatch\n"); - - /* FIXME: pend operation if possible */ - - Stack = IoGetCurrentIrpStackLocation(Irp); - LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength; - LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength; - Buffer = Irp->AssociatedIrp.SystemBuffer; - DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - ComPortBase = (PUCHAR)DeviceExtension->BaseAddress; - - /* FIXME: need to probe buffers */ - /* FIXME: see http://www.osronline.com/ddkx/serial/serref_61bm.htm */ - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_SERIAL_CLEAR_STATS: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_CLEAR_STATS not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_CLR_DTR: - { - DPRINT("Serial: IOCTL_SERIAL_CLR_DTR\n"); - /* FIXME: If the handshake flow control of the device is configured to - * automatically use DTR, return STATUS_INVALID_PARAMETER */ - DeviceExtension->MCR &= ~SR_MCR_DTR; - WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); - Status = STATUS_SUCCESS; - break; - } - case IOCTL_SERIAL_CLR_RTS: - { - DPRINT("Serial: IOCTL_SERIAL_CLR_RTS\n"); - /* FIXME: If the handshake flow control of the device is configured to - * automatically use RTS, return STATUS_INVALID_PARAMETER */ - DeviceExtension->MCR &= ~SR_MCR_RTS; - WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); - Status = STATUS_SUCCESS; - break; - } - case IOCTL_SERIAL_CONFIG_SIZE: - { - /* Obsolete on Microsoft Windows 2000+ */ - PULONG pConfigSize; - DPRINT("Serial: IOCTL_SERIAL_CONFIG_SIZE\n"); - if (LengthOut != sizeof(ULONG) || Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - pConfigSize = (PULONG)Buffer; - *pConfigSize = 0; - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_SERIAL_GET_BAUD_RATE: - { - DPRINT("Serial: IOCTL_SERIAL_GET_BAUD_RATE\n"); - if (LengthOut < sizeof(SERIAL_BAUD_RATE)) - Status = STATUS_BUFFER_TOO_SMALL; - else if (Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - ((PSERIAL_BAUD_RATE)Buffer)->BaudRate = DeviceExtension->BaudRate; - Information = sizeof(SERIAL_BAUD_RATE); - Status = STATUS_SUCCESS; - } - } - case IOCTL_SERIAL_GET_CHARS: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_GET_CHARS not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_GET_COMMSTATUS: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_GET_COMMSTATUS not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_GET_DTRRTS: - { - PULONG pDtrRts; - DPRINT("Serial: IOCTL_SERIAL_GET_DTRRTS\n"); - if (LengthOut != sizeof(ULONG) || Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - pDtrRts = (PULONG)Buffer; - *pDtrRts = 0; - if (DeviceExtension->MCR & SR_MCR_DTR) - *pDtrRts |= SERIAL_DTR_STATE; - if (DeviceExtension->MCR & SR_MCR_RTS) - *pDtrRts |= SERIAL_RTS_STATE; - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_SERIAL_GET_HANDFLOW: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_GET_HANDFLOW not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_GET_LINE_CONTROL: - { - DPRINT("Serial: IOCTL_SERIAL_GET_LINE_CONTROL\n"); - if (LengthOut < sizeof(SERIAL_LINE_CONTROL)) - Status = STATUS_BUFFER_TOO_SMALL; - else if (Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - *((PSERIAL_LINE_CONTROL)Buffer) = DeviceExtension->SerialLineControl; - Information = sizeof(SERIAL_LINE_CONTROL); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_SERIAL_GET_MODEM_CONTROL: - { - PULONG pMCR; - DPRINT("Serial: IOCTL_SERIAL_GET_MODEM_CONTROL\n"); - if (LengthOut != sizeof(ULONG) || Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - pMCR = (PULONG)Buffer; - *pMCR = DeviceExtension->MCR; - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_SERIAL_GET_MODEMSTATUS: - { - PULONG pMSR; - DPRINT("Serial: IOCTL_SERIAL_GET_MODEMSTATUS\n"); - if (LengthOut != sizeof(ULONG) || Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - pMSR = (PULONG)Buffer; - *pMSR = DeviceExtension->MSR; - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_SERIAL_GET_PROPERTIES: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_GET_PROPERTIES not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_GET_STATS: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_GET_STATS not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_GET_TIMEOUTS: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_GET_TIMEOUTS not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_GET_WAIT_MASK: - { - PULONG pWaitMask; - DPRINT("Serial: IOCTL_SERIAL_GET_WAIT_MASK\n"); - if (LengthOut != sizeof(ULONG) || Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - pWaitMask = (PULONG)Buffer; - *pWaitMask = DeviceExtension->WaitMask; - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_SERIAL_IMMEDIATE_CHAR: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_IMMEDIATE_CHAR not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_LSRMST_INSERT: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_LSRMST_INSERT not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_PURGE: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_PURGE not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_RESET_DEVICE: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_RESET_DEVICE not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_SET_BAUD_RATE: - { - PULONG pNewBaudRate; - DPRINT("Serial: IOCTL_SERIAL_SET_BAUD_RATE\n"); - if (LengthIn != sizeof(ULONG) || Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - pNewBaudRate = (PULONG)Buffer; - Status = SerialSetBaudRate(DeviceExtension, *pNewBaudRate); - } - break; - } - case IOCTL_SERIAL_SET_BREAK_OFF: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_BREAK_OFF not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_SET_BREAK_ON: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_BREAK_ON not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_SET_CHARS: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_CHARS not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_SET_DTR: - { - /* FIXME: If the handshake flow control of the device is configured to - * automatically use DTR, return STATUS_INVALID_PARAMETER */ - DPRINT("Serial: IOCTL_SERIAL_SET_DTR\n"); - if (!(DeviceExtension->MCR & SR_MCR_DTR)) - { - DeviceExtension->MCR |= SR_MCR_DTR; - WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); - } - Status = STATUS_SUCCESS; - break; - } - case IOCTL_SERIAL_SET_FIFO_CONTROL: - { - DPRINT("Serial: IOCTL_SERIAL_SET_FIFO_CONTROL\n"); - if (LengthIn != sizeof(ULONG) || Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - WRITE_PORT_UCHAR(SER_FCR(ComPortBase), (UCHAR)((*(PULONG)Buffer) & 0xff)); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_SERIAL_SET_HANDFLOW: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_HANDFLOW not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_SET_LINE_CONTROL: - { - DPRINT("Serial: IOCTL_SERIAL_SET_LINE_CONTROL\n"); - if (LengthIn < sizeof(SERIAL_LINE_CONTROL)) - Status = STATUS_BUFFER_TOO_SMALL; - else if (Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - Status = SerialSetLineControl(DeviceExtension, (PSERIAL_LINE_CONTROL)Buffer); - break; - } - case IOCTL_SERIAL_SET_MODEM_CONTROL: - { - PULONG pMCR; - DPRINT("Serial: IOCTL_SERIAL_SET_MODEM_CONTROL\n"); - if (LengthIn != sizeof(ULONG) || Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - pMCR = (PULONG)Buffer; - DeviceExtension->MCR = (UCHAR)(*pMCR & 0xff); - WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_SERIAL_SET_QUEUE_SIZE: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_QUEUE_SIZE not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_SET_RTS: - { - /* FIXME: If the handshake flow control of the device is configured to - * automatically use DTR, return STATUS_INVALID_PARAMETER */ - DPRINT("Serial: IOCTL_SERIAL_SET_RTS\n"); - if (!(DeviceExtension->MCR & SR_MCR_RTS)) - { - DeviceExtension->MCR |= SR_MCR_RTS; - WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); - } - Status = STATUS_SUCCESS; - break; - } - case IOCTL_SERIAL_SET_TIMEOUTS: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_TIMEOUTS not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_SET_WAIT_MASK: - { - PULONG pWaitMask; - DPRINT("Serial: IOCTL_SERIAL_SET_WAIT_MASK\n"); - if (LengthIn != sizeof(ULONG) || Buffer == NULL) - Status = STATUS_INVALID_PARAMETER; - else - { - pWaitMask = (PULONG)Buffer; - DeviceExtension->WaitMask = *pWaitMask; - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_SERIAL_SET_XOFF: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_XOFF not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_SET_XON: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_XON not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_WAIT_ON_MASK: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_WAIT_ON_MASK not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_SERIAL_XOFF_COUNTER: - { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_XOFF_COUNTER not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - default: - { - /* Pass Irp to lower driver */ - DPRINT("Serial: Unknown IOCTL code 0x%x\n", Stack->Parameters.DeviceIoControl.IoControlCode); - IoSkipCurrentIrpStackLocation(Irp); - return IoCallDriver(DeviceExtension->LowerDevice, Irp); - } - } - - 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/devctrl.c + * PURPOSE: Serial IRP_MJ_DEVICE_CONTROL operations + * + * PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr) + */ +/* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */ + +#define NDEBUG +#include "serial.h" + +NTSTATUS STDCALL +SerialSetBaudRate( + IN PSERIAL_DEVICE_EXTENSION DeviceExtension, + IN ULONG NewBaudRate) +{ + USHORT divisor; + PUCHAR ComPortBase = (PUCHAR)DeviceExtension->BaseAddress; + NTSTATUS Status = STATUS_SUCCESS; + + if (NewBaudRate & SERIAL_BAUD_USER) + { + divisor = (USHORT)(BAUD_CLOCK / (CLOCKS_PER_BIT * (NewBaudRate & ~SERIAL_BAUD_USER))); + } + else + { + switch (NewBaudRate) + { + case SERIAL_BAUD_075: divisor = 0x600; break; + case SERIAL_BAUD_110: divisor = 0x400; break; + case SERIAL_BAUD_134_5: divisor = 0x360; break; + case SERIAL_BAUD_150: divisor = 0x300; break; + case SERIAL_BAUD_300: divisor = 0x180; break; + case SERIAL_BAUD_600: divisor = 0xc0; break; + case SERIAL_BAUD_1200: divisor = 0x60; break; + case SERIAL_BAUD_1800: divisor = 0x40; break; + case SERIAL_BAUD_2400: divisor = 0x30; break; + case SERIAL_BAUD_4800: divisor = 0x18; break; + case SERIAL_BAUD_7200: divisor = 0x10; break; + case SERIAL_BAUD_9600: divisor = 0xc; break; + case SERIAL_BAUD_14400: divisor = 0x8; break; + case SERIAL_BAUD_38400: divisor = 0x3; break; + case SERIAL_BAUD_57600: divisor = 0x2; break; + case SERIAL_BAUD_115200: divisor = 0x1; break; + case SERIAL_BAUD_56K: divisor = 0x2; break; + case SERIAL_BAUD_128K: divisor = 0x1; break; + default: Status = STATUS_INVALID_PARAMETER; + } + } + + if (NT_SUCCESS(Status)) + { + Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); + if (NT_SUCCESS(Status)) + { + UCHAR Lcr; + DPRINT("Serial: SerialSetBaudRate(COM%lu, %lu Bauds)\n", DeviceExtension->ComPort, BAUD_CLOCK / (CLOCKS_PER_BIT * divisor)); + /* FIXME: update DeviceExtension->LowerDevice when modifying LCR? */ + /* Set Bit 7 of LCR to expose baud registers */ + Lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase)); + Lcr |= SR_LCR_DLAB; + WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr); + /* Write the baud rate */ + WRITE_PORT_UCHAR(SER_DLL(ComPortBase), divisor & 0xff); + WRITE_PORT_UCHAR(SER_DLM(ComPortBase), divisor >> 8); + /* Switch back to normal registers */ + Lcr ^= SR_LCR_DLAB; + WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr); + + IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); + } + } + + if (NT_SUCCESS(Status)) + DeviceExtension->BaudRate = NewBaudRate; + return Status; +} + +NTSTATUS STDCALL +SerialSetLineControl( + IN PSERIAL_DEVICE_EXTENSION DeviceExtension, + IN PSERIAL_LINE_CONTROL NewSettings) +{ + UCHAR Lcr = 0; + NTSTATUS Status; + + DPRINT("Serial: SerialSetLineControl(COM%lu, Settings { %lu %lu %lu })\n", + DeviceExtension->ComPort, NewSettings->StopBits, NewSettings->Parity, NewSettings->WordLength); + + /* Verify parameters */ + switch (NewSettings->WordLength) + { + case 5: Lcr |= SR_LCR_CS5; break; + case 6: Lcr |= SR_LCR_CS6; break; + case 7: Lcr |= SR_LCR_CS7; break; + case 8: Lcr |= SR_LCR_CS8; break; + default: return STATUS_INVALID_PARAMETER; + } + + if (NewSettings->WordLength < 5 || NewSettings->WordLength > 8) + return STATUS_INVALID_PARAMETER; + + switch (NewSettings->Parity) + { + case NO_PARITY: Lcr |= SR_LCR_PNO; break; + case ODD_PARITY: Lcr |= SR_LCR_POD; break; + case EVEN_PARITY: Lcr |= SR_LCR_PEV; break; + case MARK_PARITY: Lcr |= SR_LCR_PMK; break; + case SPACE_PARITY: Lcr |= SR_LCR_PSP; break; + default: return STATUS_INVALID_PARAMETER; + } + + switch (NewSettings->StopBits) + { + case STOP_BIT_1: + Lcr |= SR_LCR_ST1; + break; + case STOP_BITS_1_5: + if (NewSettings->WordLength != 5) + return STATUS_INVALID_PARAMETER; + Lcr |= SR_LCR_ST2; + break; + case STOP_BITS_2: + if (NewSettings->WordLength < 6 || NewSettings->WordLength > 8) + return STATUS_INVALID_PARAMETER; + Lcr |= SR_LCR_ST2; + break; + default: + return STATUS_INVALID_PARAMETER; + } + + /* Update current parameters */ + Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); + if (!NT_SUCCESS(Status)) + return Status; + WRITE_PORT_UCHAR(SER_LCR((PUCHAR)DeviceExtension->BaseAddress), Lcr); + IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); + + if (NT_SUCCESS(Status)) + DeviceExtension->SerialLineControl = *NewSettings; + + return Status; +} + +NTSTATUS STDCALL +SerialDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + PSERIAL_DEVICE_EXTENSION DeviceExtension; + ULONG LengthIn, LengthOut; + ULONG Information = 0; + PUCHAR Buffer; + PUCHAR ComPortBase; + NTSTATUS Status; + + DPRINT("Serial: IRP_MJ_DEVICE_CONTROL dispatch\n"); + + /* FIXME: pend operation if possible */ + + Stack = IoGetCurrentIrpStackLocation(Irp); + LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength; + LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength; + Buffer = Irp->AssociatedIrp.SystemBuffer; + DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ComPortBase = (PUCHAR)DeviceExtension->BaseAddress; + + /* FIXME: need to probe buffers */ + /* FIXME: see http://www.osronline.com/ddkx/serial/serref_61bm.htm */ + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_SERIAL_CLEAR_STATS: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_CLEAR_STATS not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_CLR_DTR: + { + DPRINT("Serial: IOCTL_SERIAL_CLR_DTR\n"); + /* FIXME: If the handshake flow control of the device is configured to + * automatically use DTR, return STATUS_INVALID_PARAMETER */ + DeviceExtension->MCR &= ~SR_MCR_DTR; + WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); + Status = STATUS_SUCCESS; + break; + } + case IOCTL_SERIAL_CLR_RTS: + { + DPRINT("Serial: IOCTL_SERIAL_CLR_RTS\n"); + /* FIXME: If the handshake flow control of the device is configured to + * automatically use RTS, return STATUS_INVALID_PARAMETER */ + DeviceExtension->MCR &= ~SR_MCR_RTS; + WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); + Status = STATUS_SUCCESS; + break; + } + case IOCTL_SERIAL_CONFIG_SIZE: + { + /* Obsolete on Microsoft Windows 2000+ */ + PULONG pConfigSize; + DPRINT("Serial: IOCTL_SERIAL_CONFIG_SIZE\n"); + if (LengthOut != sizeof(ULONG) || Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + pConfigSize = (PULONG)Buffer; + *pConfigSize = 0; + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_SERIAL_GET_BAUD_RATE: + { + DPRINT("Serial: IOCTL_SERIAL_GET_BAUD_RATE\n"); + if (LengthOut < sizeof(SERIAL_BAUD_RATE)) + Status = STATUS_BUFFER_TOO_SMALL; + else if (Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + ((PSERIAL_BAUD_RATE)Buffer)->BaudRate = DeviceExtension->BaudRate; + Information = sizeof(SERIAL_BAUD_RATE); + Status = STATUS_SUCCESS; + } + } + case IOCTL_SERIAL_GET_CHARS: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_GET_CHARS not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_GET_COMMSTATUS: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_GET_COMMSTATUS not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_GET_DTRRTS: + { + PULONG pDtrRts; + DPRINT("Serial: IOCTL_SERIAL_GET_DTRRTS\n"); + if (LengthOut != sizeof(ULONG) || Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + pDtrRts = (PULONG)Buffer; + *pDtrRts = 0; + if (DeviceExtension->MCR & SR_MCR_DTR) + *pDtrRts |= SERIAL_DTR_STATE; + if (DeviceExtension->MCR & SR_MCR_RTS) + *pDtrRts |= SERIAL_RTS_STATE; + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_SERIAL_GET_HANDFLOW: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_GET_HANDFLOW not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_GET_LINE_CONTROL: + { + DPRINT("Serial: IOCTL_SERIAL_GET_LINE_CONTROL\n"); + if (LengthOut < sizeof(SERIAL_LINE_CONTROL)) + Status = STATUS_BUFFER_TOO_SMALL; + else if (Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + *((PSERIAL_LINE_CONTROL)Buffer) = DeviceExtension->SerialLineControl; + Information = sizeof(SERIAL_LINE_CONTROL); + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_SERIAL_GET_MODEM_CONTROL: + { + PULONG pMCR; + DPRINT("Serial: IOCTL_SERIAL_GET_MODEM_CONTROL\n"); + if (LengthOut != sizeof(ULONG) || Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + pMCR = (PULONG)Buffer; + *pMCR = DeviceExtension->MCR; + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_SERIAL_GET_MODEMSTATUS: + { + PULONG pMSR; + DPRINT("Serial: IOCTL_SERIAL_GET_MODEMSTATUS\n"); + if (LengthOut != sizeof(ULONG) || Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + pMSR = (PULONG)Buffer; + *pMSR = DeviceExtension->MSR; + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_SERIAL_GET_PROPERTIES: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_GET_PROPERTIES not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_GET_STATS: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_GET_STATS not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_GET_TIMEOUTS: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_GET_TIMEOUTS not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_GET_WAIT_MASK: + { + PULONG pWaitMask; + DPRINT("Serial: IOCTL_SERIAL_GET_WAIT_MASK\n"); + if (LengthOut != sizeof(ULONG) || Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + pWaitMask = (PULONG)Buffer; + *pWaitMask = DeviceExtension->WaitMask; + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_SERIAL_IMMEDIATE_CHAR: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_IMMEDIATE_CHAR not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_LSRMST_INSERT: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_LSRMST_INSERT not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_PURGE: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_PURGE not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_RESET_DEVICE: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_RESET_DEVICE not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_SET_BAUD_RATE: + { + PULONG pNewBaudRate; + DPRINT("Serial: IOCTL_SERIAL_SET_BAUD_RATE\n"); + if (LengthIn != sizeof(ULONG) || Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + pNewBaudRate = (PULONG)Buffer; + Status = SerialSetBaudRate(DeviceExtension, *pNewBaudRate); + } + break; + } + case IOCTL_SERIAL_SET_BREAK_OFF: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_SET_BREAK_OFF not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_SET_BREAK_ON: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_SET_BREAK_ON not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_SET_CHARS: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_SET_CHARS not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_SET_DTR: + { + /* FIXME: If the handshake flow control of the device is configured to + * automatically use DTR, return STATUS_INVALID_PARAMETER */ + DPRINT("Serial: IOCTL_SERIAL_SET_DTR\n"); + if (!(DeviceExtension->MCR & SR_MCR_DTR)) + { + DeviceExtension->MCR |= SR_MCR_DTR; + WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); + } + Status = STATUS_SUCCESS; + break; + } + case IOCTL_SERIAL_SET_FIFO_CONTROL: + { + DPRINT("Serial: IOCTL_SERIAL_SET_FIFO_CONTROL\n"); + if (LengthIn != sizeof(ULONG) || Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + WRITE_PORT_UCHAR(SER_FCR(ComPortBase), (UCHAR)((*(PULONG)Buffer) & 0xff)); + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_SERIAL_SET_HANDFLOW: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_SET_HANDFLOW not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_SET_LINE_CONTROL: + { + DPRINT("Serial: IOCTL_SERIAL_SET_LINE_CONTROL\n"); + if (LengthIn < sizeof(SERIAL_LINE_CONTROL)) + Status = STATUS_BUFFER_TOO_SMALL; + else if (Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + Status = SerialSetLineControl(DeviceExtension, (PSERIAL_LINE_CONTROL)Buffer); + break; + } + case IOCTL_SERIAL_SET_MODEM_CONTROL: + { + PULONG pMCR; + DPRINT("Serial: IOCTL_SERIAL_SET_MODEM_CONTROL\n"); + if (LengthIn != sizeof(ULONG) || Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + pMCR = (PULONG)Buffer; + DeviceExtension->MCR = (UCHAR)(*pMCR & 0xff); + WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_SERIAL_SET_QUEUE_SIZE: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_SET_QUEUE_SIZE not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_SET_RTS: + { + /* FIXME: If the handshake flow control of the device is configured to + * automatically use DTR, return STATUS_INVALID_PARAMETER */ + DPRINT("Serial: IOCTL_SERIAL_SET_RTS\n"); + if (!(DeviceExtension->MCR & SR_MCR_RTS)) + { + DeviceExtension->MCR |= SR_MCR_RTS; + WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR); + } + Status = STATUS_SUCCESS; + break; + } + case IOCTL_SERIAL_SET_TIMEOUTS: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_SET_TIMEOUTS not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_SET_WAIT_MASK: + { + PULONG pWaitMask; + DPRINT("Serial: IOCTL_SERIAL_SET_WAIT_MASK\n"); + if (LengthIn != sizeof(ULONG) || Buffer == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + pWaitMask = (PULONG)Buffer; + DeviceExtension->WaitMask = *pWaitMask; + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_SERIAL_SET_XOFF: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_SET_XOFF not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_SET_XON: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_SET_XON not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_WAIT_ON_MASK: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_WAIT_ON_MASK not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_SERIAL_XOFF_COUNTER: + { + /* FIXME */ + DPRINT1("Serial: IOCTL_SERIAL_XOFF_COUNTER not implemented.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + default: + { + /* Pass Irp to lower driver */ + DPRINT("Serial: Unknown IOCTL code 0x%x\n", Stack->Parameters.DeviceIoControl.IoControlCode); + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->LowerDevice, Irp); + } + } + + Irp->IoStatus.Information = Information; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} diff --git a/reactos/drivers/dd/serial/info.c b/reactos/drivers/dd/serial/info.c index 4240be2767a..2170dc332b3 100644 --- a/reactos/drivers/dd/serial/info.c +++ b/reactos/drivers/dd/serial/info.c @@ -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; +} diff --git a/reactos/drivers/dd/serial/misc.c b/reactos/drivers/dd/serial/misc.c index f199083a8c6..2f42b7cad0b 100644 --- a/reactos/drivers/dd/serial/misc.c +++ b/reactos/drivers/dd/serial/misc.c @@ -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 +} diff --git a/reactos/drivers/dd/serial/pnp.c b/reactos/drivers/dd/serial/pnp.c index 6c4bae2c7ee..1510cea5703 100644 --- a/reactos/drivers/dd/serial/pnp.c +++ b/reactos/drivers/dd/serial/pnp.c @@ -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; +} diff --git a/reactos/drivers/dd/serial/power.c b/reactos/drivers/dd/serial/power.c index 798ca428ce5..a28507064f9 100644 --- a/reactos/drivers/dd/serial/power.c +++ b/reactos/drivers/dd/serial/power.c @@ -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; +} diff --git a/reactos/drivers/dd/serial/rw.c b/reactos/drivers/dd/serial/rw.c index e14ac899398..b1cfebbaabe 100644 --- a/reactos/drivers/dd/serial/rw.c +++ b/reactos/drivers/dd/serial/rw.c @@ -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; +} diff --git a/reactos/drivers/dd/serial/serial.h b/reactos/drivers/dd/serial/serial.h index d9db7e11c36..a1728b54842 100644 --- a/reactos/drivers/dd/serial/serial.h +++ b/reactos/drivers/dd/serial/serial.h @@ -1,208 +1,208 @@ -#if defined(__GNUC__) - #include - #include - #include - - #include - - /* 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 - #include - #include - - #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 + #include + #include + + #include + + /* 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 + #include + #include + + #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); +