Sync with trunk r63502.
[reactos.git] / drivers / bus / isapnp / fdo.c
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 }