https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f15de1555420f87aa20c2…
commit f15de1555420f87aa20c2cfaeb07a1e46846e350
Author: Dmitry Borisov <di.sean(a)protonmail.com>
AuthorDate: Thu Mar 4 18:48:43 2021 +0600
Commit: Dmitry Borisov <di.sean(a)protonmail.com>
CommitDate: Sun Jun 20 19:24:26 2021 +0600
[ISAPNP] Fixes and improvements for IRP handling
- Implement device removal.
- Finish the Read Port special handling
introduced in 21514e473f5.
- Gracefully handle low memory situations.
- Implement IRQ translator.
- Correctly stub power IRP handling.
- Remove unneeded dispatch routines; implement WMI IRP handling.
- Do not handle requests like WRITE_CONFIG.
- Add a signature member to device extensions to make checks clearer.
---
drivers/bus/isapnp/CMakeLists.txt | 1 +
drivers/bus/isapnp/fdo.c | 166 +++++++++++++++++----
drivers/bus/isapnp/interface.c | 73 ++++++++++
drivers/bus/isapnp/isapnp.c | 295 ++++++++++++++++++++++++--------------
drivers/bus/isapnp/isapnp.h | 80 +++++++++--
drivers/bus/isapnp/pdo.c | 292 +++++++++++++++++++++++++++----------
6 files changed, 682 insertions(+), 225 deletions(-)
diff --git a/drivers/bus/isapnp/CMakeLists.txt b/drivers/bus/isapnp/CMakeLists.txt
index 0d91dbf2691..6b8a6747546 100644
--- a/drivers/bus/isapnp/CMakeLists.txt
+++ b/drivers/bus/isapnp/CMakeLists.txt
@@ -4,6 +4,7 @@ list(APPEND SOURCE
pdo.c
fdo.c
hardware.c
+ interface.c
isapnp.h)
add_library(isapnp MODULE ${SOURCE} isapnp.rc)
diff --git a/drivers/bus/isapnp/fdo.c b/drivers/bus/isapnp/fdo.c
index 7b32e790246..5d61c8b2dc4 100644
--- a/drivers/bus/isapnp/fdo.c
+++ b/drivers/bus/isapnp/fdo.c
@@ -4,6 +4,7 @@
* PURPOSE: FDO-specific code
* COPYRIGHT: Copyright 2010 Cameron Gutman <cameron.gutman(a)reactos.org>
* Copyright 2020 Hervé Poussineau <hpoussin(a)reactos.org>
+ * Copyright 2021 Dmitry Borisov <di.sean(a)protonmail.com>
*/
#include "isapnp.h"
@@ -16,14 +17,22 @@ CODE_SEG("PAGE")
NTSTATUS
IsaFdoStartDevice(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
- _Inout_ PIRP Irp,
- _In_ PIO_STACK_LOCATION IrpSp)
+ _Inout_ PIRP Irp)
{
- UNREFERENCED_PARAMETER(Irp);
- UNREFERENCED_PARAMETER(IrpSp);
+ NTSTATUS Status;
PAGED_CODE();
+ if (!IoForwardIrpSynchronously(FdoExt->Ldo, Irp))
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+ Status = Irp->IoStatus.Status;
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
FdoExt->Common.State = dsStarted;
return STATUS_SUCCESS;
@@ -32,19 +41,83 @@ IsaFdoStartDevice(
static
CODE_SEG("PAGE")
NTSTATUS
-IsaFdoQueryDeviceRelations(
+IsaFdoQueryBusRelations(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
- _Inout_ PIRP Irp,
- _In_ PIO_STACK_LOCATION IrpSp)
+ _Inout_ PIRP Irp)
{
PAGED_CODE();
- if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
- return Irp->IoStatus.Status;
-
return IsaPnpFillDeviceRelations(FdoExt, Irp, TRUE);
}
+static
+CODE_SEG("PAGE")
+NTSTATUS
+IsaFdoRemoveDevice(
+ _In_ PISAPNP_FDO_EXTENSION FdoExt,
+ _Inout_ PIRP Irp)
+{
+ NTSTATUS Status;
+ PLIST_ENTRY Entry;
+
+ PAGED_CODE();
+
+ IsaPnpAcquireDeviceDataLock(FdoExt);
+
+ /* Remove our logical devices */
+ while (!IsListEmpty(&FdoExt->DeviceListHead))
+ {
+ PISAPNP_LOGICAL_DEVICE LogDevice =
CONTAINING_RECORD(RemoveHeadList(&FdoExt->
+
DeviceListHead),
+ ISAPNP_LOGICAL_DEVICE,
+ DeviceLink);
+
+ --FdoExt->DeviceCount;
+
+ if (LogDevice->Pdo)
+ {
+ IsaPnpRemoveLogicalDeviceDO(LogDevice->Pdo);
+ }
+ }
+
+ IsaPnpReleaseDeviceDataLock(FdoExt);
+
+ IsaPnpAcquireBusDataLock();
+
+ /* Remove the Read Port */
+ if (FdoExt->ReadPortPdo)
+ {
+ IsaPnpRemoveReadPortDO(FdoExt->ReadPortPdo);
+ ReadPortCreated = FALSE;
+ }
+
+ /* Find the next ISA bus, if any */
+ Entry = BusListHead.Flink;
+ if (Entry != &BusListHead)
+ {
+ PISAPNP_FDO_EXTENSION NextIsaBus = CONTAINING_RECORD(Entry,
+ ISAPNP_FDO_EXTENSION,
+ BusLink);
+
+ /* Create a new Read Port for it */
+ if (!ReadPortCreated)
+ IoInvalidateDeviceRelations(NextIsaBus->Pdo, BusRelations);
+ }
+
+ RemoveEntryList(&FdoExt->BusLink);
+
+ IsaPnpReleaseBusDataLock();
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(FdoExt->Ldo, Irp);
+
+ IoDetachDevice(FdoExt->Ldo);
+ IoDeleteDevice(FdoExt->Common.Self);
+
+ return Status;
+}
+
CODE_SEG("PAGE")
NTSTATUS
IsaFdoPnp(
@@ -52,43 +125,82 @@ IsaFdoPnp(
_Inout_ PIRP Irp,
_In_ PIO_STACK_LOCATION IrpSp)
{
- NTSTATUS Status = Irp->IoStatus.Status;
+ NTSTATUS Status;
PAGED_CODE();
+ DPRINT("%s(%p, %p) FDO %lu, Minor - %X\n",
+ __FUNCTION__,
+ FdoExt,
+ Irp,
+ FdoExt->BusNumber,
+ IrpSp->MinorFunction);
+
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:
- Status = IsaForwardIrpSynchronous(FdoExt, Irp);
-
- if (NT_SUCCESS(Status))
- Status = IsaFdoStartDevice(FdoExt, Irp, IrpSp);
+ Status = IsaFdoStartDevice(FdoExt, Irp);
Irp->IoStatus.Status = Status;
-
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
- case IRP_MN_STOP_DEVICE:
- FdoExt->Common.State = dsStopped;
+ case IRP_MN_QUERY_DEVICE_RELATIONS:
+ {
+ if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
+ break;
- Status = STATUS_SUCCESS;
- break;
+ Status = IsaFdoQueryBusRelations(FdoExt, Irp);
+ if (!NT_SUCCESS(Status))
+ {
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
- case IRP_MN_QUERY_DEVICE_RELATIONS:
- Status = IsaFdoQueryDeviceRelations(FdoExt, Irp, IrpSp);
+ return Status;
+ }
Irp->IoStatus.Status = Status;
+ break;
+ }
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
+ case IRP_MN_REMOVE_DEVICE:
+ return IsaFdoRemoveDevice(FdoExt, Irp);
- case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
- DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
+ case IRP_MN_QUERY_PNP_DEVICE_STATE:
+ Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_QUERY_INTERFACE:
+ {
+ Status = IsaFdoQueryInterface(FdoExt, IrpSp);
+ if (Status == STATUS_NOT_SUPPORTED)
+ {
+ break;
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+ }
+
+ Irp->IoStatus.Status = Status;
+ break;
+ }
+
+ case IRP_MN_SURPRISE_REMOVAL:
+ case IRP_MN_QUERY_STOP_DEVICE:
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ case IRP_MN_CANCEL_STOP_DEVICE:
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
+ case IRP_MN_STOP_DEVICE:
+ Irp->IoStatus.Status = STATUS_SUCCESS;
break;
default:
- DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
+ DPRINT("Unknown PnP code: %X\n", IrpSp->MinorFunction);
break;
}
diff --git a/drivers/bus/isapnp/interface.c b/drivers/bus/isapnp/interface.c
new file mode 100644
index 00000000000..057589bb35a
--- /dev/null
+++ b/drivers/bus/isapnp/interface.c
@@ -0,0 +1,73 @@
+/*
+ * PROJECT: ReactOS ISA PnP Bus driver
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Driver interface
+ * COPYRIGHT: Copyright 2021 Dmitry Borisov <di.sean(a)protonmail.com>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "isapnp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS ******************************************************************/
+
+CODE_SEG("PAGE")
+NTSTATUS
+IsaFdoQueryInterface(
+ _In_ PISAPNP_FDO_EXTENSION FdoExt,
+ _In_ PIO_STACK_LOCATION IrpSp)
+{
+ PAGED_CODE();
+
+ if (IsEqualGUIDAligned(IrpSp->Parameters.QueryInterface.InterfaceType,
+ &GUID_TRANSLATOR_INTERFACE_STANDARD))
+ {
+ NTSTATUS Status;
+ CM_RESOURCE_TYPE ResourceType;
+ ULONG ParentBusType, ParentBusNumber, Dummy;
+
+ ResourceType =
PtrToUlong(IrpSp->Parameters.QueryInterface.InterfaceSpecificData);
+
+ if (IrpSp->Parameters.QueryInterface.Size < sizeof(TRANSLATOR_INTERFACE)
||
+ ResourceType != CmResourceTypeInterrupt)
+ {
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ Status = IoGetDeviceProperty(FdoExt->Pdo,
+ DevicePropertyLegacyBusType,
+ sizeof(ParentBusType),
+ &ParentBusType,
+ &Dummy);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("BusType request failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ Status = IoGetDeviceProperty(FdoExt->Pdo,
+ DevicePropertyBusNumber,
+ sizeof(ParentBusNumber),
+ &ParentBusNumber,
+ &Dummy);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("BusNumber request failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ return HalGetInterruptTranslator(ParentBusType,
+ ParentBusNumber,
+ Isa,
+ IrpSp->Parameters.QueryInterface.Size,
+ IrpSp->Parameters.QueryInterface.Version,
+ (PTRANSLATOR_INTERFACE)IrpSp->
+ Parameters.QueryInterface.Interface,
+ &ParentBusNumber);
+ }
+
+ return STATUS_NOT_SUPPORTED;
+}
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index c477fecf767..148dfb6b090 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -4,15 +4,28 @@
* PURPOSE: Driver entry
* COPYRIGHT: Copyright 2010 Cameron Gutman <cameron.gutman(a)reactos.org>
* Copyright 2020 Hervé Poussineau <hpoussin(a)reactos.org>
+ * Copyright 2021 Dmitry Borisov <di.sean(a)protonmail.com>
*/
+/* INCLUDES *******************************************************************/
+
#include "isapnp.h"
#define NDEBUG
#include <debug.h>
+/* GLOBALS ********************************************************************/
+
+KEVENT BusSyncEvent;
+
+_Guarded_by_(BusSyncEvent)
BOOLEAN ReadPortCreated = FALSE;
+_Guarded_by_(BusSyncEvent)
+LIST_ENTRY BusListHead;
+
+/* FUNCTIONS ******************************************************************/
+
static
CODE_SEG("PAGE")
NTSTATUS
@@ -301,49 +314,6 @@ IsaPnpCreateLogicalDeviceResources(
return STATUS_SUCCESS;
}
-static IO_COMPLETION_ROUTINE ForwardIrpCompletion;
-
-static
-NTSTATUS
-NTAPI
-ForwardIrpCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context)
-{
- UNREFERENCED_PARAMETER(DeviceObject);
-
- if (Irp->PendingReturned)
- KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-NTSTATUS
-NTAPI
-IsaForwardIrpSynchronous(
- IN PISAPNP_FDO_EXTENSION FdoExt,
- IN PIRP Irp)
-{
- KEVENT Event;
- NTSTATUS Status;
-
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- IoCopyCurrentIrpStackLocationToNext(Irp);
-
- IoSetCompletionRoutine(Irp, ForwardIrpCompletion, &Event, TRUE, TRUE, TRUE);
-
- Status = IoCallDriver(FdoExt->Ldo, Irp);
- if (Status == STATUS_PENDING)
- {
- Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
- if (NT_SUCCESS(Status))
- Status = Irp->IoStatus.Status;
- }
-
- return Status;
-}
-
_Dispatch_type_(IRP_MJ_CREATE)
_Dispatch_type_(IRP_MJ_CLOSE)
static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaCreateClose;
@@ -359,7 +329,6 @@ IsaCreateClose(
PAGED_CODE();
Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = FILE_OPENED;
DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
@@ -368,51 +337,37 @@ IsaCreateClose(
return STATUS_SUCCESS;
}
-static DRIVER_DISPATCH IsaIoctl;
+_Dispatch_type_(IRP_MJ_DEVICE_CONTROL)
+_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
+static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaForwardOrIgnore;
static
+CODE_SEG("PAGE")
NTSTATUS
NTAPI
-IsaIoctl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+IsaForwardOrIgnore(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _Inout_ PIRP Irp)
{
- PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
- NTSTATUS Status;
+ PISAPNP_COMMON_EXTENSION CommonExt = DeviceObject->DeviceExtension;
- DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
+ PAGED_CODE();
+
+ DPRINT("%s(%p, %p) Minor - %X\n", __FUNCTION__, DeviceObject, Irp,
+ IoGetCurrentIrpStackLocation(Irp)->MinorFunction);
- switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
+ if (CommonExt->Signature == IsaPnpBus)
{
- default:
- DPRINT1("Unknown ioctl code: %x\n",
IrpSp->Parameters.DeviceIoControl.IoControlCode);
- Status = STATUS_NOT_SUPPORTED;
- break;
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(((PISAPNP_FDO_EXTENSION)CommonExt)->Ldo, Irp);
}
+ else
+ {
+ NTSTATUS Status = Irp->IoStatus.Status;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return Status;
-}
-
-static DRIVER_DISPATCH IsaReadWrite;
-
-static
-NTSTATUS
-NTAPI
-IsaReadWrite(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
-
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return STATUS_NOT_SUPPORTED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+ }
}
static
@@ -533,7 +488,7 @@ IsaPnpCreateReadPortDO(
PdoExt = FdoExt->ReadPortPdo->DeviceExtension;
RtlZeroMemory(PdoExt, sizeof(ISAPNP_PDO_EXTENSION));
- PdoExt->Common.IsFdo = FALSE;
+ PdoExt->Common.Signature = IsaPnpReadDataPort;
PdoExt->Common.Self = FdoExt->ReadPortPdo;
PdoExt->Common.State = dsStopped;
PdoExt->FdoExt = FdoExt;
@@ -551,17 +506,33 @@ IsaPnpCreateReadPortDO(
return Status;
Failure:
- if (PdoExt->RequirementsList)
- ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP);
+ IsaPnpRemoveReadPortDO(FdoExt->ReadPortPdo);
- if (PdoExt->ResourceList)
- ExFreePoolWithTag(PdoExt->ResourceList, TAG_ISAPNP);
-
- IoDeleteDevice(FdoExt->ReadPortPdo);
+ FdoExt->ReadPortPdo = NULL;
return Status;
}
+CODE_SEG("PAGE")
+VOID
+IsaPnpRemoveReadPortDO(
+ _In_ PDEVICE_OBJECT Pdo)
+{
+ PISAPNP_PDO_EXTENSION ReadPortExt = Pdo->DeviceExtension;
+
+ PAGED_CODE();
+
+ DPRINT("Removing Read Port\n");
+
+ if (ReadPortExt->RequirementsList)
+ ExFreePoolWithTag(ReadPortExt->RequirementsList, TAG_ISAPNP);
+
+ if (ReadPortExt->ResourceList)
+ ExFreePoolWithTag(ReadPortExt->ResourceList, TAG_ISAPNP);
+
+ IoDeleteDevice(Pdo);
+}
+
CODE_SEG("PAGE")
NTSTATUS
IsaPnpFillDeviceRelations(
@@ -577,6 +548,8 @@ IsaPnpFillDeviceRelations(
PAGED_CODE();
+ IsaPnpAcquireBusDataLock();
+
/* Try to claim the Read Port for our FDO */
if (!ReadPortCreated)
{
@@ -587,26 +560,68 @@ IsaPnpFillDeviceRelations(
ReadPortCreated = TRUE;
}
+ IsaPnpReleaseBusDataLock();
+
/* Inactive ISA bus */
if (!FdoExt->ReadPortPdo)
IncludeDataPort = FALSE;
+ IsaPnpAcquireDeviceDataLock(FdoExt);
+
+ /* If called from the FDO dispatch routine && Active bus */
+ if (IncludeDataPort && FdoExt->ReadPortPdo)
+ {
+ PISAPNP_PDO_EXTENSION ReadPortExt = FdoExt->ReadPortPdo->DeviceExtension;
+
+ if ((ReadPortExt->Flags & ISAPNP_READ_PORT_ALLOW_FDO_SCAN) &&
+ !(ReadPortExt->Flags & ISAPNP_SCANNED_BY_READ_PORT))
+ {
+ DPRINT("Rescan ISA PnP bus\n");
+
+ /* Run the isolation protocol */
+ if (NT_SUCCESS(IsaHwTryReadDataPort(FdoExt->ReadDataPort)))
+ {
+ /* Card identification */
+ (VOID)IsaHwFillDeviceList(FdoExt);
+ }
+ }
+
+ ReadPortExt->Flags &= ~ISAPNP_SCANNED_BY_READ_PORT;
+ }
+
PdoCount = FdoExt->DeviceCount;
if (IncludeDataPort)
++PdoCount;
+ CurrentEntry = FdoExt->DeviceListHead.Flink;
+ while (CurrentEntry != &FdoExt->DeviceListHead)
+ {
+ IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, DeviceLink);
+
+ if (!(IsaDevice->Flags & ISAPNP_PRESENT))
+ --PdoCount;
+
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
DeviceRelations = ExAllocatePoolWithTag(PagedPool,
FIELD_OFFSET(DEVICE_RELATIONS,
Objects[PdoCount]),
TAG_ISAPNP);
if (!DeviceRelations)
{
+ IsaPnpReleaseDeviceDataLock(FdoExt);
return STATUS_NO_MEMORY;
}
if (IncludeDataPort)
{
+ PISAPNP_PDO_EXTENSION ReadPortExt = FdoExt->ReadPortPdo->DeviceExtension;
+
DeviceRelations->Objects[i++] = FdoExt->ReadPortPdo;
ObReferenceObject(FdoExt->ReadPortPdo);
+
+ /* The Read Port PDO can only be removed by FDO */
+ ReadPortExt->Flags |= ISAPNP_ENUMERATED;
}
CurrentEntry = FdoExt->DeviceListHead.Flink;
@@ -616,6 +631,9 @@ IsaPnpFillDeviceRelations(
IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, DeviceLink);
+ if (!(IsaDevice->Flags & ISAPNP_PRESENT))
+ goto SkipPdo;
+
if (!IsaDevice->Pdo)
{
Status = IoCreateDevice(FdoExt->DriverObject,
@@ -626,43 +644,66 @@ IsaPnpFillDeviceRelations(
FALSE,
&IsaDevice->Pdo);
if (!NT_SUCCESS(Status))
- {
- break;
- }
+ goto SkipPdo;
IsaDevice->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
-
- //Device->Pdo->Flags |= DO_POWER_PAGABLE;
+ /* The power pagable flag is always unset */
PdoExt = IsaDevice->Pdo->DeviceExtension;
RtlZeroMemory(PdoExt, sizeof(ISAPNP_PDO_EXTENSION));
-
- PdoExt->Common.IsFdo = FALSE;
+ PdoExt->Common.Signature = IsaPnpLogicalDevice;
PdoExt->Common.Self = IsaDevice->Pdo;
PdoExt->Common.State = dsStopped;
PdoExt->IsaPnpDevice = IsaDevice;
PdoExt->FdoExt = FdoExt;
- Status = IsaPnpCreateLogicalDeviceRequirements(PdoExt);
-
- if (NT_SUCCESS(Status))
- Status = IsaPnpCreateLogicalDeviceResources(PdoExt);
-
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(IsaPnpCreateLogicalDeviceRequirements(PdoExt)) ||
+ !NT_SUCCESS(IsaPnpCreateLogicalDeviceResources(PdoExt)))
{
+ if (PdoExt->RequirementsList)
+ {
+ ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP);
+ PdoExt->RequirementsList = NULL;
+ }
+
+ if (PdoExt->ResourceList)
+ {
+ ExFreePoolWithTag(PdoExt->ResourceList, TAG_ISAPNP);
+ PdoExt->ResourceList = NULL;
+ }
+
IoDeleteDevice(IsaDevice->Pdo);
IsaDevice->Pdo = NULL;
- break;
+ goto SkipPdo;
}
}
+ else
+ {
+ PdoExt = IsaDevice->Pdo->DeviceExtension;
+ }
DeviceRelations->Objects[i++] = IsaDevice->Pdo;
-
ObReferenceObject(IsaDevice->Pdo);
+ PdoExt->Flags |= ISAPNP_ENUMERATED;
+
+ CurrentEntry = CurrentEntry->Flink;
+ continue;
+
+SkipPdo:
+ if (IsaDevice->Pdo)
+ {
+ PdoExt = IsaDevice->Pdo->DeviceExtension;
+
+ if (PdoExt)
+ PdoExt->Flags &= ~ISAPNP_ENUMERATED;
+ }
+
CurrentEntry = CurrentEntry->Flink;
}
+ IsaPnpReleaseDeviceDataLock(FdoExt);
+
DeviceRelations->Count = i;
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
@@ -694,7 +735,7 @@ IsaAddDevice(
NULL,
FILE_DEVICE_BUS_EXTENDER,
FILE_DEVICE_SECURE_OPEN,
- TRUE,
+ FALSE,
&Fdo);
if (!NT_SUCCESS(Status))
{
@@ -706,17 +747,26 @@ IsaAddDevice(
RtlZeroMemory(FdoExt, sizeof(*FdoExt));
FdoExt->Common.Self = Fdo;
- FdoExt->Common.IsFdo = TRUE;
+ FdoExt->Common.Signature = IsaPnpBus;
FdoExt->Common.State = dsStopped;
FdoExt->DriverObject = DriverObject;
FdoExt->BusNumber = BusNumber++;
FdoExt->Pdo = PhysicalDeviceObject;
FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
PhysicalDeviceObject);
+ if (!FdoExt->Ldo)
+ {
+ IoDeleteDevice(Fdo);
+ return STATUS_DEVICE_REMOVED;
+ }
InitializeListHead(&FdoExt->DeviceListHead);
KeInitializeEvent(&FdoExt->DeviceSyncEvent, SynchronizationEvent, TRUE);
+ IsaPnpAcquireBusDataLock();
+ InsertTailList(&BusListHead, &FdoExt->BusLink);
+ IsaPnpReleaseBusDataLock();
+
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
@@ -735,9 +785,22 @@ IsaPower(
PISAPNP_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension;
NTSTATUS Status;
- if (!DevExt->IsFdo)
+ if (DevExt->Signature != IsaPnpBus)
{
- Status = Irp->IoStatus.Status;
+ switch (IoGetCurrentIrpStackLocation(Irp)->MinorFunction)
+ {
+ case IRP_MN_SET_POWER:
+ case IRP_MN_QUERY_POWER:
+ Status = STATUS_SUCCESS;
+ Irp->IoStatus.Status = Status;
+ break;
+
+ default:
+ Status = Irp->IoStatus.Status;
+ break;
+ }
+
+ PoStartNextPowerIrp(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
@@ -763,9 +826,7 @@ IsaPnp(
PAGED_CODE();
- DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
-
- if (DevExt->IsFdo)
+ if (DevExt->Signature == IsaPnpBus)
return IsaFdoPnp((PISAPNP_FDO_EXTENSION)DevExt, Irp, IrpSp);
else
return IsaPdoPnp((PISAPNP_PDO_EXTENSION)DevExt, Irp, IrpSp);
@@ -782,13 +843,25 @@ DriverEntry(
DriverObject->MajorFunction[IRP_MJ_CREATE] = IsaCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IsaCreateClose;
- DriverObject->MajorFunction[IRP_MJ_READ] = IsaReadWrite;
- DriverObject->MajorFunction[IRP_MJ_WRITE] = IsaReadWrite;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaIoctl;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaForwardOrIgnore;
+ DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = IsaForwardOrIgnore;
DriverObject->MajorFunction[IRP_MJ_PNP] = IsaPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = IsaPower;
DriverObject->DriverExtension->AddDevice = IsaAddDevice;
+ /* FIXME: Fix SDK headers */
+#if 0
+ _No_competing_thread_begin_
+#endif
+
+ KeInitializeEvent(&BusSyncEvent, SynchronizationEvent, TRUE);
+ InitializeListHead(&BusListHead);
+
+ /* FIXME: Fix SDK headers */
+#if 0
+ _No_competing_thread_end_
+#endif
+
return STATUS_SUCCESS;
}
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index 4eb7fb4e19b..e476f9737b0 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -9,7 +9,7 @@
#ifndef _ISAPNP_PCH_
#define _ISAPNP_PCH_
-#include <wdm.h>
+#include <ntddk.h>
#include <ntstrsafe.h>
#include <section_attribs.h>
#include "isapnphw.h"
@@ -60,13 +60,24 @@ typedef struct _ISAPNP_LOGICAL_DEVICE
ISAPNP_DMA Dma[2];
UCHAR CSN;
UCHAR LDN;
+
+ ULONG Flags;
+#define ISAPNP_PRESENT 0x00000001 /**< @brief Cleared when the device is
physically removed. */
+
LIST_ENTRY DeviceLink;
} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
+typedef enum _ISAPNP_SIGNATURE
+{
+ IsaPnpBus = 'odFI',
+ IsaPnpLogicalDevice = 'veDI',
+ IsaPnpReadDataPort = 'pdRI'
+} ISAPNP_SIGNATURE;
+
typedef struct _ISAPNP_COMMON_EXTENSION
{
+ ISAPNP_SIGNATURE Signature;
PDEVICE_OBJECT Self;
- BOOLEAN IsFdo;
ISAPNP_DEVICE_STATE State;
} ISAPNP_COMMON_EXTENSION, *PISAPNP_COMMON_EXTENSION;
@@ -75,13 +86,19 @@ typedef struct _ISAPNP_FDO_EXTENSION
ISAPNP_COMMON_EXTENSION Common;
PDEVICE_OBJECT Ldo;
PDEVICE_OBJECT Pdo;
- PDEVICE_OBJECT ReadPortPdo;
+ PDEVICE_OBJECT ReadPortPdo; /**< @remarks The pointer is NULL for all inactive
FDOs. */
ULONG BusNumber;
KEVENT DeviceSyncEvent;
+
+ _Guarded_by_(DeviceSyncEvent)
LIST_ENTRY DeviceListHead;
+
+ _Guarded_by_(DeviceSyncEvent)
ULONG DeviceCount;
+
PDRIVER_OBJECT DriverObject;
PUCHAR ReadDataPort;
+ LIST_ENTRY BusLink;
} ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
typedef struct _ISAPNP_PDO_EXTENSION
@@ -90,10 +107,44 @@ typedef struct _ISAPNP_PDO_EXTENSION
PISAPNP_LOGICAL_DEVICE IsaPnpDevice;
PISAPNP_FDO_EXTENSION FdoExt;
PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
+
PCM_RESOURCE_LIST ResourceList;
ULONG ResourceListSize;
+
+ ULONG Flags;
+#define ISAPNP_ENUMERATED 0x00000001 /**< @brief Whether the device has
been reported to the PnP manager. */
+#define ISAPNP_SCANNED_BY_READ_PORT 0x00000002 /**< @brief The bus has been
scanned by Read Port PDO. */
+#define ISAPNP_READ_PORT_ALLOW_FDO_SCAN 0x00000004 /**< @brief Allows the active FDO
to scan the bus. */
+
+ _Write_guarded_by_(_Global_interlock_)
+ volatile LONG SpecialFiles;
} ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION;
+extern KEVENT BusSyncEvent;
+
+_Guarded_by_(BusSyncEvent)
+extern BOOLEAN ReadPortCreated;
+
+_Guarded_by_(BusSyncEvent)
+extern LIST_ENTRY BusListHead;
+
+_Requires_lock_not_held_(BusSyncEvent)
+_Acquires_lock_(BusSyncEvent)
+FORCEINLINE
+VOID
+IsaPnpAcquireBusDataLock(VOID)
+{
+ KeWaitForSingleObject(&BusSyncEvent, Executive, KernelMode, FALSE, NULL);
+}
+
+_Releases_lock_(BusSyncEvent)
+FORCEINLINE
+VOID
+IsaPnpReleaseBusDataLock(VOID)
+{
+ KeSetEvent(&BusSyncEvent, IO_NO_INCREMENT, FALSE);
+}
+
_Requires_lock_not_held_(FdoExt->DeviceSyncEvent)
_Acquires_lock_(FdoExt->DeviceSyncEvent)
FORCEINLINE
@@ -115,6 +166,11 @@ IsaPnpReleaseDeviceDataLock(
/* isapnp.c */
+CODE_SEG("PAGE")
+VOID
+IsaPnpRemoveReadPortDO(
+ _In_ PDEVICE_OBJECT Pdo);
+
CODE_SEG("PAGE")
NTSTATUS
IsaPnpFillDeviceRelations(
@@ -125,12 +181,6 @@ IsaPnpFillDeviceRelations(
CODE_SEG("INIT")
DRIVER_INITIALIZE DriverEntry;
-NTSTATUS
-NTAPI
-IsaForwardIrpSynchronous(
- _In_ PISAPNP_FDO_EXTENSION FdoExt,
- _Inout_ PIRP Irp);
-
/* fdo.c */
CODE_SEG("PAGE")
NTSTATUS
@@ -139,6 +189,13 @@ IsaFdoPnp(
_Inout_ PIRP Irp,
_In_ PIO_STACK_LOCATION IrpSp);
+/* interface.c */
+CODE_SEG("PAGE")
+NTSTATUS
+IsaFdoQueryInterface(
+ _In_ PISAPNP_FDO_EXTENSION FdoExt,
+ _In_ PIO_STACK_LOCATION IrpSp);
+
/* pdo.c */
CODE_SEG("PAGE")
NTSTATUS
@@ -147,6 +204,11 @@ IsaPdoPnp(
_Inout_ PIRP Irp,
_In_ PIO_STACK_LOCATION IrpSp);
+CODE_SEG("PAGE")
+VOID
+IsaPnpRemoveLogicalDeviceDO(
+ _In_ PDEVICE_OBJECT Pdo);
+
/* hardware.c */
CODE_SEG("PAGE")
NTSTATUS
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 1fae349f9e0..27aedff6c6f 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -4,6 +4,7 @@
* PURPOSE: PDO-specific code
* COPYRIGHT: Copyright 2010 Cameron Gutman <cameron.gutman(a)reactos.org>
* Copyright 2020 Hervé Poussineau <hpoussin(a)reactos.org>
+ * Copyright 2021 Dmitry Borisov <di.sean(a)protonmail.com>
*/
#include "isapnp.h"
@@ -24,7 +25,7 @@ IsaPdoQueryDeviceRelations(
PAGED_CODE();
if (IrpSp->Parameters.QueryDeviceRelations.Type == RemovalRelations &&
- PdoExt->Common.Self == PdoExt->FdoExt->ReadPortPdo)
+ PdoExt->Common.Signature == IsaPnpReadDataPort)
{
return IsaPnpFillDeviceRelations(PdoExt->FdoExt, Irp, FALSE);
}
@@ -70,8 +71,7 @@ IsaPdoQueryCapabilities(
DeviceCapabilities->UniqueID = TRUE;
- if (PdoExt->FdoExt->ReadPortPdo &&
- PdoExt->Common.Self == PdoExt->FdoExt->ReadPortPdo)
+ if (PdoExt->Common.Signature == IsaPnpReadDataPort)
{
DeviceCapabilities->RawDeviceOK = TRUE;
DeviceCapabilities->SilentInstall = TRUE;
@@ -89,13 +89,17 @@ CODE_SEG("PAGE")
NTSTATUS
IsaPdoQueryPnpDeviceState(
_In_ PISAPNP_PDO_EXTENSION PdoExt,
- _Inout_ PIRP Irp,
- _In_ PIO_STACK_LOCATION IrpSp)
+ _Inout_ PIRP Irp)
{
PAGED_CODE();
- Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
- return STATUS_SUCCESS;
+ if (PdoExt->SpecialFiles > 0)
+ {
+ Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
+ return STATUS_SUCCESS;
+ }
+
+ return Irp->IoStatus.Status;
}
static
@@ -319,6 +323,8 @@ IsaPdoQueryResources(
ULONG ListSize;
PCM_RESOURCE_LIST ResourceList;
+ UNREFERENCED_PARAMETER(IrpSp);
+
PAGED_CODE();
if (!PdoExt->ResourceList)
@@ -345,6 +351,8 @@ IsaPdoQueryResourceRequirements(
ULONG ListSize;
PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
+ UNREFERENCED_PARAMETER(IrpSp);
+
PAGED_CODE();
if (!PdoExt->RequirementsList)
@@ -367,6 +375,7 @@ IsaPdoStartReadPort(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
_In_ PIO_STACK_LOCATION IrpSp)
{
+ PISAPNP_PDO_EXTENSION PdoExt = FdoExt->ReadPortPdo->DeviceExtension;
PCM_RESOURCE_LIST ResourceList =
IrpSp->Parameters.StartDevice.AllocatedResources;
NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
ULONG i;
@@ -410,6 +419,9 @@ IsaPdoStartReadPort(
if (FdoExt->DeviceCount > 0)
{
+ PdoExt->Flags |= ISAPNP_READ_PORT_ALLOW_FDO_SCAN |
+ ISAPNP_SCANNED_BY_READ_PORT;
+
IoInvalidateDeviceRelations(FdoExt->Pdo, BusRelations);
IoInvalidateDeviceRelations(FdoExt->ReadPortPdo,
RemovalRelations);
}
@@ -426,61 +438,19 @@ IsaPdoStartReadPort(
}
static
+CODE_SEG("PAGE")
NTSTATUS
-NTAPI
-IsaPdoOnRepeaterComplete(
- PDEVICE_OBJECT Tdo,
- PIRP SubIrp,
- PVOID NeedsVote)
-{
- PIO_STACK_LOCATION SubStack = IoGetCurrentIrpStackLocation(SubIrp);
- PIRP Irp = (PIRP)SubStack->Parameters.Others.Argument1;
- ObDereferenceObject(Tdo);
-
- if (SubIrp->IoStatus.Status == STATUS_NOT_SUPPORTED)
- {
- if (NeedsVote)
- {
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- }
- }
- else
- {
- Irp->IoStatus = SubIrp->IoStatus;
- }
-
- IoFreeIrp(SubIrp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-NTSTATUS
-NTAPI
-IsaPdoRepeatRequest(
+IsaPdoFilterResourceRequirements(
_In_ PISAPNP_PDO_EXTENSION PdoExt,
- _In_ PIRP Irp,
- _In_ BOOLEAN NeedsVote)
+ _Inout_ PIRP Irp,
+ _In_ PIO_STACK_LOCATION IrpSp)
{
- PDEVICE_OBJECT Fdo = PdoExt->FdoExt->Common.Self;
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
- PDEVICE_OBJECT Tdo = IoGetAttachedDeviceReference(Fdo);
- PIRP SubIrp = IoAllocateIrp(Tdo->StackSize + 1, FALSE);
- PIO_STACK_LOCATION SubStack = IoGetNextIrpStackLocation(SubIrp);
-
- SubStack->DeviceObject = Tdo;
- SubStack->Parameters.Others.Argument1 = (PVOID)Irp;
-
- IoSetNextIrpStackLocation(SubIrp);
- SubStack = IoGetNextIrpStackLocation(SubIrp);
- RtlCopyMemory(SubStack, Stack, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine));
- SubStack->Control = 0;
- IoSetCompletionRoutine(SubIrp, IsaPdoOnRepeaterComplete, (PVOID)(ULONG_PTR)NeedsVote,
TRUE, TRUE, TRUE);
-
- SubIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- IoMarkIrpPending(Irp);
- IoCallDriver(Tdo, SubIrp);
-
- return STATUS_PENDING;
+ PAGED_CODE();
+
+ /* TODO: Handle */
+ UNREFERENCED_PARAMETER(PdoExt);
+ UNREFERENCED_PARAMETER(IrpSp);
+ return Irp->IoStatus.Status;
}
static
@@ -508,6 +478,124 @@ IsaPdoQueryBusInformation(
return STATUS_SUCCESS;
}
+static
+CODE_SEG("PAGE")
+NTSTATUS
+IsaPdoQueryDeviceUsageNotification(
+ _In_ PISAPNP_PDO_EXTENSION PdoExt,
+ _Inout_ PIRP Irp,
+ _In_ PIO_STACK_LOCATION IrpSp)
+{
+ BOOLEAN InPath = IrpSp->Parameters.UsageNotification.InPath;
+
+ PAGED_CODE();
+
+ switch (IrpSp->Parameters.UsageNotification.Type)
+ {
+ case DeviceUsageTypePaging:
+ case DeviceUsageTypeHibernation:
+ case DeviceUsageTypeDumpFile:
+ IoAdjustPagingPathCount(&PdoExt->SpecialFiles, InPath);
+ IoInvalidateDeviceState(PdoExt->Common.Self);
+ break;
+
+ default:
+ return Irp->IoStatus.Status;
+ }
+
+ /* Do not send it to FDO for compatibility */
+ return STATUS_SUCCESS;
+}
+
+static
+CODE_SEG("PAGE")
+NTSTATUS
+IsaPdoRemoveDevice(
+ _In_ PISAPNP_PDO_EXTENSION PdoExt,
+ _In_ BOOLEAN FinalRemove)
+{
+ PISAPNP_FDO_EXTENSION FdoExt = PdoExt->FdoExt;
+
+ PAGED_CODE();
+
+ if (FinalRemove && !(PdoExt->Flags & ISAPNP_ENUMERATED))
+ {
+ IsaPnpAcquireDeviceDataLock(FdoExt);
+
+ RemoveEntryList(&PdoExt->IsaPnpDevice->DeviceLink);
+ --FdoExt->DeviceCount;
+
+ IsaPnpReleaseDeviceDataLock(FdoExt);
+
+ IsaPnpRemoveLogicalDeviceDO(PdoExt->Common.Self);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static
+CODE_SEG("PAGE")
+NTSTATUS
+IsaReadPortRemoveDevice(
+ _In_ PISAPNP_PDO_EXTENSION PdoExt,
+ _In_ BOOLEAN FinalRemove)
+{
+ PISAPNP_FDO_EXTENSION FdoExt = PdoExt->FdoExt;
+ PLIST_ENTRY Entry;
+
+ PAGED_CODE();
+
+ IsaPnpAcquireDeviceDataLock(FdoExt);
+
+ /* Logical devices will receive a remove request afterwards */
+ for (Entry = FdoExt->DeviceListHead.Flink;
+ Entry != &FdoExt->DeviceListHead;
+ Entry = Entry->Flink)
+ {
+ PISAPNP_LOGICAL_DEVICE LogDevice = CONTAINING_RECORD(Entry,
+ ISAPNP_LOGICAL_DEVICE,
+ DeviceLink);
+
+ LogDevice->Flags &= ~ISAPNP_PRESENT;
+ }
+
+ IsaPnpReleaseDeviceDataLock(FdoExt);
+
+ PdoExt->Flags &= ~ISAPNP_READ_PORT_ALLOW_FDO_SCAN;
+ IoInvalidateDeviceRelations(FdoExt->Pdo, BusRelations);
+
+ if (FinalRemove && !(PdoExt->Flags & ISAPNP_ENUMERATED))
+ {
+ IsaPnpRemoveReadPortDO(PdoExt->Common.Self);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+CODE_SEG("PAGE")
+VOID
+IsaPnpRemoveLogicalDeviceDO(
+ _In_ PDEVICE_OBJECT Pdo)
+{
+ PISAPNP_PDO_EXTENSION PdoExt = Pdo->DeviceExtension;
+ PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
+
+ PAGED_CODE();
+ ASSERT(LogDev);
+
+ DPRINT("Removing CSN %u, LDN %u\n", LogDev->CSN, LogDev->LDN);
+
+ if (PdoExt->RequirementsList)
+ ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP);
+
+ if (PdoExt->ResourceList)
+ ExFreePoolWithTag(PdoExt->ResourceList, TAG_ISAPNP);
+
+ ExFreePoolWithTag(LogDev, TAG_ISAPNP);
+
+ IoDeleteDevice(PdoExt->Common.Self);
+}
+
CODE_SEG("PAGE")
NTSTATUS
IsaPdoPnp(
@@ -519,10 +607,29 @@ IsaPdoPnp(
PAGED_CODE();
+ if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
+ {
+ DPRINT("%s(%p, %p) CSN %u, LDN %u, Minor - %X\n",
+ __FUNCTION__,
+ PdoExt,
+ Irp,
+ PdoExt->IsaPnpDevice->CSN,
+ PdoExt->IsaPnpDevice->LDN,
+ IrpSp->MinorFunction);
+ }
+ else
+ {
+ DPRINT("%s(%p, %p) ReadPort, Minor - %X\n",
+ __FUNCTION__,
+ PdoExt,
+ Irp,
+ IrpSp->MinorFunction);
+ }
+
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:
- if (PdoExt->IsaPnpDevice)
+ if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
else
Status = IsaPdoStartReadPort(PdoExt->FdoExt, IrpSp);
@@ -532,15 +639,36 @@ IsaPdoPnp(
break;
case IRP_MN_STOP_DEVICE:
- if (PdoExt->IsaPnpDevice)
+ if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
else
+ {
+ PdoExt->Flags &= ~ISAPNP_READ_PORT_ALLOW_FDO_SCAN;
Status = STATUS_SUCCESS;
+ }
if (NT_SUCCESS(Status))
PdoExt->Common.State = dsStopped;
break;
+ case IRP_MN_QUERY_STOP_DEVICE:
+ {
+ if (PdoExt->SpecialFiles > 0)
+ Status = STATUS_DEVICE_BUSY;
+ else
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ {
+ if (PdoExt->SpecialFiles > 0)
+ Status = STATUS_DEVICE_BUSY;
+ else
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
case IRP_MN_QUERY_DEVICE_RELATIONS:
Status = IsaPdoQueryDeviceRelations(PdoExt, Irp, IrpSp);
break;
@@ -549,9 +677,22 @@ IsaPdoPnp(
Status = IsaPdoQueryCapabilities(PdoExt, Irp, IrpSp);
break;
+ case IRP_MN_SURPRISE_REMOVAL:
+ if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
+ Status = IsaPdoRemoveDevice(PdoExt, FALSE);
+ else
+ Status = IsaReadPortRemoveDevice(PdoExt, FALSE);
+ break;
+
+ case IRP_MN_REMOVE_DEVICE:
+ if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
+ Status = IsaPdoRemoveDevice(PdoExt, TRUE);
+ else
+ Status = IsaReadPortRemoveDevice(PdoExt, TRUE);
+ break;
+
case IRP_MN_QUERY_PNP_DEVICE_STATE:
- if (PdoExt->Common.Self == PdoExt->FdoExt->ReadPortPdo)
- Status = IsaPdoQueryPnpDeviceState(PdoExt, Irp, IrpSp);
+ Status = IsaPdoQueryPnpDeviceState(PdoExt, Irp);
break;
case IRP_MN_QUERY_RESOURCES:
@@ -563,36 +704,31 @@ IsaPdoPnp(
break;
case IRP_MN_QUERY_ID:
- if (PdoExt->IsaPnpDevice)
+ if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
Status = IsaPdoQueryId(PdoExt, Irp, IrpSp);
else
Status = IsaReadPortQueryId(Irp, IrpSp);
break;
+ case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
+ Status = IsaPdoFilterResourceRequirements(PdoExt, Irp, IrpSp);
+ break;
+
case IRP_MN_QUERY_BUS_INFORMATION:
Status = IsaPdoQueryBusInformation(PdoExt, Irp);
break;
- case IRP_MN_QUERY_REMOVE_DEVICE:
- case IRP_MN_REMOVE_DEVICE:
+ case IRP_MN_DEVICE_USAGE_NOTIFICATION:
+ Status = IsaPdoQueryDeviceUsageNotification(PdoExt, Irp, IrpSp);
+ break;
+
case IRP_MN_CANCEL_REMOVE_DEVICE:
- case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_CANCEL_STOP_DEVICE:
- case IRP_MN_QUERY_DEVICE_TEXT:
- case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
- case IRP_MN_SURPRISE_REMOVAL:
Status = STATUS_SUCCESS;
break;
- case IRP_MN_READ_CONFIG:
- case IRP_MN_WRITE_CONFIG:
- case IRP_MN_EJECT:
- case IRP_MN_SET_LOCK:
- case IRP_MN_DEVICE_USAGE_NOTIFICATION:
- return IsaPdoRepeatRequest(PdoExt, Irp, TRUE);
-
default:
- DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
+ DPRINT("Unknown PnP code: %X\n", IrpSp->MinorFunction);
break;
}