Author: ekohl
Date: Wed May 27 20:18:10 2015
New Revision: 67936

URL: http://svn.reactos.org/svn/reactos?rev=67936&view=rev
Log:
[PARPORT]
- Add FdoQueryBusRelations to enumerate the 'attached' raw port.
- Create the PDO for the raw port (\Device\ParallelX) and let the symbolic link 
(\DosDevices\LPTX) point to it.
- Move the open, close and write code from the FDO to the PDO.

Added:
    trunk/reactos/drivers/parallel/parport/hardware.h   (with props)
Modified:
    trunk/reactos/drivers/parallel/parport/fdo.c
    trunk/reactos/drivers/parallel/parport/misc.c
    trunk/reactos/drivers/parallel/parport/parport.h
    trunk/reactos/drivers/parallel/parport/pdo.c

Modified: trunk/reactos/drivers/parallel/parport/fdo.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/fdo.c?rev=67936&r1=67935&r2=67936&view=diff
==============================================================================
--- trunk/reactos/drivers/parallel/parport/fdo.c        [iso-8859-1] (original)
+++ trunk/reactos/drivers/parallel/parport/fdo.c        [iso-8859-1] Wed May 27 
20:18:10 2015
@@ -6,37 +6,6 @@
  */
 
 #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 ****************************************************************/
 
@@ -86,11 +55,7 @@
     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->PortNumber = 
IoGetConfigurationInformation()->ParallelCount++;
     DeviceExtension->Pdo = Pdo;
 
     Status = IoAttachDeviceToDeviceStackSafe(Fdo,
@@ -141,127 +106,185 @@
                IN PCM_RESOURCE_LIST ResourceListTranslated)
 {
     PFDO_DEVICE_EXTENSION DeviceExtension;
+    ULONG i;
+//    ULONG Vector = 0;
+//    KIRQL Dirql = 0;
+//    KAFFINITY Affinity = 0;
+//    KINTERRUPT_MODE InterruptMode = Latched;
+//    BOOLEAN ShareInterrupt = TRUE;
+
+    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
+
+    DeviceExtension->Common.PnpState = dsStarted;
+
+
+    /* We don't really care if the call succeeded or not... */
+
+    return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
+FdoCreateRawParallelPdo(
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension = NULL;
+    PDEVICE_OBJECT Pdo = NULL;
     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);
+    DPRINT("FdoCreateRawParallelPdo()\n");
+
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    /* Create new device object */
+    swprintf(DeviceNameBuffer,
+             L"\\Device\\Parallel%lu",
+             FdoDeviceExtension->PortNumber);
+    RtlInitUnicodeString(&DeviceName,
+                         DeviceNameBuffer);
+
+    Status = IoCreateDevice(DeviceObject->DriverObject,
+                            sizeof(PDO_DEVICE_EXTENSION),
+                            &DeviceName,
+                            FILE_DEVICE_CONTROLLER,
+                            0,
+                            FALSE,
+                            &Pdo);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("IoCreateDevice() failed with status 0x%08x\n", Status);
+        goto done;
+    }
+
+    Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
+    Pdo->Flags |= DO_POWER_PAGABLE;
+
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
+    RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
+
+    PdoDeviceExtension->Common.IsFDO = FALSE;
+    PdoDeviceExtension->Common.PnpState = dsStopped;
+
+    Pdo->StackSize = DeviceObject->StackSize + 1;
+
+    FdoDeviceExtension->AttachedRawPdo = Pdo;
+    PdoDeviceExtension->AttachedFdo = DeviceObject;
+
+    PdoDeviceExtension->PortNumber = FdoDeviceExtension->PortNumber;
+    PdoDeviceExtension->LptPort = PdoDeviceExtension->PortNumber + 1;
+
+
+    /* Create link \DosDevices\LPTX -> \Device\ParallelY */
+    swprintf(LinkNameBuffer, L"\\DosDevices\\LPT%lu", 
PdoDeviceExtension->LptPort);
     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;
-    }
-
+        goto done;
+    }
+
+    swprintf(LptPortBuffer, L"LPT%lu", PdoDeviceExtension->LptPort);
+    RtlInitUnicodeString(&LptPort, LptPortBuffer);
 
     /* Write an entry value under HKLM\HARDWARE\DeviceMap\PARALLEL PORTS. */
     /* This step is not mandatory, so do not exit in case of error. */
@@ -292,10 +315,66 @@
         ZwClose(KeyHandle);
     }
 
