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 9 #include "hdaudbus.h" 10 11 DRIVER_DISPATCH HDA_Pnp; 12 DRIVER_DISPATCH HDA_SystemControl; 13 DRIVER_DISPATCH HDA_Power; 14 DRIVER_ADD_DEVICE HDA_AddDevice; 15 DRIVER_UNLOAD HDA_Unload; 16 extern "C" DRIVER_INITIALIZE DriverEntry; 17 18 PVOID 19 AllocateItem( 20 _In_ POOL_TYPE PoolType, 21 _In_ SIZE_T NumberOfBytes) 22 { 23 return ExAllocatePoolZero(PoolType, NumberOfBytes, TAG_HDA); 24 } 25 26 VOID 27 FreeItem( 28 __drv_freesMem(Mem) PVOID Item) 29 { 30 ExFreePoolWithTag(Item, TAG_HDA); 31 } 32 33 NTSTATUS 34 HDA_FdoPnp( 35 _In_ PDEVICE_OBJECT DeviceObject, 36 _Inout_ PIRP Irp) 37 { 38 NTSTATUS Status; 39 PIO_STACK_LOCATION IoStack; 40 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 41 ULONG CodecIndex, AFGIndex; 42 PHDA_CODEC_ENTRY CodecEntry; 43 PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension; 44 45 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 46 IoStack = IoGetCurrentIrpStackLocation(Irp); 47 48 switch (IoStack->MinorFunction) 49 { 50 case IRP_MN_START_DEVICE: 51 Status = HDA_FDOStartDevice(DeviceObject, Irp); 52 Irp->IoStatus.Status = Status; 53 IoCompleteRequest(Irp, IO_NO_INCREMENT); 54 return Status; 55 case IRP_MN_REMOVE_DEVICE: 56 return HDA_FDORemoveDevice(DeviceObject, Irp); 57 case IRP_MN_SURPRISE_REMOVAL: 58 for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++) 59 { 60 CodecEntry = FDODeviceExtension->Codecs[CodecIndex]; 61 62 ASSERT(CodecEntry->AudioGroupCount <= HDA_MAX_AUDIO_GROUPS); 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(Irp->IoStatus.Information == 0); 131 132 /* allocate device relation */ 133 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS)); 134 if (DeviceRelation) 135 { 136 DeviceRelation->Count = 1; 137 DeviceRelation->Objects[0] = DeviceObject; 138 139 /* reference self */ 140 ObReferenceObject(DeviceObject); 141 142 /* store result */ 143 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation; 144 145 /* done */ 146 Status = STATUS_SUCCESS; 147 } 148 else 149 { 150 /* no memory */ 151 Status = STATUS_INSUFFICIENT_RESOURCES; 152 } 153 } 154 else 155 { 156 Status = Irp->IoStatus.Status; 157 } 158 break; 159 case IRP_MN_QUERY_CAPABILITIES: 160 /* query capabilities */ 161 Status = HDA_PDOQueryBusDeviceCapabilities(Irp); 162 break; 163 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 164 /* no op */ 165 Status = STATUS_SUCCESS; 166 break; 167 case IRP_MN_QUERY_RESOURCES: 168 /* no op */ 169 Status = STATUS_SUCCESS; 170 break; 171 case IRP_MN_QUERY_ID: 172 Status = HDA_PDOQueryId(DeviceObject, Irp); 173 break; 174 case IRP_MN_QUERY_DEVICE_TEXT: 175 Status = HDA_PDOHandleQueryDeviceText(Irp); 176 break; 177 case IRP_MN_QUERY_INTERFACE: 178 Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp); 179 break; 180 default: 181 /* get default status */ 182 Status = Irp->IoStatus.Status; 183 break; 184 } 185 186 Irp->IoStatus.Status = Status; 187 IoCompleteRequest(Irp, IO_NO_INCREMENT); 188 189 return Status; 190 } 191 192 NTSTATUS 193 NTAPI 194 HDA_Pnp( 195 _In_ PDEVICE_OBJECT DeviceObject, 196 _Inout_ PIRP Irp) 197 { 198 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 199 200 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 201 202 if (FDODeviceExtension->IsFDO) 203 { 204 return HDA_FdoPnp(DeviceObject, Irp); 205 } 206 else 207 { 208 return HDA_PdoPnp(DeviceObject, Irp); 209 } 210 } 211 212 NTSTATUS 213 NTAPI 214 HDA_SystemControl( 215 _In_ PDEVICE_OBJECT DeviceObject, 216 _Inout_ PIRP Irp) 217 { 218 NTSTATUS Status; 219 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 220 221 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 222 223 if (FDODeviceExtension->IsFDO) 224 { 225 IoSkipCurrentIrpStackLocation(Irp); 226 return IoCallDriver(FDODeviceExtension->LowerDevice, Irp); 227 } 228 else 229 { 230 Status = Irp->IoStatus.Status; 231 IoCompleteRequest(Irp, IO_NO_INCREMENT); 232 return Status; 233 } 234 } 235 236 NTSTATUS 237 NTAPI 238 HDA_Power( 239 _In_ PDEVICE_OBJECT DeviceObject, 240 _Inout_ PIRP Irp) 241 { 242 NTSTATUS Status; 243 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 244 245 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 246 247 if (FDODeviceExtension->IsFDO) 248 { 249 PoStartNextPowerIrp(Irp); 250 IoSkipCurrentIrpStackLocation(Irp); 251 return PoCallDriver(FDODeviceExtension->LowerDevice, Irp); 252 } 253 else 254 { 255 Status = Irp->IoStatus.Status; 256 PoStartNextPowerIrp(Irp); 257 IoCompleteRequest(Irp, IO_NO_INCREMENT); 258 return Status; 259 } 260 } 261 262 NTSTATUS 263 NTAPI 264 HDA_AddDevice( 265 _In_ PDRIVER_OBJECT DriverObject, 266 _In_ PDEVICE_OBJECT PhysicalDeviceObject) 267 { 268 PDEVICE_OBJECT DeviceObject; 269 PHDA_FDO_DEVICE_EXTENSION DeviceExtension; 270 NTSTATUS Status; 271 272 /* create device object */ 273 Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject); 274 if (!NT_SUCCESS(Status)) 275 { 276 /* failed */ 277 return Status; 278 } 279 280 /* get device extension*/ 281 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 282 283 /* init device extension*/ 284 DeviceExtension->IsFDO = TRUE; 285 DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); 286 IoInitializeDpcRequest(DeviceObject, HDA_DpcForIsr); 287 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1)); 288 289 /* set device flags */ 290 DeviceObject->Flags |= DO_POWER_PAGABLE; 291 292 return Status; 293 } 294 295 VOID 296 NTAPI 297 HDA_Unload( 298 _In_ PDRIVER_OBJECT DriverObject) 299 { 300 } 301 302 extern "C" 303 { 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 } // extern "C" 321