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