https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7a98d28d7f8e58fcf3ef9…
commit 7a98d28d7f8e58fcf3ef980514b79ec14b59c82b
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Thu Mar 12 11:53:09 2020 +0100
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Sat Mar 14 23:39:01 2020 +0100
[ISAPNP] Rewrite device reporting method
IoCreateDevice() was called too early, when a spinlock was acquired.
Create ISAPNP_LOGICAL_DEVICE structure when a device is detected, and call
IoCreateDevice() later, when required.
---
drivers/bus/isapnp/fdo.c | 47 ++++++++++++++++++++++++++++++++-----------
drivers/bus/isapnp/hardware.c | 26 ++++--------------------
drivers/bus/isapnp/isapnp.c | 3 ++-
drivers/bus/isapnp/isapnp.h | 28 ++++++++++++++++----------
drivers/bus/isapnp/pdo.c | 28 ++++++++++++++------------
5 files changed, 73 insertions(+), 59 deletions(-)
diff --git a/drivers/bus/isapnp/fdo.c b/drivers/bus/isapnp/fdo.c
index c0a5eb9eb91..1529267b1c4 100644
--- a/drivers/bus/isapnp/fdo.c
+++ b/drivers/bus/isapnp/fdo.c
@@ -24,18 +24,16 @@ IsaFdoStartDevice(
UNREFERENCED_PARAMETER(IrpSp);
KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
-
Status = IsaHwDetectReadDataPort(FdoExt);
+ KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+
if (!NT_SUCCESS(Status))
{
- KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
return Status;
}
FdoExt->Common.State = dsStarted;
- KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
-
return STATUS_SUCCESS;
}
@@ -46,6 +44,7 @@ IsaFdoQueryDeviceRelations(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
+ PISAPNP_PDO_EXTENSION PdoExt;
NTSTATUS Status;
PLIST_ENTRY CurrentEntry;
PISAPNP_LOGICAL_DEVICE IsaDevice;
@@ -57,11 +56,11 @@ IsaFdoQueryDeviceRelations(
return Irp->IoStatus.Status;
KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
-
Status = IsaHwFillDeviceList(FdoExt);
+ KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+
if (!NT_SUCCESS(Status))
{
- KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
return Status;
}
@@ -69,8 +68,7 @@ IsaFdoQueryDeviceRelations(
sizeof(DEVICE_RELATIONS) + sizeof(DEVICE_OBJECT) *
(FdoExt->DeviceCount - 1));
if (!DeviceRelations)
{
- KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
- return STATUS_INSUFFICIENT_RESOURCES;
+ return STATUS_NO_MEMORY;
}
CurrentEntry = FdoExt->DeviceListHead.Flink;
@@ -78,17 +76,42 @@ IsaFdoQueryDeviceRelations(
{
IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, ListEntry);
- DeviceRelations->Objects[i++] = IsaDevice->Common.Self;
+ if (!IsaDevice->Pdo)
+ {
+ Status = IoCreateDevice(FdoExt->DriverObject,
+ sizeof(ISAPNP_PDO_EXTENSION),
+ NULL,
+ FILE_DEVICE_CONTROLLER,
+ FILE_DEVICE_SECURE_OPEN |
FILE_AUTOGENERATED_DEVICE_NAME,
+ FALSE,
+ &IsaDevice->Pdo);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
- ObReferenceObject(IsaDevice->Common.Self);
+ IsaDevice->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ //Device->Pdo->Flags |= DO_POWER_PAGABLE;
+
+ PdoExt = (PISAPNP_PDO_EXTENSION)IsaDevice->Pdo->DeviceExtension;
+
+ RtlZeroMemory(PdoExt, sizeof(ISAPNP_PDO_EXTENSION));
+
+ PdoExt->Common.IsFdo = FALSE;
+ PdoExt->Common.Self = IsaDevice->Pdo;
+ PdoExt->Common.State = dsStopped;
+ PdoExt->IsaPnpDevice = IsaDevice;
+ }
+ DeviceRelations->Objects[i++] = IsaDevice->Pdo;
+
+ ObReferenceObject(IsaDevice->Pdo);
CurrentEntry = CurrentEntry->Flink;
}
DeviceRelations->Count = FdoExt->DeviceCount;
- KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
-
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
return STATUS_SUCCESS;
diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
index acabdd2d04c..df3d8e398a7 100644
--- a/drivers/bus/isapnp/hardware.c
+++ b/drivers/bus/isapnp/hardware.c
@@ -463,8 +463,6 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
ISAPNP_LOGDEVID LogDevId;
USHORT Csn;
USHORT LogDev;
- PDEVICE_OBJECT Pdo;
- NTSTATUS Status;
ASSERT(FdoExt->ReadDataPort);
@@ -472,26 +470,12 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
{
for (LogDev = 0; LogDev <= 0xFF; LogDev++)
{
- Status = IoCreateDevice(FdoExt->Common.Self->DriverObject,
- sizeof(ISAPNP_LOGICAL_DEVICE),
- NULL,
- FILE_DEVICE_CONTROLLER,
- FILE_DEVICE_SECURE_OPEN,
- FALSE,
- &Pdo);
- if (!NT_SUCCESS(Status))
- return Status;
-
- Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-
- LogDevice = Pdo->DeviceExtension;
+ LogDevice = ExAllocatePool(NonPagedPool, sizeof(ISAPNP_LOGICAL_DEVICE));
+ if (!LogDevice)
+ return STATUS_NO_MEMORY;
RtlZeroMemory(LogDevice, sizeof(ISAPNP_LOGICAL_DEVICE));
- LogDevice->Common.Self = Pdo;
- LogDevice->Common.IsFdo = FALSE;
- LogDevice->Common.State = dsStopped;
-
LogDevice->CSN = Csn;
LogDevice->LDN = LogDev;
@@ -503,7 +487,7 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
if (Identifier.VendorId & 0x80)
{
- IoDeleteDevice(LogDevice->Common.Self);
+ ExFreePool(LogDevice);
return STATUS_SUCCESS;
}
@@ -525,8 +509,6 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
WaitForKey();
- Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
-
InsertTailList(&FdoExt->DeviceListHead, &LogDevice->ListEntry);
FdoExt->DeviceCount++;
}
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index ae94622b66b..eebe03c29aa 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -152,6 +152,7 @@ IsaAddDevice(
FdoExt->Common.Self = Fdo;
FdoExt->Common.IsFdo = TRUE;
FdoExt->Common.State = dsStopped;
+ FdoExt->DriverObject = DriverObject;
FdoExt->Pdo = PhysicalDeviceObject;
FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
PhysicalDeviceObject);
@@ -186,7 +187,7 @@ IsaPnp(
}
else
{
- return IsaPdoPnp((PISAPNP_LOGICAL_DEVICE)DevExt,
+ return IsaPdoPnp((PISAPNP_PDO_EXTENSION)DevExt,
Irp,
IrpSp);
}
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index 538e33b9063..c941712f77a 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -15,6 +15,18 @@ typedef enum {
dsStarted
} ISAPNP_DEVICE_STATE;
+typedef struct _ISAPNP_LOGICAL_DEVICE {
+ PDEVICE_OBJECT Pdo;
+ UCHAR VendorId[3];
+ USHORT ProdId;
+ ULONG SerialNumber;
+ USHORT IoAddr;
+ UCHAR IrqNo;
+ UCHAR CSN;
+ UCHAR LDN;
+ LIST_ENTRY ListEntry;
+} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
+
typedef struct _ISAPNP_COMMON_EXTENSION {
PDEVICE_OBJECT Self;
BOOLEAN IsFdo;
@@ -27,21 +39,15 @@ typedef struct _ISAPNP_FDO_EXTENSION {
PDEVICE_OBJECT Pdo;
LIST_ENTRY DeviceListHead;
ULONG DeviceCount;
+ PDRIVER_OBJECT DriverObject;
PUCHAR ReadDataPort;
KSPIN_LOCK Lock;
} ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
-typedef struct _ISAPNP_LOGICAL_DEVICE {
+typedef struct _ISAPNP_PDO_EXTENSION {
ISAPNP_COMMON_EXTENSION Common;
- UCHAR VendorId[3];
- USHORT ProdId;
- ULONG SerialNumber;
- USHORT IoAddr;
- UCHAR IrqNo;
- UCHAR CSN;
- UCHAR LDN;
- LIST_ENTRY ListEntry;
-} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
+ PISAPNP_LOGICAL_DEVICE IsaPnpDevice;
+} ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION;
/* isapnp.c */
@@ -71,7 +77,7 @@ IsaFdoPnp(
NTSTATUS
NTAPI
IsaPdoPnp(
- IN PISAPNP_LOGICAL_DEVICE LogDev,
+ IN PISAPNP_PDO_EXTENSION PdoDeviceExtension,
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp);
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 450462f39d6..6e06af29241 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -13,7 +13,7 @@
NTSTATUS
NTAPI
IsaPdoQueryDeviceRelations(
- IN PISAPNP_LOGICAL_DEVICE LogDev,
+ IN PISAPNP_PDO_EXTENSION PdoExt,
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
@@ -27,8 +27,8 @@ IsaPdoQueryDeviceRelations(
return STATUS_INSUFFICIENT_RESOURCES;
DeviceRelations->Count = 1;
- DeviceRelations->Objects[0] = LogDev->Common.Self;
- ObReferenceObject(LogDev->Common.Self);
+ DeviceRelations->Objects[0] = PdoExt->Common.Self;
+ ObReferenceObject(PdoExt->Common.Self);
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
@@ -38,11 +38,12 @@ IsaPdoQueryDeviceRelations(
NTSTATUS
NTAPI
IsaPdoQueryCapabilities(
- IN PISAPNP_LOGICAL_DEVICE LogDev,
+ IN PISAPNP_PDO_EXTENSION PdoExt,
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
PDEVICE_CAPABILITIES DeviceCapabilities;
+ PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
if (DeviceCapabilities->Version != 1)
@@ -57,10 +58,11 @@ IsaPdoQueryCapabilities(
NTSTATUS
NTAPI
IsaPdoQueryId(
- IN PISAPNP_LOGICAL_DEVICE LogDev,
+ IN PISAPNP_PDO_EXTENSION PdoExt,
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
+ PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
WCHAR Temp[256];
PWCHAR Buffer, End;
ULONG Length;
@@ -140,7 +142,7 @@ IsaPdoQueryId(
NTSTATUS
NTAPI
IsaPdoPnp(
- IN PISAPNP_LOGICAL_DEVICE LogDev,
+ IN PISAPNP_PDO_EXTENSION PdoExt,
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
@@ -149,25 +151,25 @@ IsaPdoPnp(
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:
- Status = IsaHwActivateDevice(LogDev);
+ Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
if (NT_SUCCESS(Status))
- LogDev->Common.State = dsStarted;
+ PdoExt->Common.State = dsStarted;
break;
case IRP_MN_STOP_DEVICE:
- Status = IsaHwDeactivateDevice(LogDev);
+ Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
if (NT_SUCCESS(Status))
- LogDev->Common.State = dsStopped;
+ PdoExt->Common.State = dsStopped;
break;
case IRP_MN_QUERY_DEVICE_RELATIONS:
- Status = IsaPdoQueryDeviceRelations(LogDev, Irp, IrpSp);
+ Status = IsaPdoQueryDeviceRelations(PdoExt, Irp, IrpSp);
break;
case IRP_MN_QUERY_CAPABILITIES:
- Status = IsaPdoQueryCapabilities(LogDev, Irp, IrpSp);
+ Status = IsaPdoQueryCapabilities(PdoExt, Irp, IrpSp);
break;
case IRP_MN_QUERY_RESOURCES:
@@ -179,7 +181,7 @@ IsaPdoPnp(
break;
case IRP_MN_QUERY_ID:
- Status = IsaPdoQueryId(LogDev, Irp, IrpSp);
+ Status = IsaPdoQueryId(PdoExt, Irp, IrpSp);
break;
default: