Also let kernel choose the read data port address, by using the resources given in IRP_MN_START_DEVICE.
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
- NTSTATUS Status;
- KIRQL OldIrql;
-
UNREFERENCED_PARAMETER(Irp);
UNREFERENCED_PARAMETER(IrpSp);
- KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
- Status = IsaHwDetectReadDataPort(FdoExt);
- KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
-
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
FdoExt->Common.State = dsStarted;
return STATUS_SUCCESS;
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
- NTSTATUS Status;
- KIRQL OldIrql;
-
if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
return Irp->IoStatus.Status;
- KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
- Status = IsaHwFillDeviceList(FdoExt);
- KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
-
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
return IsaPnpFillDeviceRelations(FdoExt, Irp, TRUE);
}
return Csn;
}
-static
-PUCHAR
-Isolate(VOID)
-{
- PUCHAR ReadPort;
-
- for (ReadPort = (PUCHAR)ISAPNP_READ_PORT_START;
- (ULONG_PTR)ReadPort <= ISAPNP_READ_PORT_MAX;
- ReadPort += ISAPNP_READ_PORT_STEP)
- {
- /* Avoid the NE2000 probe space */
- if ((ULONG_PTR)ReadPort >= 0x280 &&
- (ULONG_PTR)ReadPort <= 0x380)
- continue;
-
- if (TryIsolate(ReadPort) > 0)
- return ReadPort;
- }
-
- return 0;
-}
-
VOID
DeviceActivation(
IN PISAPNP_LOGICAL_DEVICE IsaDevice,
NTSTATUS
NTAPI
-IsaHwDetectReadDataPort(
- IN PISAPNP_FDO_EXTENSION FdoExt)
+IsaHwTryReadDataPort(
+ IN PUCHAR ReadDataPort)
{
- FdoExt->ReadDataPort = Isolate();
- if (!FdoExt->ReadDataPort)
- {
- DPRINT1("No read data port found\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- DPRINT1("Detected read data port at 0x%p\n", FdoExt->ReadDataPort);
-
- return STATUS_SUCCESS;
+ return TryIsolate(ReadDataPort) > 0 ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
}
NTSTATUS
/* hardware.c */
NTSTATUS
NTAPI
-IsaHwDetectReadDataPort(
- IN PISAPNP_FDO_EXTENSION FdoExt);
+IsaHwTryReadDataPort(
+ IN PUCHAR ReadDataPort);
NTSTATUS
NTAPI
return STATUS_SUCCESS;
}
+static
+NTSTATUS
+NTAPI
+IsaPdoStartReadPort(
+ IN PISAPNP_FDO_EXTENSION FdoExt,
+ IN PIO_STACK_LOCATION IrpSp)
+{
+ PCM_RESOURCE_LIST ResourceList = IrpSp->Parameters.StartDevice.AllocatedResources;
+ NTSTATUS Status;
+ KIRQL OldIrql;
+ ULONG i;
+
+ if (!ResourceList || ResourceList->Count != 1)
+ {
+ DPRINT1("No resource list (%p) or bad count (%d)\n", ResourceList, ResourceList ? ResourceList->Count : 0);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ if (ResourceList->List[0].PartialResourceList.Version != 1
+ || ResourceList->List[0].PartialResourceList.Revision != 1)
+ {
+ DPRINT1("Bad resource list version (%d.%d)\n", ResourceList->List[0].PartialResourceList.Version, ResourceList->List[0].PartialResourceList.Revision);
+ return STATUS_REVISION_MISMATCH;
+ }
+ for (i = 0; i < ResourceList->List[0].PartialResourceList.Count; i++)
+ {
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
+ if (PartialDescriptor->Type == CmResourceTypePort)
+ {
+ PUCHAR ReadDataPort = (PUCHAR)PartialDescriptor->u.Port.Start.u.LowPart + 3;
+ if (PartialDescriptor->u.Port.Length > 1 && !FdoExt->ReadDataPort && NT_SUCCESS(IsaHwTryReadDataPort(ReadDataPort)))
+ {
+ FdoExt->ReadDataPort = ReadDataPort;
+ KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
+ Status = IsaHwFillDeviceList(FdoExt);
+ KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+ if (FdoExt->DeviceCount > 0)
+ {
+ IoInvalidateDeviceRelations(FdoExt->Pdo, BusRelations);
+ IoInvalidateDeviceRelations(FdoExt->DataPortPdo, RemovalRelations);
+ }
+ }
+ }
+ }
+ return Status;
+}
+
NTSTATUS
NTAPI
IsaPdoPnp(
if (PdoExt->IsaPnpDevice)
Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
else
- Status = STATUS_SUCCESS;
+ Status = IsaPdoStartReadPort(PdoExt->FdoExt, IrpSp);
if (NT_SUCCESS(Status))
PdoExt->Common.State = dsStarted;