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_DISPATCH HDA_SystemControl; 12 DRIVER_DISPATCH HDA_Power; 13 DRIVER_ADD_DEVICE HDA_AddDevice; 14 DRIVER_UNLOAD HDA_Unload; 15 extern "C" DRIVER_INITIALIZE DriverEntry; 16 17 PVOID 18 AllocateItem( 19 _In_ POOL_TYPE PoolType, 20 _In_ SIZE_T NumberOfBytes) 21 { 22 PVOID Item = ExAllocatePoolWithTag(PoolType, NumberOfBytes, TAG_HDA); 23 if (!Item) 24 return Item; 25 26 RtlZeroMemory(Item, NumberOfBytes); 27 return Item; 28 } 29 30 VOID 31 FreeItem( 32 __drv_freesMem(Mem) PVOID Item) 33 { 34 ExFreePool(Item); 35 } 36 37 NTSTATUS 38 HDA_FdoPnp( 39 _In_ PDEVICE_OBJECT DeviceObject, 40 _Inout_ PIRP Irp) 41 { 42 NTSTATUS Status; 43 PIO_STACK_LOCATION IoStack; 44 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 45 ULONG CodecIndex, AFGIndex; 46 PHDA_CODEC_ENTRY CodecEntry; 47 PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension; 48 49 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 50 IoStack = IoGetCurrentIrpStackLocation(Irp); 51 52 switch (IoStack->MinorFunction) 53 { 54 case IRP_MN_START_DEVICE: 55 Status = HDA_FDOStartDevice(DeviceObject, Irp); 56 Irp->IoStatus.Status = Status; 57 IoCompleteRequest(Irp, IO_NO_INCREMENT); 58 return Status; 59 case IRP_MN_REMOVE_DEVICE: 60 return HDA_FDORemoveDevice(DeviceObject, Irp); 61 case IRP_MN_SURPRISE_REMOVAL: 62 for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++) 63 { 64 CodecEntry = FDODeviceExtension->Codecs[CodecIndex]; 65 66 ASSERT(CodecEntry->AudioGroupCount <= HDA_MAX_AUDIO_GROUPS); 67 for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++) 68 { 69 ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(CodecEntry->AudioGroups[AFGIndex]->ChildPDO->DeviceExtension); 70 ChildDeviceExtension->ReportedMissing = TRUE; 71 } 72 } 73 Irp->IoStatus.Status = STATUS_SUCCESS; 74 break; 75 case IRP_MN_QUERY_REMOVE_DEVICE: 76 case IRP_MN_CANCEL_REMOVE_DEVICE: 77 Irp->IoStatus.Status = STATUS_SUCCESS; 78 break; 79 case IRP_MN_QUERY_DEVICE_RELATIONS: 80 /* handle bus device relations */ 81 if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations) 82 { 83 Status = HDA_FDOQueryBusRelations(DeviceObject, Irp); 84 Irp->IoStatus.Status = Status; 85 if (!NT_SUCCESS(Status)) 86 { 87 IoCompleteRequest(Irp, IO_NO_INCREMENT); 88 return Status; 89 } 90 } 91 break; 92 } 93 94 IoSkipCurrentIrpStackLocation(Irp); 95 return IoCallDriver(FDODeviceExtension->LowerDevice, Irp); 96 } 97 98 NTSTATUS 99 HDA_PdoPnp( 100 _In_ PDEVICE_OBJECT DeviceObject, 101 _Inout_ PIRP Irp) 102 { 103 NTSTATUS Status; 104 PIO_STACK_LOCATION IoStack; 105 PDEVICE_RELATIONS DeviceRelation; 106 107 IoStack = IoGetCurrentIrpStackLocation(Irp); 108 109 switch (IoStack->MinorFunction) 110 { 111 case IRP_MN_START_DEVICE: 112 /* no op for pdo */ 113 Status = STATUS_SUCCESS; 114 break; 115 case IRP_MN_REMOVE_DEVICE: 116 Status = HDA_PDORemoveDevice(DeviceObject); 117 break; 118 case IRP_MN_QUERY_REMOVE_DEVICE: 119 case IRP_MN_CANCEL_REMOVE_DEVICE: 120 Status = STATUS_SUCCESS; 121 break; 122 case IRP_MN_QUERY_BUS_INFORMATION: 123 /* query bus information */ 124 Status = HDA_PDOQueryBusInformation(Irp); 125 break; 126 case IRP_MN_QUERY_PNP_DEVICE_STATE: 127 /* query pnp state */ 128 Status = HDA_PDOQueryBusDevicePnpState(Irp); 129 break; 130 case IRP_MN_QUERY_DEVICE_RELATIONS: 131 if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) 132 { 133 /* handle target device relations */ 134 ASSERT(Irp->IoStatus.Information == 0); 135 136 /* allocate device relation */ 137 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS)); 138 if (DeviceRelation) 139 { 140 DeviceRelation->Count = 1; 141 DeviceRelation->Objects[0] = DeviceObject; 142 143 /* reference self */ 144 ObReferenceObject(DeviceObject); 145 146 /* store result */ 147 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation; 148 149 /* done */ 150 Status = STATUS_SUCCESS; 151 } 152 else 153 { 154 /* no memory */ 155 Status = STATUS_INSUFFICIENT_RESOURCES; 156 } 157 } 158 else 159 { 160 Status = Irp->IoStatus.Status; 161 } 162 break; 163 case IRP_MN_QUERY_CAPABILITIES: 164 /* query capabilities */ 165 Status = HDA_PDOQueryBusDeviceCapabilities(Irp); 166 break; 167 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 168 /* no op */ 169 Status = STATUS_SUCCESS; 170 break; 171 case IRP_MN_QUERY_RESOURCES: 172 /* no op */ 173 Status = STATUS_SUCCESS; 174 break; 175 case IRP_MN_QUERY_ID: 176 Status = HDA_PDOQueryId(DeviceObject, Irp); 177 break; 178 case IRP_MN_QUERY_DEVICE_TEXT: 179 Status = HDA_PDOHandleQueryDeviceText(Irp); 180 break; 181 case IRP_MN_QUERY_INTERFACE: 182 Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp); 183 break; 184 default: 185 /* get default status */ 186 Status = Irp->IoStatus.Status; 187 break; 188 } 189 190 Irp->IoStatus.Status = Status; 191 IoCompleteRequest(Irp, IO_NO_INCREMENT); 192 193 return Status; 194 } 195 196 NTSTATUS 197 NTAPI 198 HDA_Pnp( 199 _In_ PDEVICE_OBJECT DeviceObject, 200 _Inout_ PIRP Irp) 201 { 202 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 203 204 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 205 206 if (FDODeviceExtension->IsFDO) 207 { 208 return HDA_FdoPnp(DeviceObject, Irp); 209 } 210 else 211 { 212 return HDA_PdoPnp(DeviceObject, Irp); 213 } 214 } 215 216 NTSTATUS 217 NTAPI 218 HDA_SystemControl( 219 _In_ PDEVICE_OBJECT DeviceObject, 220 _Inout_ PIRP Irp) 221 { 222 NTSTATUS Status; 223 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 224 225 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 226 227 if (FDODeviceExtension->IsFDO) 228 { 229 IoSkipCurrentIrpStackLocation(Irp); 230 return IoCallDriver(FDODeviceExtension->LowerDevice, Irp); 231 } 232 else 233 { 234 Status = Irp->IoStatus.Status; 235 IoCompleteRequest(Irp, IO_NO_INCREMENT); 236 return Status; 237 } 238 } 239 240 NTSTATUS 241 NTAPI 242 HDA_Power( 243 _In_ PDEVICE_OBJECT DeviceObject, 244 _Inout_ PIRP Irp) 245 { 246 NTSTATUS Status; 247 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 248 249 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 250 251 if (FDODeviceExtension->IsFDO) 252 { 253 PoStartNextPowerIrp(Irp); 254 IoSkipCurrentIrpStackLocation(Irp); 255 return PoCallDriver(FDODeviceExtension->LowerDevice, Irp); 256 } 257 else 258 { 259 Status = Irp->IoStatus.Status; 260 PoStartNextPowerIrp(Irp); 261 IoCompleteRequest(Irp, IO_NO_INCREMENT); 262 return Status; 263 } 264 } 265 266 NTSTATUS 267 NTAPI 268 HDA_AddDevice( 269 _In_ PDRIVER_OBJECT DriverObject, 270 _In_ PDEVICE_OBJECT PhysicalDeviceObject) 271 { 272 PDEVICE_OBJECT DeviceObject; 273 PHDA_FDO_DEVICE_EXTENSION DeviceExtension; 274 NTSTATUS Status; 275 276 /* create device object */ 277 Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject); 278 if (!NT_SUCCESS(Status)) 279 { 280 /* failed */ 281 return Status; 282 } 283 284 /* get device extension*/ 285 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 286 287 /* init device extension*/ 288 DeviceExtension->IsFDO = TRUE; 289 DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); 290 IoInitializeDpcRequest(DeviceObject, HDA_DpcForIsr); 291 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1)); 292 293 /* set device flags */ 294 DeviceObject->Flags |= DO_POWER_PAGABLE; 295 296 return Status; 297 } 298 299 VOID 300 NTAPI 301 HDA_Unload( 302 _In_ PDRIVER_OBJECT DriverObject) 303 { 304 } 305 306 extern "C" 307 { 308 NTSTATUS 309 NTAPI 310 DriverEntry( 311 _In_ PDRIVER_OBJECT DriverObject, 312 _In_ PUNICODE_STRING RegistryPathName) 313 { 314 DriverObject->DriverUnload = HDA_Unload; 315 DriverObject->DriverExtension->AddDevice = HDA_AddDevice; 316 DriverObject->MajorFunction[IRP_MJ_POWER] = HDA_Power; 317 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HDA_SystemControl; 318 DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp; 319 320 return STATUS_SUCCESS; 321 } 322 323 } 324