[HDAUDBUS] Use a switch for minor function codes.
[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_ADD_DEVICE HDA_AddDevice;
12 extern "C" DRIVER_INITIALIZE DriverEntry;
13
14 PVOID
15 AllocateItem(
16 _In_ POOL_TYPE PoolType,
17 _In_ SIZE_T NumberOfBytes)
18 {
19 PVOID Item = ExAllocatePoolWithTag(PoolType, NumberOfBytes, TAG_HDA);
20 if (!Item)
21 return Item;
22
23 RtlZeroMemory(Item, NumberOfBytes);
24 return Item;
25 }
26
27 VOID
28 FreeItem(
29 __drv_freesMem(Mem) PVOID Item)
30 {
31 ExFreePool(Item);
32 }
33
34 NTSTATUS
35 NTAPI
36 HDA_SyncForwardIrpCompletionRoutine(
37 IN PDEVICE_OBJECT DeviceObject,
38 IN PIRP Irp,
39 IN PVOID Context)
40 {
41 if (Irp->PendingReturned)
42 {
43 KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
44 }
45 return STATUS_MORE_PROCESSING_REQUIRED;
46 }
47
48 NTSTATUS
49 NTAPI
50 HDA_SyncForwardIrp(
51 IN PDEVICE_OBJECT DeviceObject,
52 IN PIRP Irp)
53 {
54 KEVENT Event;
55 NTSTATUS Status;
56
57 /* Initialize event */
58 KeInitializeEvent(&Event, NotificationEvent, FALSE);
59
60 /* Copy irp stack location */
61 IoCopyCurrentIrpStackLocationToNext(Irp);
62
63 /* Set completion routine */
64 IoSetCompletionRoutine(Irp,
65 HDA_SyncForwardIrpCompletionRoutine,
66 &Event,
67 TRUE,
68 TRUE,
69 TRUE);
70
71 /* Call driver */
72 Status = IoCallDriver(DeviceObject, Irp);
73
74 /* Check if pending */
75 if (Status == STATUS_PENDING)
76 {
77 /* Wait for the request to finish */
78 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
79
80 /* Copy status code */
81 Status = Irp->IoStatus.Status;
82 }
83
84 /* Done */
85 return Status;
86 }
87
88 NTSTATUS
89 HDA_FdoPnp(
90 _In_ PDEVICE_OBJECT DeviceObject,
91 _Inout_ PIRP Irp)
92 {
93 NTSTATUS Status;
94 PIO_STACK_LOCATION IoStack;
95 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
96
97 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
98 IoStack = IoGetCurrentIrpStackLocation(Irp);
99
100 switch (IoStack->MinorFunction)
101 {
102 case IRP_MN_START_DEVICE:
103 Status = HDA_FDOStartDevice(DeviceObject, Irp);
104 break;
105 case IRP_MN_QUERY_DEVICE_RELATIONS:
106 /* handle bus device relations */
107 if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
108 {
109 Status = HDA_FDOQueryBusRelations(DeviceObject, Irp);
110 }
111 else
112 {
113 Status = Irp->IoStatus.Status;
114 }
115 break;
116 default:
117 /* get default status */
118 Status = Irp->IoStatus.Status;
119 break;
120 }
121
122 Irp->IoStatus.Status = Status;
123 IoCompleteRequest(Irp, IO_NO_INCREMENT);
124
125 return Status;
126 }
127
128 NTSTATUS
129 HDA_PdoPnp(
130 _In_ PDEVICE_OBJECT DeviceObject,
131 _Inout_ PIRP Irp)
132 {
133 NTSTATUS Status;
134 PIO_STACK_LOCATION IoStack;
135 PDEVICE_RELATIONS DeviceRelation;
136
137 IoStack = IoGetCurrentIrpStackLocation(Irp);
138
139 switch (IoStack->MinorFunction)
140 {
141 case IRP_MN_START_DEVICE:
142 /* no op for pdo */
143 Status = STATUS_SUCCESS;
144 break;
145 case IRP_MN_QUERY_BUS_INFORMATION:
146 /* query bus information */
147 Status = HDA_PDOQueryBusInformation(Irp);
148 break;
149 case IRP_MN_QUERY_PNP_DEVICE_STATE:
150 /* query pnp state */
151 Status = HDA_PDOQueryBusDevicePnpState(Irp);
152 break;
153 case IRP_MN_QUERY_DEVICE_RELATIONS:
154 if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
155 {
156 /* handle target device relations */
157 ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation);
158 ASSERT(Irp->IoStatus.Information == 0);
159
160 /* allocate device relation */
161 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
162 if (DeviceRelation)
163 {
164 DeviceRelation->Count = 1;
165 DeviceRelation->Objects[0] = DeviceObject;
166
167 /* reference self */
168 ObReferenceObject(DeviceObject);
169
170 /* store result */
171 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
172
173 /* done */
174 Status = STATUS_SUCCESS;
175 }
176 else
177 {
178 /* no memory */
179 Status = STATUS_INSUFFICIENT_RESOURCES;
180 }
181 }
182 break;
183 case IRP_MN_QUERY_CAPABILITIES:
184 /* query capabilities */
185 Status = HDA_PDOQueryBusDeviceCapabilities(Irp);
186 break;
187 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
188 /* no op */
189 Status = STATUS_SUCCESS;
190 break;
191 case IRP_MN_QUERY_RESOURCES:
192 /* no op */
193 Status = STATUS_SUCCESS;
194 break;
195 case IRP_MN_QUERY_ID:
196 Status = HDA_PDOQueryId(DeviceObject, Irp);
197 break;
198 case IRP_MN_QUERY_DEVICE_TEXT:
199 Status = HDA_PDOHandleQueryDeviceText(Irp);
200 break;
201 case IRP_MN_QUERY_INTERFACE:
202 Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp);
203 break;
204 default:
205 /* get default status */
206 Status = Irp->IoStatus.Status;
207 break;
208 }
209
210 Irp->IoStatus.Status = Status;
211 IoCompleteRequest(Irp, IO_NO_INCREMENT);
212
213 return Status;
214 }
215
216 NTSTATUS
217 NTAPI
218 HDA_Pnp(
219 _In_ PDEVICE_OBJECT DeviceObject,
220 _Inout_ PIRP Irp)
221 {
222 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
223
224 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
225
226 if (FDODeviceExtension->IsFDO)
227 {
228 return HDA_FdoPnp(DeviceObject, Irp);
229 }
230 else
231 {
232 return HDA_PdoPnp(DeviceObject, Irp);
233 }
234 }
235
236
237 NTSTATUS
238 NTAPI
239 HDA_AddDevice(
240 _In_ PDRIVER_OBJECT DriverObject,
241 _In_ PDEVICE_OBJECT PhysicalDeviceObject)
242 {
243 PDEVICE_OBJECT DeviceObject;
244 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
245 NTSTATUS Status;
246
247 /* create device object */
248 Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject);
249 if (!NT_SUCCESS(Status))
250 {
251 /* failed */
252 return Status;
253 }
254
255 /* get device extension*/
256 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
257
258 /* init device extension*/
259 DeviceExtension->IsFDO = TRUE;
260 DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
261 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1));
262
263 /* set device flags */
264 DeviceObject->Flags |= DO_POWER_PAGABLE;
265
266 return Status;
267 }
268 extern "C"
269 {
270 NTSTATUS
271 NTAPI
272 DriverEntry(
273 _In_ PDRIVER_OBJECT DriverObject,
274 _In_ PUNICODE_STRING RegistryPathName)
275 {
276 DriverObject->DriverExtension->AddDevice = HDA_AddDevice;
277 DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp;
278
279 return STATUS_SUCCESS;
280 }
281
282 }