-    DeviceExtension->Common.PnpState = dsStarted;
-
-
-    /* We don't really care if the call succeeded or not... */
+    Pdo->Flags |= DO_BUFFERED_IO;
+    Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        if (Pdo)
+        {
+            ASSERT(PdoDeviceExtension);
+            IoDeleteDevice(Pdo);
+        }
+    }
+
+    return Status;
+}
+
+
+static
+NTSTATUS
+FdoQueryBusRelations(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp,
+    PIO_STACK_LOCATION IrpSp)
+{
+    PFDO_DEVICE_EXTENSION DeviceExtension;
+    PDEVICE_RELATIONS DeviceRelations;
+    ULONG Size;
+    ULONG i;
+    ULONG PdoCount = 0;
+    NTSTATUS Status;
+
+    UNREFERENCED_PARAMETER(IrpSp);
+
+    DPRINT("FdoQueryBusRelations()\n");
+
+    DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(DeviceExtension->Common.IsFDO);
+
+    /* TODO: Enumerate parallel devices and create their PDOs */
+
+    Status = FdoCreateRawParallelPdo(DeviceObject);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    PdoCount++;
+
+    /* Allocate a buffer for the device relations */
+    Size = sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (PdoCount - 1);
+    DeviceRelations = ExAllocatePoolWithTag(PagedPool, Size, PARPORT_TAG);
+    if (DeviceRelations == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* Fill the buffer */
+    i = 0;
+    ObReferenceObject(DeviceExtension->AttachedRawPdo);
+    DeviceRelations->Objects[i] = DeviceExtension->AttachedRawPdo;
+
+    Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
+
+    DPRINT("Done\n");
 
     return STATUS_SUCCESS;
 }
@@ -345,7 +424,7 @@
         goto done;
     }
 
-    DPRINT("Open LPT%lu: successful\n", DeviceExtension->LptPort);
+    DPRINT("Open parallel port %lu: successful\n", 
DeviceExtension->PortNumber);
     DeviceExtension->OpenCount++;
 
 done:
@@ -397,68 +476,11 @@
 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;
 }
 
@@ -524,26 +546,29 @@
             switch (Stack->Parameters.QueryDeviceRelations.Type)
             {
                 case BusRelations:
-                    DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / 
BusRelations\n");
+                    DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / 
BusRelations\n");
+                    Status = FdoQueryBusRelations(DeviceObject, Irp, Stack);
+                    Irp->IoStatus.Status = Status;
+                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                    return Status;
+
+                case RemovalRelations:
+                    DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / 
RemovalRelations\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",
+                    DPRINT("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");
+            DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
             return ForwardIrpAndForget(DeviceObject, Irp);
 
         default:
-            DPRINT1("Unknown minor function 0x%x\n", MinorFunction);
+            DPRINT("Unknown minor function 0x%x\n", MinorFunction);
             return ForwardIrpAndForget(DeviceObject, Irp);
     }
 

Added: trunk/reactos/drivers/parallel/parport/hardware.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/hardware.h?rev=67936
==============================================================================
--- trunk/reactos/drivers/parallel/parport/hardware.h   (added)
+++ trunk/reactos/drivers/parallel/parport/hardware.h   [iso-8859-1] Wed May 27 
20:18:10 2015
@@ -0,0 +1,41 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         Parallel Port Function Driver
+ * FILE:            drivers/parallel/parport/hardware.h
+ * PURPOSE:         Hardware definitions
+ */
+
+#ifndef _HARDWARE_H_
+#define _HARDWARE_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 */
+
+#endif /* _HARDWARE_H_ */

Propchange: trunk/reactos/drivers/parallel/parport/hardware.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/drivers/parallel/parport/misc.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/misc.c?rev=67936&r1=67935&r2=67936&view=diff
==============================================================================
--- trunk/reactos/drivers/parallel/parport/misc.c       [iso-8859-1] (original)
+++ trunk/reactos/drivers/parallel/parport/misc.c       [iso-8859-1] Wed May 27 
20:18:10 2015
@@ -61,7 +61,10 @@
 {
     PDEVICE_OBJECT LowerDevice;
 
-    LowerDevice = 
((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+    if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+        LowerDevice = 
((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+    else
+        LowerDevice = 
((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedFdo;
     ASSERT(LowerDevice);
 
     IoSkipCurrentIrpStackLocation(Irp);

Modified: trunk/reactos/drivers/parallel/parport/parport.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/parport.h?rev=67936&r1=67935&r2=67936&view=diff
==============================================================================
--- trunk/reactos/drivers/parallel/parport/parport.h    [iso-8859-1] (original)
+++ trunk/reactos/drivers/parallel/parport/parport.h    [iso-8859-1] Wed May 27 
20:18:10 2015
@@ -1,6 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         Parallel Port Function Driver
+ * FILE:            drivers/parallel/parport/parport.h
  * PURPOSE:         Parport driver header
  */
 
@@ -11,6 +12,8 @@
 #include <ndk/haltypes.h>
 #include <ntddpar.h>
 #include <stdio.h>
+
+#include "hardware.h"
 
 //#define NDEBUG
 #include <debug.h>
@@ -37,9 +40,11 @@
     PDEVICE_OBJECT Pdo;
     PDEVICE_OBJECT LowerDevice;
 
-    ULONG ParallelPortNumber;
+    PDEVICE_OBJECT AttachedRawPdo;
+    PDEVICE_OBJECT AttachedPdo[2];
 
-    ULONG LptPort;
+    ULONG PortNumber;
+
     ULONG OpenCount;
 
     ULONG BaseAddress;
@@ -51,8 +56,16 @@
 {
     COMMON_DEVICE_EXTENSION Common;
 
+    PDEVICE_OBJECT AttachedFdo;
+
+    ULONG PortNumber;
+    ULONG LptPort;
+
+    ULONG OpenCount;
+
 } PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
 
+#define PARPORT_TAG 'trpP'
 
 /* fdo.c */
 

Modified: trunk/reactos/drivers/parallel/parport/pdo.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/pdo.c?rev=67936&r1=67935&r2=67936&view=diff
==============================================================================
--- trunk/reactos/drivers/parallel/parport/pdo.c        [iso-8859-1] (original)
+++ trunk/reactos/drivers/parallel/parport/pdo.c        [iso-8859-1] Wed May 27 
20:18:10 2015
@@ -14,12 +14,31 @@
 PdoCreate(IN PDEVICE_OBJECT DeviceObject,
           IN PIRP Irp)
 {
+    PPDO_DEVICE_EXTENSION DeviceExtension;
+    PIO_STACK_LOCATION Stack;
+    NTSTATUS Status = STATUS_SUCCESS;
+
     DPRINT("PdoCreate()\n");
 
+    Stack = IoGetCurrentIrpStackLocation(Irp);
+    DeviceExtension = (PPDO_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;
-    Irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return STATUS_SUCCESS;
+
+    return Status;
 }
 
 
@@ -28,11 +47,17 @@
 PdoClose(IN PDEVICE_OBJECT DeviceObject,
          IN PIRP Irp)
 {
+    PPDO_DEVICE_EXTENSION pDeviceExtension;
+
     DPRINT("PdoClose()\n");
+
+    pDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    pDeviceExtension->OpenCount--;
 
     Irp->IoStatus.Information = 0;
     Irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
     return STATUS_SUCCESS;
 }
 
@@ -56,7 +81,66 @@
 PdoWrite(IN PDEVICE_OBJECT DeviceObject,
          IN PIRP Irp)
 {
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    PIO_STACK_LOCATION IoStack;
+    PUCHAR Buffer;
+    ULONG i;
+    UCHAR PortStatus;
+    ULONG ulCount;
+
     DPRINT("PdoWrite()\n");
+
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    FdoDeviceExtension = 
(PFDO_DEVICE_EXTENSION)PdoDeviceExtension->AttachedFdo->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)(FdoDeviceExtension->BaseAddress + 1));
+            ulCount++;
+        }
+        while (ulCount < 500000 && !(PortStatus & LP_PBUSY));
+
+        if (ulCount == 500000)
+        {
+            DPRINT("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)FdoDeviceExtension->BaseAddress, Buffer[i]);
+
+        KeStallExecutionProcessor(10);
+
+        WRITE_PORT_UCHAR((PUCHAR)(FdoDeviceExtension->BaseAddress + 2), 
(LP_PSELECP | LP_PINITP | LP_PSTROBE));
+
+        KeStallExecutionProcessor(10);
+
+        WRITE_PORT_UCHAR((PUCHAR)(FdoDeviceExtension->BaseAddress + 2), 
(LP_PSELECP | LP_PINITP));
+    }
 
     Irp->IoStatus.Information = 0;
     Irp->IoStatus.Status = STATUS_SUCCESS;


Reply via email to