0202385a82fc38555a61052c5f3d10d0e8ff9a68
[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 HDA_FdoPnp(
36 _In_ PDEVICE_OBJECT DeviceObject,
37 _Inout_ PIRP Irp)
38 {
39 NTSTATUS Status;
40 PIO_STACK_LOCATION IoStack;
41 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
42 ULONG CodecIndex, AFGIndex;
43 PHDA_CODEC_ENTRY CodecEntry;
44 PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
45
46 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
47 IoStack = IoGetCurrentIrpStackLocation(Irp);
48
49 switch (IoStack->MinorFunction)
50 {
51 case IRP_MN_START_DEVICE:
52 Status = HDA_FDOStartDevice(DeviceObject, Irp);
53 Irp->IoStatus.Status = Status;
54 IoCompleteRequest(Irp, IO_NO_INCREMENT);
55 return Status;
56 case IRP_MN_REMOVE_DEVICE:
57 return HDA_FDORemoveDevice(DeviceObject, Irp);
58 case IRP_MN_SURPRISE_REMOVAL:
59 for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
60 {
61 CodecEntry = FDODeviceExtension->Codecs[CodecIndex];
62
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
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(IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation);
131 ASSERT(Irp->IoStatus.Information == 0);
132
133 /* allocate device relation */
134 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
135 if (DeviceRelation)
136 {
137 DeviceRelation->Count = 1;
138 DeviceRelation->Objects[0] = DeviceObject;
139
140 /* reference self */
141 ObReferenceObject(DeviceObject);
142
143 /* store result */
144 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
145
146 /* done */
147 Status = STATUS_SUCCESS;
148 }
149 else
150 {
151 /* no memory */
152 Status = STATUS_INSUFFICIENT_RESOURCES;
153 }
154 }
155 break;
156 case IRP_MN_QUERY_CAPABILITIES:
157 /* query capabilities */
158 Status = HDA_PDOQueryBusDeviceCapabilities(Irp);
159 break;
160 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
161 /* no op */
162 Status = STATUS_SUCCESS;
163 break;
164 case IRP_MN_QUERY_RESOURCES:
165 /* no op */
166 Status = STATUS_SUCCESS;
167 break;
168 case IRP_MN_QUERY_ID:
169 Status = HDA_PDOQueryId(DeviceObject, Irp);
170 break;
171 case IRP_MN_QUERY_DEVICE_TEXT:
172 Status = HDA_PDOHandleQueryDeviceText(Irp);
173 break;
174 case IRP_MN_QUERY_INTERFACE:
175 Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp);
176 break;
177 default:
178 /* get default status */
179 Status = Irp->IoStatus.Status;
180 break;
181 }
182
183 Irp->IoStatus.Status = Status;
184 IoCompleteRequest(Irp, IO_NO_INCREMENT);
185
186 return Status;
187 }
188
189 NTSTATUS
190 NTAPI
191 HDA_Pnp(
192 _In_ PDEVICE_OBJECT DeviceObject,
193 _Inout_ PIRP Irp)
194 {
195 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
196
197 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
198
199 if (FDODeviceExtension->IsFDO)
200 {
201 return HDA_FdoPnp(DeviceObject, Irp);
202 }
203 else
204 {
205 return HDA_PdoPnp(DeviceObject, Irp);
206 }
207 }
208
209
210 NTSTATUS
211 NTAPI
212 HDA_AddDevice(
213 _In_ PDRIVER_OBJECT DriverObject,
214 _In_ PDEVICE_OBJECT PhysicalDeviceObject)
215 {
216 PDEVICE_OBJECT DeviceObject;
217 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
218 NTSTATUS Status;
219
220 /* create device object */
221 Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject);
222 if (!NT_SUCCESS(Status))
223 {
224 /* failed */
225 return Status;
226 }
227
228 /* get device extension*/
229 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
230
231 /* init device extension*/
232 DeviceExtension->IsFDO = TRUE;
233 DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
234 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1));
235
236 /* set device flags */
237 DeviceObject->Flags |= DO_POWER_PAGABLE;
238
239 return Status;
240 }
241 extern "C"
242 {
243 NTSTATUS
244 NTAPI
245 DriverEntry(
246 _In_ PDRIVER_OBJECT DriverObject,
247 _In_ PUNICODE_STRING RegistryPathName)
248 {
249 DriverObject->DriverExtension->AddDevice = HDA_AddDevice;
250 DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp;
251
252 return STATUS_SUCCESS;
253 }
254
255 }