xref: /reactos/drivers/bus/isapnp/fdo.c (revision c2c66aff)
1 /*
2  * PROJECT:         ReactOS ISA PnP Bus driver
3  * FILE:            fdo.c
4  * PURPOSE:         FDO-specific code
5  * PROGRAMMERS:     Cameron Gutman (cameron.gutman@reactos.org)
6  */
7 
8 #include <isapnp.h>
9 
10 #define NDEBUG
11 #include <debug.h>
12 
13 NTSTATUS
14 NTAPI
15 IsaFdoStartDevice(
16   IN PISAPNP_FDO_EXTENSION FdoExt,
17   IN PIRP Irp,
18   IN PIO_STACK_LOCATION IrpSp)
19 {
20   NTSTATUS Status;
21   KIRQL OldIrql;
22 
23   UNREFERENCED_PARAMETER(Irp);
24   UNREFERENCED_PARAMETER(IrpSp);
25 
26   KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
27 
28   Status = IsaHwDetectReadDataPort(FdoExt);
29   if (!NT_SUCCESS(Status))
30   {
31       KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
32       return Status;
33   }
34 
35   FdoExt->Common.State = dsStarted;
36 
37   KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
38 
39   return STATUS_SUCCESS;
40 }
41 
42 NTSTATUS
43 NTAPI
44 IsaFdoQueryDeviceRelations(
45   IN PISAPNP_FDO_EXTENSION FdoExt,
46   IN PIRP Irp,
47   IN PIO_STACK_LOCATION IrpSp)
48 {
49   NTSTATUS Status;
50   PLIST_ENTRY CurrentEntry;
51   PISAPNP_LOGICAL_DEVICE IsaDevice;
52   PDEVICE_RELATIONS DeviceRelations;
53   KIRQL OldIrql;
54   ULONG i = 0;
55 
56   if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
57       return Irp->IoStatus.Status;
58 
59   KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
60 
61   Status = IsaHwFillDeviceList(FdoExt);
62   if (!NT_SUCCESS(Status))
63   {
64       KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
65       return Status;
66   }
67 
68   DeviceRelations = ExAllocatePool(NonPagedPool,
69                             sizeof(DEVICE_RELATIONS) + sizeof(DEVICE_OBJECT) * (FdoExt->DeviceCount - 1));
70   if (!DeviceRelations)
71   {
72       KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
73       return STATUS_INSUFFICIENT_RESOURCES;
74   }
75 
76   CurrentEntry = FdoExt->DeviceListHead.Flink;
77   while (CurrentEntry != &FdoExt->DeviceListHead)
78   {
79      IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, ListEntry);
80 
81      DeviceRelations->Objects[i++] = IsaDevice->Common.Self;
82 
83      ObReferenceObject(IsaDevice->Common.Self);
84 
85      CurrentEntry = CurrentEntry->Flink;
86   }
87 
88   DeviceRelations->Count = FdoExt->DeviceCount;
89 
90   KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
91 
92   Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
93 
94   return STATUS_SUCCESS;
95 }
96 
97 NTSTATUS
98 NTAPI
99 IsaFdoPnp(
100   IN PISAPNP_FDO_EXTENSION FdoExt,
101   IN PIRP Irp,
102   IN PIO_STACK_LOCATION IrpSp)
103 {
104   NTSTATUS Status = Irp->IoStatus.Status;
105 
106   switch (IrpSp->MinorFunction)
107   {
108      case IRP_MN_START_DEVICE:
109        Status = IsaForwardIrpSynchronous(FdoExt, Irp);
110 
111        if (NT_SUCCESS(Status))
112          Status = IsaFdoStartDevice(FdoExt, Irp, IrpSp);
113 
114        Irp->IoStatus.Status = Status;
115 
116        IoCompleteRequest(Irp, IO_NO_INCREMENT);
117        return Status;
118 
119      case IRP_MN_STOP_DEVICE:
120        FdoExt->Common.State = dsStopped;
121 
122        Status = STATUS_SUCCESS;
123        break;
124 
125      case IRP_MN_QUERY_DEVICE_RELATIONS:
126        Status = IsaFdoQueryDeviceRelations(FdoExt, Irp, IrpSp);
127 
128        Irp->IoStatus.Status = Status;
129 
130        IoCompleteRequest(Irp, IO_NO_INCREMENT);
131        return Status;
132 
133      case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
134        DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
135        break;
136 
137      default:
138        DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
139        break;
140   }
141 
142   IoSkipCurrentIrpStackLocation(Irp);
143 
144   return IoCallDriver(FdoExt->Ldo, Irp);
145 }
146