Author: ekohl
Date: Thu May 14 14:42:05 2015
New Revision: 67713
URL:
http://svn.reactos.org/svn/reactos?rev=67713&view=rev
Log:
[PARPORT]
Implement basic funtions of the parallel port driver. It supports Centronics-Mode only.
You can print files using: copy <filename> lpt1:
Added:
trunk/reactos/drivers/parallel/parport/fdo.c (with props)
trunk/reactos/drivers/parallel/parport/misc.c (with props)
trunk/reactos/drivers/parallel/parport/pdo.c (with props)
Modified:
trunk/reactos/drivers/parallel/parport/CMakeLists.txt
trunk/reactos/drivers/parallel/parport/parport.c
trunk/reactos/drivers/parallel/parport/parport.h
Modified: trunk/reactos/drivers/parallel/parport/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/C…
==============================================================================
--- trunk/reactos/drivers/parallel/parport/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/drivers/parallel/parport/CMakeLists.txt [iso-8859-1] Thu May 14 14:42:05
2015
@@ -1,5 +1,16 @@
-add_library(parport SHARED parport.c parport.rc)
+list(APPEND SOURCE
+ fdo.c
+ misc.c
+ pdo.c
+ parport.c
+ parport.h)
+
+add_library(parport SHARED
+ ${SOURCE}
+ parport.rc)
+
set_module_type(parport kernelmodedriver)
+add_pch(parport parport.h SOURCE)
add_importlibs(parport ntoskrnl hal)
add_cd_file(TARGET parport DESTINATION reactos/system32/drivers FOR all)
Added: trunk/reactos/drivers/parallel/parport/fdo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/f…
==============================================================================
--- trunk/reactos/drivers/parallel/parport/fdo.c (added)
+++ trunk/reactos/drivers/parallel/parport/fdo.c [iso-8859-1] Thu May 14 14:42:05 2015
@@ -0,0 +1,572 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Parallel Port Function Driver
+ * FILE: drivers/parallel/parport/fdo.c
+ * PURPOSE: FDO functions
+ */
+
+#include "parport.h"
+
+/*
+ * The following constants describe the various signals of the printer port
+ * hardware. Note that the hardware inverts some signals and that some
+ * signals are active low. An example is LP_STROBE, which must be programmed
+ * with 1 for being active and 0 for being inactive, because the strobe signal
+ * gets inverted, but it is also active low.
+ */
+
+/*
+ * bit defines for 8255 status port
+ * base + 1
+ * accessed with LP_S(minor), which gets the byte...
+ */
+#define LP_PBUSY 0x80 /* inverted input, active high */
+#define LP_PACK 0x40 /* unchanged input, active low */
+#define LP_POUTPA 0x20 /* unchanged input, active high */
+#define LP_PSELECD 0x10 /* unchanged input, active high */
+#define LP_PERRORP 0x08 /* unchanged input, active low */
+
+/*
+ * defines for 8255 control port
+ * base + 2
+ * accessed with LP_C(minor)
+ */
+#define LP_PINTEN 0x10
+#define LP_PSELECP 0x08 /* inverted output, active low */
+#define LP_PINITP 0x04 /* unchanged output, active low */
+#define LP_PAUTOLF 0x02 /* inverted output, active low */
+#define LP_PSTROBE 0x01 /* inverted output, active low */
+
+
+/* FUNCTIONS ****************************************************************/
+
+NTSTATUS
+NTAPI
+AddDeviceInternal(IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT Pdo,
+ IN PULONG pLptPortNumber OPTIONAL,
+ OUT PDEVICE_OBJECT* pFdo OPTIONAL)
+{
+ PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
+ PDEVICE_OBJECT Fdo = NULL;
+ WCHAR DeviceNameBuffer[32];
+ UNICODE_STRING DeviceName;
+ NTSTATUS Status;
+
+ DPRINT("AddDeviceInternal()\n");
+
+ ASSERT(DriverObject);
+ ASSERT(Pdo);
+
+ /* Create new device object */
+ swprintf(DeviceNameBuffer,
+ L"\\Device\\ParallelPort%lu",
+ IoGetConfigurationInformation()->ParallelCount);
+ RtlInitUnicodeString(&DeviceName,
+ DeviceNameBuffer);
+
+ Status = IoCreateDevice(DriverObject,
+ sizeof(FDO_DEVICE_EXTENSION),
+ &DeviceName,
+ FILE_DEVICE_PARALLEL_PORT,
+ FILE_DEVICE_SECURE_OPEN,
+ FALSE,
+ &Fdo);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoCreateDevice() failed (Status 0x%08lx)\n", Status);
+ Fdo = NULL;
+ goto done;
+ }
+
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
+ RtlZeroMemory(DeviceExtension,
+ sizeof(FDO_DEVICE_EXTENSION));
+
+ DeviceExtension->Common.IsFDO = TRUE;
+ DeviceExtension->Common.PnpState = dsStopped;
+
+ DeviceExtension->ParallelPortNumber =
IoGetConfigurationInformation()->ParallelCount++;
+ if (pLptPortNumber == NULL)
+ DeviceExtension->LptPort = DeviceExtension->ParallelPortNumber + 1;
+ else
+ DeviceExtension->LptPort = *pLptPortNumber;
+ DeviceExtension->Pdo = Pdo;
+
+ Status = IoAttachDeviceToDeviceStackSafe(Fdo,
+ Pdo,
+ &DeviceExtension->LowerDevice);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoAttachDeviceToDeviceStackSafe() failed (Status 0x%08lx)\n",
Status);
+ goto done;
+ }
+
+ if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
+ Fdo->Flags |= DO_POWER_PAGABLE;
+
+ if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO)
+ Fdo->Flags |= DO_BUFFERED_IO;
+
+ if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO)
+ Fdo->Flags |= DO_DIRECT_IO;
+
+ /* Choose default strategy */
+ if ((Fdo->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO)) == 0)
+ Fdo->Flags |= DO_BUFFERED_IO;
+
+ Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ if (pFdo)
+ {
+ *pFdo = Fdo;
+ }
+
+ return STATUS_SUCCESS;
+
+done:
+ if (Fdo)
+ {
+ IoDeleteDevice(Fdo);
+ }
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+FdoStartDevice(IN PDEVICE_OBJECT DeviceObject,
+ IN PCM_RESOURCE_LIST ResourceList,
+ IN PCM_RESOURCE_LIST ResourceListTranslated)
+{
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+ WCHAR DeviceNameBuffer[32];
+ WCHAR LinkNameBuffer[32];
+ WCHAR LptPortBuffer[32];
+ UNICODE_STRING DeviceName;
+ UNICODE_STRING LinkName;
+ UNICODE_STRING LptPort;
+ ULONG i;
+// ULONG Vector = 0;
+// KIRQL Dirql = 0;
+// KAFFINITY Affinity = 0;
+// KINTERRUPT_MODE InterruptMode = Latched;
+// BOOLEAN ShareInterrupt = TRUE;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyName;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+
+ DPRINT("FdoStartDevice ()\n");
+
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ ASSERT(DeviceExtension);
+ ASSERT(DeviceExtension->Common.IsFDO == TRUE);
+
+ if (!ResourceList)
+ {
+ DPRINT1("No allocated resources sent to driver\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (ResourceList->Count != 1)
+ {
+ DPRINT1("Wrong number of allocated resources sent to driver\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if ((ResourceList->List[0].PartialResourceList.Version != 1) ||
+ (ResourceList->List[0].PartialResourceList.Revision != 1) ||
+ (ResourceListTranslated->List[0].PartialResourceList.Version != 1) ||
+ (ResourceListTranslated->List[0].PartialResourceList.Revision != 1))
+ {
+ DPRINT1("Revision mismatch: %u.%u != 1.1 or %u.%u != 1.1\n",
+ ResourceList->List[0].PartialResourceList.Version,
+ ResourceList->List[0].PartialResourceList.Revision,
+ ResourceListTranslated->List[0].PartialResourceList.Version,
+ ResourceListTranslated->List[0].PartialResourceList.Revision);
+ return STATUS_REVISION_MISMATCH;
+ }
+
+ DeviceExtension->BaseAddress = 0;
+
+ for (i = 0; i < ResourceList->List[0].PartialResourceList.Count; i++)
+ {
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor =
&ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorTranslated =
&ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[i];
+
+ switch (PartialDescriptor->Type)
+ {
+ case CmResourceTypePort:
+ DPRINT("Port: BaseAddress 0x%lx Length %lu\n",
+ PartialDescriptor->u.Port.Start.u.LowPart,
+ PartialDescriptor->u.Port.Length);
+
+ if (DeviceExtension->BaseAddress == 0)
+ {
+ if (PartialDescriptor->u.Port.Length < 8)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ DeviceExtension->BaseAddress =
PartialDescriptor->u.Port.Start.u.LowPart;
+ }
+ break;
+
+ case CmResourceTypeInterrupt:
+ DPRINT("Interrupt: Level %lu Vector %lu\n",
+ PartialDescriptorTranslated->u.Interrupt.Level,
+ PartialDescriptorTranslated->u.Interrupt.Vector);
+
+// Dirql = (KIRQL)PartialDescriptorTranslated->u.Interrupt.Level;
+// Vector = PartialDescriptorTranslated->u.Interrupt.Vector;
+// Affinity = PartialDescriptorTranslated->u.Interrupt.Affinity;
+
+// if (PartialDescriptorTranslated->Flags &
CM_RESOURCE_INTERRUPT_LATCHED)
+// InterruptMode = Latched;
+// else
+// InterruptMode = LevelSensitive;
+
+// ShareInterrupt = (PartialDescriptorTranslated->ShareDisposition ==
CmResourceShareShared);
+ break;
+
+ default:
+ DPRINT1("Other ressource: \n");
+ break;
+ }
+ }
+
+ DPRINT("New LPT port: Base 0x%lx\n",
+ DeviceExtension->BaseAddress);
+
+ if (!DeviceExtension->BaseAddress)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+#if 0
+ if (!Dirql)
+ return STATUS_INSUFFICIENT_RESOURCES;
+#endif
+
+ /* Create link \DosDevices\LPTX -> \Device\ParallelPortX */
+ swprintf(DeviceNameBuffer, L"\\Device\\ParallelPort%lu",
DeviceExtension->ParallelPortNumber);
+ swprintf(LinkNameBuffer, L"\\DosDevices\\LPT%lu",
DeviceExtension->LptPort);
+ swprintf(LptPortBuffer, L"LPT%lu", DeviceExtension->LptPort);
+ RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
+ RtlInitUnicodeString(&LinkName, LinkNameBuffer);
+ RtlInitUnicodeString(&LptPort, LptPortBuffer);
+ Status = IoCreateSymbolicLink(&LinkName,
+ &DeviceName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoCreateSymbolicLink() failed with status 0x%08x\n", Status);
+ return Status;
+ }
+
+
+ /* Write an entry value under HKLM\HARDWARE\DeviceMap\PARALLEL PORTS. */
+ /* This step is not mandatory, so do not exit in case of error. */
+ RtlInitUnicodeString(&KeyName,
+ L"\\Registry\\Machine\\HARDWARE\\DeviceMap\\PARALLEL
PORTS");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = ZwCreateKey(&KeyHandle,
+ KEY_SET_VALUE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* Key = \Device\Parallelx, Value = LPTx */
+ ZwSetValueKey(KeyHandle,
+ &DeviceName,
+ 0,
+ REG_SZ,
+ LptPortBuffer,
+ LptPort.Length + sizeof(WCHAR));
+ ZwClose(KeyHandle);
+ }
+
+ DeviceExtension->Common.PnpState = dsStarted;
+
+
+ /* We don't really care if the call succeeded or not... */
+
+ return STATUS_SUCCESS;
+}
+
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+NTSTATUS
+NTAPI
+AddDevice(IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT Pdo)
+{
+ DPRINT("AddDevice(%p %p)\n", DriverObject, Pdo);
+
+ /* Serial.sys is a legacy driver. AddDevice is called once
+ * with a NULL Pdo just after the driver initialization.
+ * Detect this case and return success.
+ */
+ if (Pdo == NULL)
+ return STATUS_SUCCESS;
+
+ /* We have here a PDO not null. It represents a real serial
+ * port. So call the internal AddDevice function.
+ */
+ return AddDeviceInternal(DriverObject, Pdo, NULL, NULL);
+}
+
+
+NTSTATUS
+NTAPI
+FdoCreate(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("FdoCreate()\n");
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ if (Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
+ {
+ DPRINT1("Not a directory\n");
+ Status = STATUS_NOT_A_DIRECTORY;
+ goto done;
+ }
+
+ DPRINT("Open LPT%lu: successful\n", DeviceExtension->LptPort);
+ DeviceExtension->OpenCount++;
+
+done:
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+FdoClose(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PFDO_DEVICE_EXTENSION pDeviceExtension;
+
+ DPRINT("FdoClose()\n");
+
+ pDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ pDeviceExtension->OpenCount--;
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+FdoCleanup(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("FdoCleanup()\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+FdoWrite(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+ PIO_STACK_LOCATION IoStack;
+ PUCHAR Buffer;
+ ULONG i;
+ UCHAR PortStatus;
+ ULONG ulCount;
+
+ DPRINT("FdoWrite()\n");
+
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ Buffer = GetUserBuffer(Irp);
+ DPRINT("Length: %lu\n", IoStack->Parameters.Write.Length);
+ DPRINT("Buffer: %p\n", Buffer);
+
+ if (Buffer != NULL)
+ {
+ DPRINT("%s\n", Buffer);
+ }
+
+ for (i = 0; i < IoStack->Parameters.Write.Length; i++)
+ {
+ DPRINT("%lu: %c\n", i, Buffer[i]);
+
+ ulCount = 0;
+
+ do
+ {
+ KeStallExecutionProcessor(10);
+ PortStatus = READ_PORT_UCHAR((PUCHAR)(DeviceExtension->BaseAddress + 1));
+ ulCount++;
+ }
+ while (ulCount < 500000 && !(PortStatus & LP_PBUSY));
+
+ if (ulCount == 500000)
+ {
+ DPRINT1("Timed out\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_TIMEOUT;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_TIMEOUT;
+ }
+
+ /* Write character */
+ WRITE_PORT_UCHAR((PUCHAR)DeviceExtension->BaseAddress, Buffer[i]);
+
+ KeStallExecutionProcessor(10);
+
+ WRITE_PORT_UCHAR((PUCHAR)(DeviceExtension->BaseAddress + 2), (LP_PSELECP |
LP_PINITP | LP_PSTROBE));
+
+ KeStallExecutionProcessor(10);
+
+ WRITE_PORT_UCHAR((PUCHAR)(DeviceExtension->BaseAddress + 2), (LP_PSELECP |
LP_PINITP));
+ }
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+FdoPnp(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ ULONG MinorFunction;
+ PIO_STACK_LOCATION Stack;
+ ULONG_PTR Information = 0;
+ NTSTATUS Status;
+
+ DPRINT("FdoPnp()\n");
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = Stack->MinorFunction;
+
+ switch (MinorFunction)
+ {
+ /* FIXME: do all these minor functions
+ IRP_MN_QUERY_REMOVE_DEVICE 0x1
+ IRP_MN_REMOVE_DEVICE 0x2
+ {
+ TRACE_(SERIAL, "IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
+ IoAcquireRemoveLock
+ IoReleaseRemoveLockAndWait
+ pass request to DeviceExtension-LowerDriver
+ disable interface
+ IoDeleteDevice(Fdo) and/or IoDetachDevice
+ break;
+ }
+ IRP_MN_CANCEL_REMOVE_DEVICE 0x3
+ IRP_MN_STOP_DEVICE 0x4
+ IRP_MN_QUERY_STOP_DEVICE 0x5
+ IRP_MN_CANCEL_STOP_DEVICE 0x6
+ IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations (optional) 0x7
+ IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) 0x7
+ IRP_MN_QUERY_INTERFACE (optional) 0x8
+ IRP_MN_QUERY_CAPABILITIES (optional) 0x9
+ IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional) 0xd
+ IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
+ IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
+ IRP_MN_SURPRISE_REMOVAL 0x17
+ */
+ case IRP_MN_START_DEVICE: /* 0x0 */
+ DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+
+
ASSERT(((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.PnpState ==
dsStopped);
+
+ /* Call lower driver */
+ Status = ForwardIrpAndWait(DeviceObject, Irp);
+ if (NT_SUCCESS(Status))
+ {
+ Status = FdoStartDevice(DeviceObject,
+
Stack->Parameters.StartDevice.AllocatedResources,
+
Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
+ }
+ break;
+
+ case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
+ switch (Stack->Parameters.QueryDeviceRelations.Type)
+ {
+ case BusRelations:
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS /
BusRelations\n");
+ return ForwardIrpAndForget(DeviceObject, Irp);
+
+ case RemovalRelations:
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS /
RemovalRelations\n");
+ return ForwardIrpAndForget(DeviceObject, Irp);
+
+ default:
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown
type 0x%lx\n",
+ Stack->Parameters.QueryDeviceRelations.Type);
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ break;
+
+ case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0xd */
+ DPRINT1("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
+ return ForwardIrpAndForget(DeviceObject, Irp);
+
+ default:
+ DPRINT1("Unknown minor function 0x%x\n", MinorFunction);
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+FdoPower(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("FdoPower()\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+/* EOF */
Propchange: trunk/reactos/drivers/parallel/parport/fdo.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/parallel/parport/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/m…
==============================================================================
--- trunk/reactos/drivers/parallel/parport/misc.c (added)
+++ trunk/reactos/drivers/parallel/parport/misc.c [iso-8859-1] Thu May 14 14:42:05 2015
@@ -0,0 +1,83 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Parallel Port Function Driver
+ * FILE: drivers/parallel/parport/misc.c
+ * PURPOSE: Miscellaneous functions
+ */
+
+#include "parport.h"
+
+
+static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion;
+
+/* FUNCTIONS ****************************************************************/
+
+static
+NTSTATUS
+NTAPI
+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;
+ KEVENT Event;
+ NTSTATUS Status;
+
+ LowerDevice =
((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+ ASSERT(LowerDevice);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+
+ DPRINT("Calling lower device %p\n", LowerDevice);
+ 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;
+}
+
+
+NTSTATUS
+NTAPI
+ForwardIrpAndForget(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PDEVICE_OBJECT LowerDevice;
+
+ LowerDevice =
((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+ ASSERT(LowerDevice);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(LowerDevice, Irp);
+}
+
+
+PVOID
+GetUserBuffer(IN PIRP Irp)
+{
+ ASSERT(Irp);
+
+ if (Irp->MdlAddress)
+ return Irp->MdlAddress;
+ else
+ return Irp->AssociatedIrp.SystemBuffer;
+}
+
+/* EOF */
Propchange: trunk/reactos/drivers/parallel/parport/misc.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/drivers/parallel/parport/parport.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/p…
==============================================================================
--- trunk/reactos/drivers/parallel/parport/parport.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/parallel/parport/parport.c [iso-8859-1] Thu May 14 14:42:05
2015
@@ -7,7 +7,15 @@
#include "parport.h"
static DRIVER_UNLOAD DriverUnload;
+static DRIVER_DISPATCH DispatchCreate;
+static DRIVER_DISPATCH DispatchClose;
+static DRIVER_DISPATCH DispatchCleanup;
+static DRIVER_DISPATCH DispatchPnp;
+static DRIVER_DISPATCH DispatchPower;
DRIVER_INITIALIZE DriverEntry;
+
+
+/* FUNCTIONS ****************************************************************/
static
VOID
@@ -17,14 +25,109 @@
DPRINT("Parport DriverUnload\n");
}
+
+static
+NTSTATUS
+NTAPI
+DispatchCreate(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+ return FdoCreate(DeviceObject, Irp);
+ else
+ return PdoCreate(DeviceObject, Irp);
+}
+
+
+static
+NTSTATUS
+NTAPI
+DispatchClose(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+ return FdoClose(DeviceObject, Irp);
+ else
+ return PdoClose(DeviceObject, Irp);
+}
+
+
+static
+NTSTATUS
+NTAPI
+DispatchCleanup(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+ return FdoCleanup(DeviceObject, Irp);
+ else
+ return PdoCleanup(DeviceObject, Irp);
+}
+
+
+static
+NTSTATUS
+NTAPI
+DispatchWrite(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+ return FdoWrite(DeviceObject, Irp);
+ else
+ return PdoWrite(DeviceObject, Irp);
+}
+
+
+static
+NTSTATUS
+NTAPI
+DispatchPnp(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+ return FdoPnp(DeviceObject, Irp);
+ else
+ return PdoPnp(DeviceObject, Irp);
+}
+
+
+static
+NTSTATUS
+NTAPI
+DispatchPower(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+ return FdoPower(DeviceObject, Irp);
+ else
+ return PdoPower(DeviceObject, Irp);
+}
+
+
NTSTATUS
NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegPath)
{
+ ULONG i;
+
DPRINT("Parport DriverEntry\n");
DriverObject->DriverUnload = DriverUnload;
+ DriverObject->DriverExtension->AddDevice = AddDevice;
+
+ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
+ DriverObject->MajorFunction[i] = ForwardIrpAndForget;
+
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
+ DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
+// DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
+// DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
+// DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
DispatchQueryInformation;
+ DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
+ DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
return STATUS_SUCCESS;
}
Modified: trunk/reactos/drivers/parallel/parport/parport.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/p…
==============================================================================
--- trunk/reactos/drivers/parallel/parport/parport.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/parallel/parport/parport.h [iso-8859-1] Thu May 14 14:42:05
2015
@@ -8,9 +8,131 @@
#define _PARPORT_PCH_
#include <ntddk.h>
-#include <ntddser.h>
+#include <ndk/haltypes.h>
+#include <ntddpar.h>
+#include <stdio.h>
//#define NDEBUG
#include <debug.h>
+typedef enum
+{
+ dsStopped,
+ dsStarted,
+ dsPaused,
+ dsRemoved,
+ dsSurpriseRemoved
+} DEVICE_STATE;
+
+typedef struct _COMMON_DEVICE_EXTENSION
+{
+ BOOLEAN IsFDO;
+ DEVICE_STATE PnpState;
+} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
+
+typedef struct _FDO_DEVICE_EXTENSION
+{
+ COMMON_DEVICE_EXTENSION Common;
+
+ PDEVICE_OBJECT Pdo;
+ PDEVICE_OBJECT LowerDevice;
+
+ ULONG ParallelPortNumber;
+
+ ULONG LptPort;
+ ULONG OpenCount;
+
+ ULONG BaseAddress;
+ PKINTERRUPT Interrupt;
+
+} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
+
+typedef struct _PDO_DEVICE_EXTENSION
+{
+ COMMON_DEVICE_EXTENSION Common;
+
+} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
+
+
+/* fdo.c */
+
+DRIVER_ADD_DEVICE AddDevice;
+
+NTSTATUS
+NTAPI
+FdoCreate(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+FdoClose(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+FdoCleanup(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+FdoWrite(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+FdoPnp(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+FdoPower(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+
+/* misc.c */
+
+NTSTATUS
+ForwardIrpAndWait(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+DRIVER_DISPATCH ForwardIrpAndForget;
+
+PVOID
+GetUserBuffer(IN PIRP Irp);
+
+//KSERVICE_ROUTINE ParportInterruptService;
+
+
+/* pdo.c */
+
+NTSTATUS
+NTAPI
+PdoCreate(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+PdoClose(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+PdoCleanup(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+PdoWrite(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+PdoPnp(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+NTAPI
+PdoPower(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
#endif /* _PARPORT_PCH_ */
Added: trunk/reactos/drivers/parallel/parport/pdo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/p…
==============================================================================
--- trunk/reactos/drivers/parallel/parport/pdo.c (added)
+++ trunk/reactos/drivers/parallel/parport/pdo.c [iso-8859-1] Thu May 14 14:42:05 2015
@@ -0,0 +1,95 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Parallel Port Function Driver
+ * FILE: drivers/parallel/parport/pdo.c
+ * PURPOSE: PDO functions
+ */
+
+#include "parport.h"
+
+/* FUNCTIONS ****************************************************************/
+
+NTSTATUS
+NTAPI
+PdoCreate(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("PdoCreate()\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+PdoClose(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("PdoClose()\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+PdoCleanup(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("PdoCleanup()\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+PdoWrite(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("PdoWrite()\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+PdoPnp(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("PdoPnp()\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+PdoPower(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("PdoPower()\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+/* EOF */
Propchange: trunk/reactos/drivers/parallel/parport/pdo.c
------------------------------------------------------------------------------
svn:eol-style = native