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(IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation); 135 ASSERT(Irp->IoStatus.Information == 0); 136 137 /* allocate device relation */ 138 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS)); 139 if (DeviceRelation) 140 { 141 DeviceRelation->Count = 1; 142 DeviceRelation->Objects[0] = DeviceObject; 143 144 /* reference self */ 145 ObReferenceObject(DeviceObject); 146 147 /* store result */ 148 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation; 149 150 /* done */ 151 Status = STATUS_SUCCESS; 152 } 153 else 154 { 155 /* no memory */ 156 Status = STATUS_INSUFFICIENT_RESOURCES; 157 } 158 } 159 break; 160 case IRP_MN_QUERY_CAPABILITIES: 161 /* query capabilities */ 162 Status = HDA_PDOQueryBusDeviceCapabilities(Irp); 163 break; 164 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 165 /* no op */ 166 Status = STATUS_SUCCESS; 167 break; 168 case IRP_MN_QUERY_RESOURCES: 169 /* no op */ 170 Status = STATUS_SUCCESS; 171 break; 172 case IRP_MN_QUERY_ID: 173 Status = HDA_PDOQueryId(DeviceObject, Irp); 174 break; 175 case IRP_MN_QUERY_DEVICE_TEXT: 176 Status = HDA_PDOHandleQueryDeviceText(Irp); 177 break; 178 case IRP_MN_QUERY_INTERFACE: 179 Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp); 180 break; 181 default: 182 /* get default status */ 183 Status = Irp->IoStatus.Status; 184 break; 185 } 186 187 Irp->IoStatus.Status = Status; 188 IoCompleteRequest(Irp, IO_NO_INCREMENT); 189 190 return Status; 191 } 192 193 NTSTATUS 194 NTAPI 195 HDA_Pnp( 196 _In_ PDEVICE_OBJECT DeviceObject, 197 _Inout_ PIRP Irp) 198 { 199 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 200 201 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 202 203 if (FDODeviceExtension->IsFDO) 204 { 205 return HDA_FdoPnp(DeviceObject, Irp); 206 } 207 else 208 { 209 return HDA_PdoPnp(DeviceObject, Irp); 210 } 211 } 212 213 NTSTATUS 214 NTAPI 215 HDA_SystemControl( 216 _In_ PDEVICE_OBJECT DeviceObject, 217 _Inout_ PIRP Irp) 218 { 219 NTSTATUS Status; 220 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 221 222 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 223 224 if (FDODeviceExtension->IsFDO) 225 { 226 IoSkipCurrentIrpStackLocation(Irp); 227 return IoCallDriver(FDODeviceExtension->LowerDevice, Irp); 228 } 229 else 230 { 231 Status = Irp->IoStatus.Status; 232 IoCompleteRequest(Irp, IO_NO_INCREMENT); 233 return Status; 234 } 235 } 236 237 NTSTATUS 238 NTAPI 239 HDA_Power( 240 _In_ PDEVICE_OBJECT DeviceObject, 241 _Inout_ PIRP Irp) 242 { 243 NTSTATUS Status; 244 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 245 246 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 247 248 if (FDODeviceExtension->IsFDO) 249 { 250 PoStartNextPowerIrp(Irp); 251 IoSkipCurrentIrpStackLocation(Irp); 252 return PoCallDriver(FDODeviceExtension->LowerDevice, Irp); 253 } 254 else 255 { 256 Status = Irp->IoStatus.Status; 257 PoStartNextPowerIrp(Irp); 258 IoCompleteRequest(Irp, IO_NO_INCREMENT); 259 return Status; 260 } 261 } 262 263 NTSTATUS 264 NTAPI 265 HDA_AddDevice( 266 _In_ PDRIVER_OBJECT DriverObject, 267 _In_ PDEVICE_OBJECT PhysicalDeviceObject) 268 { 269 PDEVICE_OBJECT DeviceObject; 270 PHDA_FDO_DEVICE_EXTENSION DeviceExtension; 271 NTSTATUS Status; 272 273 /* create device object */ 274 Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject); 275 if (!NT_SUCCESS(Status)) 276 { 277 /* failed */ 278 return Status; 279 } 280 281 /* get device extension*/ 282 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 283 284 /* init device extension*/ 285 DeviceExtension->IsFDO = TRUE; 286 DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); 287 IoInitializeDpcRequest(DeviceObject, HDA_DpcForIsr); 288 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1)); 289 290 /* set device flags */ 291 DeviceObject->Flags |= DO_POWER_PAGABLE; 292 293 return Status; 294 } 295 296 VOID 297 NTAPI 298 HDA_Unload( 299 _In_ PDRIVER_OBJECT DriverObject) 300 { 301 } 302 303 extern "C" 304 { 305 NTSTATUS 306 NTAPI 307 DriverEntry( 308 _In_ PDRIVER_OBJECT DriverObject, 309 _In_ PUNICODE_STRING RegistryPathName) 310 { 311 DriverObject->DriverUnload = HDA_Unload; 312 DriverObject->DriverExtension->AddDevice = HDA_AddDevice; 313 DriverObject->MajorFunction[IRP_MJ_POWER] = HDA_Power; 314 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HDA_SystemControl; 315 DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp; 316 317 return STATUS_SUCCESS; 318 } 319 320 } 321