[HDAUDBUS] Implement HDA_Unload. Stub HDA_Power and HDA_SystemControl.
[reactos.git] / drivers / wdm / audio / hdaudbus / hdaudbus.cpp
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/hdaudbus/hdaudbus.cpp
5 * PURPOSE: HDA Driver Entry
6 * PROGRAMMER: Johannes Anderwald
7 */
8 #include "hdaudbus.h"
9
10 DRIVER_DISPATCH HDA_Pnp;
11 DRIVER_DISPATCH HDA_SystemControl;
12 DRIVER_DISPATCH HDA_Power;
13 DRIVER_ADD_DEVICE HDA_AddDevice;
14 DRIVER_UNLOAD HDA_Unload;
15 extern "C" DRIVER_INITIALIZE DriverEntry;
16
17 PVOID
18 AllocateItem(
19 _In_ POOL_TYPE PoolType,
20 _In_ SIZE_T NumberOfBytes)
21 {
22 PVOID Item = ExAllocatePoolWithTag(PoolType, NumberOfBytes, TAG_HDA);
23 if (!Item)
24 return Item;
25
26 RtlZeroMemory(Item, NumberOfBytes);
27 return Item;
28 }
29
30 VOID
31 FreeItem(
32 __drv_freesMem(Mem) PVOID Item)
33 {
34 ExFreePool(Item);
35 }
36
37 NTSTATUS
38 HDA_FdoPnp(
39 _In_ PDEVICE_OBJECT DeviceObject,
40 _Inout_ PIRP Irp)
41 {
42 NTSTATUS Status;
43 PIO_STACK_LOCATION IoStack;
44 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
45 ULONG CodecIndex, AFGIndex;
46 PHDA_CODEC_ENTRY CodecEntry;
47 PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
48
49 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
50 IoStack = IoGetCurrentIrpStackLocation(Irp);
51
52 switch (IoStack->MinorFunction)
53 {
54 case IRP_MN_START_DEVICE:
55 Status = HDA_FDOStartDevice(DeviceObject, Irp);
56 Irp->IoStatus.Status = Status;
57 IoCompleteRequest(Irp, IO_NO_INCREMENT);
58 return Status;
59 case IRP_MN_REMOVE_DEVICE:
60 return HDA_FDORemoveDevice(DeviceObject, Irp);
61 case IRP_MN_SURPRISE_REMOVAL:
62 for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
63 {
64 CodecEntry = FDODeviceExtension->Codecs[CodecIndex];
65
66 for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++)
67 {
68 ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(CodecEntry->AudioGroups[AFGIndex]->ChildPDO->DeviceExtension);
69 ChildDeviceExtension->ReportedMissing = TRUE;
70 }
71 }
72 Irp->IoStatus.Status = STATUS_SUCCESS;
73 break;
74 case IRP_MN_QUERY_REMOVE_DEVICE:
75 case IRP_MN_CANCEL_REMOVE_DEVICE:
76 Irp->IoStatus.Status = STATUS_SUCCESS;
77 break;
78 case IRP_MN_QUERY_DEVICE_RELATIONS:
79 /* handle bus device relations */
80 if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
81 {
82 Status = HDA_FDOQueryBusRelations(DeviceObject, Irp);
83 Irp->IoStatus.Status = Status;
84 if (!NT_SUCCESS(Status))
85 {
86 IoCompleteRequest(Irp, IO_NO_INCREMENT);
87 return Status;
88 }
89 }
90 break;
91 }
92
93 IoSkipCurrentIrpStackLocation(Irp);
94 return IoCallDriver(FDODeviceExtension->LowerDevice, Irp);
95 }
96
97 NTSTATUS
98 HDA_PdoPnp(
99 _In_ PDEVICE_OBJECT DeviceObject,
100 _Inout_ PIRP Irp)
101 {
102 NTSTATUS Status;
103 PIO_STACK_LOCATION IoStack;
104 PDEVICE_RELATIONS DeviceRelation;
105
106 IoStack = IoGetCurrentIrpStackLocation(Irp);
107
108 switch (IoStack->MinorFunction)
109 {
110 case IRP_MN_START_DEVICE:
111 /* no op for pdo */
112 Status = STATUS_SUCCESS;
113 break;
114 case IRP_MN_REMOVE_DEVICE:
115 Status = HDA_PDORemoveDevice(DeviceObject);
116 break;
117 case IRP_MN_QUERY_REMOVE_DEVICE:
118 case IRP_MN_CANCEL_REMOVE_DEVICE:
119 Status = STATUS_SUCCESS;
120 break;
121 case IRP_MN_QUERY_BUS_INFORMATION:
122 /* query bus information */
123 Status = HDA_PDOQueryBusInformation(Irp);
124 break;
125 case IRP_MN_QUERY_PNP_DEVICE_STATE:
126 /* query pnp state */
127 Status = HDA_PDOQueryBusDevicePnpState(Irp);
128 break;
129 case IRP_MN_QUERY_DEVICE_RELATIONS:
130 if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
131 {
132 /* handle target device relations */
133 ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation);
134 ASSERT(Irp->IoStatus.Information == 0);
135
136 /* allocate device relation */
137 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
138 if (DeviceRelation)
139 {
140 DeviceRelation->Count = 1;
141 DeviceRelation->Objects[0] = DeviceObject;
142
143 /* reference self */
144 ObReferenceObject(DeviceObject);
145
146 /* store result */
147 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
148
149 /* done */
150 Status = STATUS_SUCCESS;
151 }
152 else
153 {
154 /* no memory */
155 Status = STATUS_INSUFFICIENT_RESOURCES;
156 }
157 }
158 break;
159 case IRP_MN_QUERY_CAPABILITIES:
160 /* query capabilities */
161 Status = HDA_PDOQueryBusDeviceCapabilities(Irp);
162 break;
163 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
164 /* no op */
165 Status = STATUS_SUCCESS;
166 break;
167 case IRP_MN_QUERY_RESOURCES:
168 /* no op */
169 Status = STATUS_SUCCESS;
170 break;
171 case IRP_MN_QUERY_ID:
172 Status = HDA_PDOQueryId(DeviceObject, Irp);
173 break;
174 case IRP_MN_QUERY_DEVICE_TEXT:
175 Status = HDA_PDOHandleQueryDeviceText(Irp);
176 break;
177 case IRP_MN_QUERY_INTERFACE:
178 Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp);
179 break;
180 default:
181 /* get default status */
182 Status = Irp->IoStatus.Status;
183 break;
184 }
185
186 Irp->IoStatus.Status = Status;
187 IoCompleteRequest(Irp, IO_NO_INCREMENT);
188
189 return Status;
190 }
191
192 NTSTATUS
193 NTAPI
194 HDA_Pnp(
195 _In_ PDEVICE_OBJECT DeviceObject,
196 _Inout_ PIRP Irp)
197 {
198 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
199
200 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
201
202 if (FDODeviceExtension->IsFDO)
203 {
204 return HDA_FdoPnp(DeviceObject, Irp);
205 }
206 else
207 {
208 return HDA_PdoPnp(DeviceObject, Irp);
209 }
210 }
211
212 NTSTATUS
213 NTAPI
214 HDA_SystemControl(
215 _In_ PDEVICE_OBJECT DeviceObject,
216 _Inout_ PIRP Irp)
217 {
218 NTSTATUS Status;
219 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
220
221 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
222
223 if (FDODeviceExtension->IsFDO)
224 {
225 IoSkipCurrentIrpStackLocation(Irp);
226 return IoCallDriver(FDODeviceExtension->LowerDevice, Irp);
227 }
228 else
229 {
230 Status = Irp->IoStatus.Status;
231 IoCompleteRequest(Irp, IO_NO_INCREMENT);
232 return Status;
233 }
234 }
235
236 NTSTATUS
237 NTAPI
238 HDA_Power(
239 _In_ PDEVICE_OBJECT DeviceObject,
240 _Inout_ PIRP Irp)
241 {
242 NTSTATUS Status;
243 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
244
245 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
246
247 if (FDODeviceExtension->IsFDO)
248 {
249 PoStartNextPowerIrp(Irp);
250 IoSkipCurrentIrpStackLocation(Irp);
251 return PoCallDriver(FDODeviceExtension->LowerDevice, Irp);
252 }
253 else
254 {
255 Status = Irp->IoStatus.Status;
256 PoStartNextPowerIrp(Irp);
257 IoCompleteRequest(Irp, IO_NO_INCREMENT);
258 return Status;
259 }
260 }
261
262 NTSTATUS
263 NTAPI
264 HDA_AddDevice(
265 _In_ PDRIVER_OBJECT DriverObject,
266 _In_ PDEVICE_OBJECT PhysicalDeviceObject)
267 {
268 PDEVICE_OBJECT DeviceObject;
269 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
270 NTSTATUS Status;
271
272 /* create device object */
273 Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject);
274 if (!NT_SUCCESS(Status))
275 {
276 /* failed */
277 return Status;
278 }
279
280 /* get device extension*/
281 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
282
283 /* init device extension*/
284 DeviceExtension->IsFDO = TRUE;
285 DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
286 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1));
287
288 /* set device flags */
289 DeviceObject->Flags |= DO_POWER_PAGABLE;
290
291 return Status;
292 }
293
294 VOID
295 NTAPI
296 HDA_Unload(
297 _In_ PDRIVER_OBJECT DriverObject)
298 {
299 }
300
301 extern "C"
302 {
303 NTSTATUS
304 NTAPI
305 DriverEntry(
306 _In_ PDRIVER_OBJECT DriverObject,
307 _In_ PUNICODE_STRING RegistryPathName)
308 {
309 DriverObject->DriverUnload = HDA_Unload;
310 DriverObject->DriverExtension->AddDevice = HDA_AddDevice;
311 DriverObject->MajorFunction[IRP_MJ_POWER] = HDA_Power;
312 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HDA_SystemControl;
313 DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp;
314
315 return STATUS_SUCCESS;
316 }
317
318 }