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
9 #include "hdaudbus.h"
10
11 DRIVER_DISPATCH HDA_Pnp;
12 DRIVER_DISPATCH HDA_SystemControl;
13 DRIVER_DISPATCH HDA_Power;
14 DRIVER_ADD_DEVICE HDA_AddDevice;
15 DRIVER_UNLOAD HDA_Unload;
16 extern "C" DRIVER_INITIALIZE DriverEntry;
17
18 PVOID
AllocateItem(_In_ POOL_TYPE PoolType,_In_ SIZE_T NumberOfBytes)19 AllocateItem(
20 _In_ POOL_TYPE PoolType,
21 _In_ SIZE_T NumberOfBytes)
22 {
23 return ExAllocatePoolZero(PoolType, NumberOfBytes, TAG_HDA);
24 }
25
26 VOID
FreeItem(__drv_freesMem (Mem)PVOID Item)27 FreeItem(
28 __drv_freesMem(Mem) PVOID Item)
29 {
30 ExFreePoolWithTag(Item, TAG_HDA);
31 }
32
33 NTSTATUS
HDA_FdoPnp(_In_ PDEVICE_OBJECT DeviceObject,_Inout_ PIRP Irp)34 HDA_FdoPnp(
35 _In_ PDEVICE_OBJECT DeviceObject,
36 _Inout_ PIRP Irp)
37 {
38 NTSTATUS Status;
39 PIO_STACK_LOCATION IoStack;
40 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
41 ULONG CodecIndex, AFGIndex;
42 PHDA_CODEC_ENTRY CodecEntry;
43 PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
44
45 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
46 IoStack = IoGetCurrentIrpStackLocation(Irp);
47
48 switch (IoStack->MinorFunction)
49 {
50 case IRP_MN_START_DEVICE:
51 Status = HDA_FDOStartDevice(DeviceObject, Irp);
52 Irp->IoStatus.Status = Status;
53 IoCompleteRequest(Irp, IO_NO_INCREMENT);
54 return Status;
55 case IRP_MN_REMOVE_DEVICE:
56 return HDA_FDORemoveDevice(DeviceObject, Irp);
57 case IRP_MN_SURPRISE_REMOVAL:
58 for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
59 {
60 CodecEntry = FDODeviceExtension->Codecs[CodecIndex];
61
62 ASSERT(CodecEntry->AudioGroupCount <= HDA_MAX_AUDIO_GROUPS);
63 for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++)
64 {
65 ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(CodecEntry->AudioGroups[AFGIndex]->ChildPDO->DeviceExtension);
66 ChildDeviceExtension->ReportedMissing = TRUE;
67 }
68 }
69 Irp->IoStatus.Status = STATUS_SUCCESS;
70 break;
71 case IRP_MN_QUERY_REMOVE_DEVICE:
72 case IRP_MN_CANCEL_REMOVE_DEVICE:
73 Irp->IoStatus.Status = STATUS_SUCCESS;
74 break;
75 case IRP_MN_QUERY_DEVICE_RELATIONS:
76 /* handle bus device relations */
77 if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
78 {
79 Status = HDA_FDOQueryBusRelations(DeviceObject, Irp);
80 Irp->IoStatus.Status = Status;
81 if (!NT_SUCCESS(Status))
82 {
83 IoCompleteRequest(Irp, IO_NO_INCREMENT);
84 return Status;
85 }
86 }
87 break;
88 }
89
90 IoSkipCurrentIrpStackLocation(Irp);
91 return IoCallDriver(FDODeviceExtension->LowerDevice, Irp);
92 }
93
94 NTSTATUS
HDA_PdoPnp(_In_ PDEVICE_OBJECT DeviceObject,_Inout_ PIRP Irp)95 HDA_PdoPnp(
96 _In_ PDEVICE_OBJECT DeviceObject,
97 _Inout_ PIRP Irp)
98 {
99 NTSTATUS Status;
100 PIO_STACK_LOCATION IoStack;
101 PDEVICE_RELATIONS DeviceRelation;
102
103 IoStack = IoGetCurrentIrpStackLocation(Irp);
104
105 switch (IoStack->MinorFunction)
106 {
107 case IRP_MN_START_DEVICE:
108 /* no op for pdo */
109 Status = STATUS_SUCCESS;
110 break;
111 case IRP_MN_REMOVE_DEVICE:
112 Status = HDA_PDORemoveDevice(DeviceObject);
113 break;
114 case IRP_MN_QUERY_REMOVE_DEVICE:
115 case IRP_MN_CANCEL_REMOVE_DEVICE:
116 Status = STATUS_SUCCESS;
117 break;
118 case IRP_MN_QUERY_BUS_INFORMATION:
119 /* query bus information */
120 Status = HDA_PDOQueryBusInformation(Irp);
121 break;
122 case IRP_MN_QUERY_PNP_DEVICE_STATE:
123 /* query pnp state */
124 Status = HDA_PDOQueryBusDevicePnpState(Irp);
125 break;
126 case IRP_MN_QUERY_DEVICE_RELATIONS:
127 if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
128 {
129 /* handle target device relations */
130 ASSERT(Irp->IoStatus.Information == 0);
131
132 /* allocate device relation */
133 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
134 if (DeviceRelation)
135 {
136 DeviceRelation->Count = 1;
137 DeviceRelation->Objects[0] = DeviceObject;
138
139 /* reference self */
140 ObReferenceObject(DeviceObject);
141
142 /* store result */
143 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
144
145 /* done */
146 Status = STATUS_SUCCESS;
147 }
148 else
149 {
150 /* no memory */
151 Status = STATUS_INSUFFICIENT_RESOURCES;
152 }
153 }
154 else
155 {
156 Status = Irp->IoStatus.Status;
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
HDA_Pnp(_In_ PDEVICE_OBJECT DeviceObject,_Inout_ PIRP Irp)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
HDA_SystemControl(_In_ PDEVICE_OBJECT DeviceObject,_Inout_ PIRP Irp)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
HDA_Power(_In_ PDEVICE_OBJECT DeviceObject,_Inout_ PIRP Irp)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
HDA_AddDevice(_In_ PDRIVER_OBJECT DriverObject,_In_ PDEVICE_OBJECT PhysicalDeviceObject)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 IoInitializeDpcRequest(DeviceObject, HDA_DpcForIsr);
287 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1));
288
289 /* set device flags */
290 DeviceObject->Flags |= DO_POWER_PAGABLE;
291
292 return Status;
293 }
294
295 VOID
296 NTAPI
HDA_Unload(_In_ PDRIVER_OBJECT DriverObject)297 HDA_Unload(
298 _In_ PDRIVER_OBJECT DriverObject)
299 {
300 }
301
302 extern "C"
303 {
304
305 NTSTATUS
306 NTAPI
DriverEntry(_In_ PDRIVER_OBJECT DriverObject,_In_ PUNICODE_STRING RegistryPathName)307 DriverEntry(
308 _In_ PDRIVER_OBJECT DriverObject,
309 _In_ PUNICODE_STRING RegistryPathName)
310 {
311 DriverObject->DriverUnload = HDA_Unload;
312 DriverObject->DriverExtension->AddDevice = HDA_AddDevice;
313 DriverObject->MajorFunction[IRP_MJ_POWER] = HDA_Power;
314 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HDA_SystemControl;
315 DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp;
316
317 return STATUS_SUCCESS;
318 }
319
320 } // extern "C"
321