mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[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.
This commit is contained in:
parent
58e8be6258
commit
7a98d28d7f
5 changed files with 73 additions and 59 deletions
|
@ -24,18 +24,16 @@ IsaFdoStartDevice(
|
||||||
UNREFERENCED_PARAMETER(IrpSp);
|
UNREFERENCED_PARAMETER(IrpSp);
|
||||||
|
|
||||||
KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
|
KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
|
||||||
|
|
||||||
Status = IsaHwDetectReadDataPort(FdoExt);
|
Status = IsaHwDetectReadDataPort(FdoExt);
|
||||||
|
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
FdoExt->Common.State = dsStarted;
|
FdoExt->Common.State = dsStarted;
|
||||||
|
|
||||||
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +44,7 @@ IsaFdoQueryDeviceRelations(
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PIO_STACK_LOCATION IrpSp)
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
PISAPNP_PDO_EXTENSION PdoExt;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PISAPNP_LOGICAL_DEVICE IsaDevice;
|
PISAPNP_LOGICAL_DEVICE IsaDevice;
|
||||||
|
@ -57,11 +56,11 @@ IsaFdoQueryDeviceRelations(
|
||||||
return Irp->IoStatus.Status;
|
return Irp->IoStatus.Status;
|
||||||
|
|
||||||
KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
|
KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
|
||||||
|
|
||||||
Status = IsaHwFillDeviceList(FdoExt);
|
Status = IsaHwFillDeviceList(FdoExt);
|
||||||
|
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,8 +68,7 @@ IsaFdoQueryDeviceRelations(
|
||||||
sizeof(DEVICE_RELATIONS) + sizeof(DEVICE_OBJECT) * (FdoExt->DeviceCount - 1));
|
sizeof(DEVICE_RELATIONS) + sizeof(DEVICE_OBJECT) * (FdoExt->DeviceCount - 1));
|
||||||
if (!DeviceRelations)
|
if (!DeviceRelations)
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
return STATUS_NO_MEMORY;
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentEntry = FdoExt->DeviceListHead.Flink;
|
CurrentEntry = FdoExt->DeviceListHead.Flink;
|
||||||
|
@ -78,17 +76,42 @@ IsaFdoQueryDeviceRelations(
|
||||||
{
|
{
|
||||||
IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, ListEntry);
|
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;
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceRelations->Count = FdoExt->DeviceCount;
|
DeviceRelations->Count = FdoExt->DeviceCount;
|
||||||
|
|
||||||
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -463,8 +463,6 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
|
||||||
ISAPNP_LOGDEVID LogDevId;
|
ISAPNP_LOGDEVID LogDevId;
|
||||||
USHORT Csn;
|
USHORT Csn;
|
||||||
USHORT LogDev;
|
USHORT LogDev;
|
||||||
PDEVICE_OBJECT Pdo;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
ASSERT(FdoExt->ReadDataPort);
|
ASSERT(FdoExt->ReadDataPort);
|
||||||
|
|
||||||
|
@ -472,26 +470,12 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
|
||||||
{
|
{
|
||||||
for (LogDev = 0; LogDev <= 0xFF; LogDev++)
|
for (LogDev = 0; LogDev <= 0xFF; LogDev++)
|
||||||
{
|
{
|
||||||
Status = IoCreateDevice(FdoExt->Common.Self->DriverObject,
|
LogDevice = ExAllocatePool(NonPagedPool, sizeof(ISAPNP_LOGICAL_DEVICE));
|
||||||
sizeof(ISAPNP_LOGICAL_DEVICE),
|
if (!LogDevice)
|
||||||
NULL,
|
return STATUS_NO_MEMORY;
|
||||||
FILE_DEVICE_CONTROLLER,
|
|
||||||
FILE_DEVICE_SECURE_OPEN,
|
|
||||||
FALSE,
|
|
||||||
&Pdo);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
|
||||||
|
|
||||||
LogDevice = Pdo->DeviceExtension;
|
|
||||||
|
|
||||||
RtlZeroMemory(LogDevice, sizeof(ISAPNP_LOGICAL_DEVICE));
|
RtlZeroMemory(LogDevice, sizeof(ISAPNP_LOGICAL_DEVICE));
|
||||||
|
|
||||||
LogDevice->Common.Self = Pdo;
|
|
||||||
LogDevice->Common.IsFdo = FALSE;
|
|
||||||
LogDevice->Common.State = dsStopped;
|
|
||||||
|
|
||||||
LogDevice->CSN = Csn;
|
LogDevice->CSN = Csn;
|
||||||
LogDevice->LDN = LogDev;
|
LogDevice->LDN = LogDev;
|
||||||
|
|
||||||
|
@ -503,7 +487,7 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
|
||||||
|
|
||||||
if (Identifier.VendorId & 0x80)
|
if (Identifier.VendorId & 0x80)
|
||||||
{
|
{
|
||||||
IoDeleteDevice(LogDevice->Common.Self);
|
ExFreePool(LogDevice);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,8 +509,6 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
|
||||||
|
|
||||||
WaitForKey();
|
WaitForKey();
|
||||||
|
|
||||||
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
|
||||||
|
|
||||||
InsertTailList(&FdoExt->DeviceListHead, &LogDevice->ListEntry);
|
InsertTailList(&FdoExt->DeviceListHead, &LogDevice->ListEntry);
|
||||||
FdoExt->DeviceCount++;
|
FdoExt->DeviceCount++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,7 @@ IsaAddDevice(
|
||||||
FdoExt->Common.Self = Fdo;
|
FdoExt->Common.Self = Fdo;
|
||||||
FdoExt->Common.IsFdo = TRUE;
|
FdoExt->Common.IsFdo = TRUE;
|
||||||
FdoExt->Common.State = dsStopped;
|
FdoExt->Common.State = dsStopped;
|
||||||
|
FdoExt->DriverObject = DriverObject;
|
||||||
FdoExt->Pdo = PhysicalDeviceObject;
|
FdoExt->Pdo = PhysicalDeviceObject;
|
||||||
FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
|
FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
|
||||||
PhysicalDeviceObject);
|
PhysicalDeviceObject);
|
||||||
|
@ -186,7 +187,7 @@ IsaPnp(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return IsaPdoPnp((PISAPNP_LOGICAL_DEVICE)DevExt,
|
return IsaPdoPnp((PISAPNP_PDO_EXTENSION)DevExt,
|
||||||
Irp,
|
Irp,
|
||||||
IrpSp);
|
IrpSp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,18 @@ typedef enum {
|
||||||
dsStarted
|
dsStarted
|
||||||
} ISAPNP_DEVICE_STATE;
|
} 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 {
|
typedef struct _ISAPNP_COMMON_EXTENSION {
|
||||||
PDEVICE_OBJECT Self;
|
PDEVICE_OBJECT Self;
|
||||||
BOOLEAN IsFdo;
|
BOOLEAN IsFdo;
|
||||||
|
@ -27,21 +39,15 @@ typedef struct _ISAPNP_FDO_EXTENSION {
|
||||||
PDEVICE_OBJECT Pdo;
|
PDEVICE_OBJECT Pdo;
|
||||||
LIST_ENTRY DeviceListHead;
|
LIST_ENTRY DeviceListHead;
|
||||||
ULONG DeviceCount;
|
ULONG DeviceCount;
|
||||||
|
PDRIVER_OBJECT DriverObject;
|
||||||
PUCHAR ReadDataPort;
|
PUCHAR ReadDataPort;
|
||||||
KSPIN_LOCK Lock;
|
KSPIN_LOCK Lock;
|
||||||
} ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
|
} ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
|
||||||
|
|
||||||
typedef struct _ISAPNP_LOGICAL_DEVICE {
|
typedef struct _ISAPNP_PDO_EXTENSION {
|
||||||
ISAPNP_COMMON_EXTENSION Common;
|
ISAPNP_COMMON_EXTENSION Common;
|
||||||
UCHAR VendorId[3];
|
PISAPNP_LOGICAL_DEVICE IsaPnpDevice;
|
||||||
USHORT ProdId;
|
} ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION;
|
||||||
ULONG SerialNumber;
|
|
||||||
USHORT IoAddr;
|
|
||||||
UCHAR IrqNo;
|
|
||||||
UCHAR CSN;
|
|
||||||
UCHAR LDN;
|
|
||||||
LIST_ENTRY ListEntry;
|
|
||||||
} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
|
|
||||||
|
|
||||||
/* isapnp.c */
|
/* isapnp.c */
|
||||||
|
|
||||||
|
@ -71,7 +77,7 @@ IsaFdoPnp(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IsaPdoPnp(
|
IsaPdoPnp(
|
||||||
IN PISAPNP_LOGICAL_DEVICE LogDev,
|
IN PISAPNP_PDO_EXTENSION PdoDeviceExtension,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PIO_STACK_LOCATION IrpSp);
|
IN PIO_STACK_LOCATION IrpSp);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IsaPdoQueryDeviceRelations(
|
IsaPdoQueryDeviceRelations(
|
||||||
IN PISAPNP_LOGICAL_DEVICE LogDev,
|
IN PISAPNP_PDO_EXTENSION PdoExt,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PIO_STACK_LOCATION IrpSp)
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
@ -27,8 +27,8 @@ IsaPdoQueryDeviceRelations(
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
DeviceRelations->Count = 1;
|
DeviceRelations->Count = 1;
|
||||||
DeviceRelations->Objects[0] = LogDev->Common.Self;
|
DeviceRelations->Objects[0] = PdoExt->Common.Self;
|
||||||
ObReferenceObject(LogDev->Common.Self);
|
ObReferenceObject(PdoExt->Common.Self);
|
||||||
|
|
||||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||||
|
|
||||||
|
@ -38,11 +38,12 @@ IsaPdoQueryDeviceRelations(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IsaPdoQueryCapabilities(
|
IsaPdoQueryCapabilities(
|
||||||
IN PISAPNP_LOGICAL_DEVICE LogDev,
|
IN PISAPNP_PDO_EXTENSION PdoExt,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PIO_STACK_LOCATION IrpSp)
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PDEVICE_CAPABILITIES DeviceCapabilities;
|
PDEVICE_CAPABILITIES DeviceCapabilities;
|
||||||
|
PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
|
||||||
|
|
||||||
DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
|
DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
|
||||||
if (DeviceCapabilities->Version != 1)
|
if (DeviceCapabilities->Version != 1)
|
||||||
|
@ -57,10 +58,11 @@ IsaPdoQueryCapabilities(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IsaPdoQueryId(
|
IsaPdoQueryId(
|
||||||
IN PISAPNP_LOGICAL_DEVICE LogDev,
|
IN PISAPNP_PDO_EXTENSION PdoExt,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PIO_STACK_LOCATION IrpSp)
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
|
||||||
WCHAR Temp[256];
|
WCHAR Temp[256];
|
||||||
PWCHAR Buffer, End;
|
PWCHAR Buffer, End;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
@ -140,7 +142,7 @@ IsaPdoQueryId(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IsaPdoPnp(
|
IsaPdoPnp(
|
||||||
IN PISAPNP_LOGICAL_DEVICE LogDev,
|
IN PISAPNP_PDO_EXTENSION PdoExt,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PIO_STACK_LOCATION IrpSp)
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
@ -149,25 +151,25 @@ IsaPdoPnp(
|
||||||
switch (IrpSp->MinorFunction)
|
switch (IrpSp->MinorFunction)
|
||||||
{
|
{
|
||||||
case IRP_MN_START_DEVICE:
|
case IRP_MN_START_DEVICE:
|
||||||
Status = IsaHwActivateDevice(LogDev);
|
Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
LogDev->Common.State = dsStarted;
|
PdoExt->Common.State = dsStarted;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRP_MN_STOP_DEVICE:
|
case IRP_MN_STOP_DEVICE:
|
||||||
Status = IsaHwDeactivateDevice(LogDev);
|
Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
LogDev->Common.State = dsStopped;
|
PdoExt->Common.State = dsStopped;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
Status = IsaPdoQueryDeviceRelations(LogDev, Irp, IrpSp);
|
Status = IsaPdoQueryDeviceRelations(PdoExt, Irp, IrpSp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRP_MN_QUERY_CAPABILITIES:
|
case IRP_MN_QUERY_CAPABILITIES:
|
||||||
Status = IsaPdoQueryCapabilities(LogDev, Irp, IrpSp);
|
Status = IsaPdoQueryCapabilities(PdoExt, Irp, IrpSp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRP_MN_QUERY_RESOURCES:
|
case IRP_MN_QUERY_RESOURCES:
|
||||||
|
@ -179,7 +181,7 @@ IsaPdoPnp(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRP_MN_QUERY_ID:
|
case IRP_MN_QUERY_ID:
|
||||||
Status = IsaPdoQueryId(LogDev, Irp, IrpSp);
|
Status = IsaPdoQueryId(PdoExt, Irp, IrpSp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue