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/fd... ============================================================================== --- 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/ha... ============================================================================== --- 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/mi... ============================================================================== --- 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/pa... ============================================================================== --- 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/pd... ============================================================================== --- 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;