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