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