[HDAUDBUS] Use IoForwardIrpSynchronously instead of HDA_SyncForwardIrp.
[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
43 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
44 IoStack = IoGetCurrentIrpStackLocation(Irp);
45
46 switch (IoStack->MinorFunction)
47 {
48 case IRP_MN_START_DEVICE:
49 Status = HDA_FDOStartDevice(DeviceObject, Irp);
50 Irp->IoStatus.Status = Status;
51 IoCompleteRequest(Irp, IO_NO_INCREMENT);
52 return Status;
53 case IRP_MN_QUERY_DEVICE_RELATIONS:
54 /* handle bus device relations */
55 if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
56 {
57 Status = HDA_FDOQueryBusRelations(DeviceObject, Irp);
58 Irp->IoStatus.Status = Status;
59 if (!NT_SUCCESS(Status))
60 {
61 IoCompleteRequest(Irp, IO_NO_INCREMENT);
62 return Status;
63 }
64 }
65 break;
66 }
67
68 IoSkipCurrentIrpStackLocation(Irp);
69 return IoCallDriver(FDODeviceExtension->LowerDevice, Irp);
70 }
71
72 NTSTATUS
73 HDA_PdoPnp(
74 _In_ PDEVICE_OBJECT DeviceObject,
75 _Inout_ PIRP Irp)
76 {
77 NTSTATUS Status;
78 PIO_STACK_LOCATION IoStack;
79 PDEVICE_RELATIONS DeviceRelation;
80
81 IoStack = IoGetCurrentIrpStackLocation(Irp);
82
83 switch (IoStack->MinorFunction)
84 {
85 case IRP_MN_START_DEVICE:
86 /* no op for pdo */
87 Status = STATUS_SUCCESS;
88 break;
89 case IRP_MN_QUERY_BUS_INFORMATION:
90 /* query bus information */
91 Status = HDA_PDOQueryBusInformation(Irp);
92 break;
93 case IRP_MN_QUERY_PNP_DEVICE_STATE:
94 /* query pnp state */
95 Status = HDA_PDOQueryBusDevicePnpState(Irp);
96 break;
97 case IRP_MN_QUERY_DEVICE_RELATIONS:
98 if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
99 {
100 /* handle target device relations */
101 ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation);
102 ASSERT(Irp->IoStatus.Information == 0);
103
104 /* allocate device relation */
105 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
106 if (DeviceRelation)
107 {
108 DeviceRelation->Count = 1;
109 DeviceRelation->Objects[0] = DeviceObject;
110
111 /* reference self */
112 ObReferenceObject(DeviceObject);
113
114 /* store result */
115 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
116
117 /* done */
118 Status = STATUS_SUCCESS;
119 }
120 else
121 {
122 /* no memory */
123 Status = STATUS_INSUFFICIENT_RESOURCES;
124 }
125 }
126 break;
127 case IRP_MN_QUERY_CAPABILITIES:
128 /* query capabilities */
129 Status = HDA_PDOQueryBusDeviceCapabilities(Irp);
130 break;
131 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
132 /* no op */
133 Status = STATUS_SUCCESS;
134 break;
135 case IRP_MN_QUERY_RESOURCES:
136 /* no op */
137 Status = STATUS_SUCCESS;
138 break;
139 case IRP_MN_QUERY_ID:
140 Status = HDA_PDOQueryId(DeviceObject, Irp);
141 break;
142 case IRP_MN_QUERY_DEVICE_TEXT:
143 Status = HDA_PDOHandleQueryDeviceText(Irp);
144 break;
145 case IRP_MN_QUERY_INTERFACE:
146 Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp);
147 break;
148 default:
149 /* get default status */
150 Status = Irp->IoStatus.Status;
151 break;
152 }
153
154 Irp->IoStatus.Status = Status;
155 IoCompleteRequest(Irp, IO_NO_INCREMENT);
156
157 return Status;
158 }
159
160 NTSTATUS
161 NTAPI
162 HDA_Pnp(
163 _In_ PDEVICE_OBJECT DeviceObject,
164 _Inout_ PIRP Irp)
165 {
166 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
167
168 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
169
170 if (FDODeviceExtension->IsFDO)
171 {
172 return HDA_FdoPnp(DeviceObject, Irp);
173 }
174 else
175 {
176 return HDA_PdoPnp(DeviceObject, Irp);
177 }
178 }
179
180
181 NTSTATUS
182 NTAPI
183 HDA_AddDevice(
184 _In_ PDRIVER_OBJECT DriverObject,
185 _In_ PDEVICE_OBJECT PhysicalDeviceObject)
186 {
187 PDEVICE_OBJECT DeviceObject;
188 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
189 NTSTATUS Status;
190
191 /* create device object */
192 Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject);
193 if (!NT_SUCCESS(Status))
194 {
195 /* failed */
196 return Status;
197 }
198
199 /* get device extension*/
200 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
201
202 /* init device extension*/
203 DeviceExtension->IsFDO = TRUE;
204 DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
205 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1));
206
207 /* set device flags */
208 DeviceObject->Flags |= DO_POWER_PAGABLE;
209
210 return Status;
211 }
212 extern "C"
213 {
214 NTSTATUS
215 NTAPI
216 DriverEntry(
217 _In_ PDRIVER_OBJECT DriverObject,
218 _In_ PUNICODE_STRING RegistryPathName)
219 {
220 DriverObject->DriverExtension->AddDevice = HDA_AddDevice;
221 DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp;
222
223 return STATUS_SUCCESS;
224 }
225
226 }