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 NTAPI 36 HDA_SyncForwardIrpCompletionRoutine( 37 IN PDEVICE_OBJECT DeviceObject, 38 IN PIRP Irp, 39 IN PVOID Context) 40 { 41 if (Irp->PendingReturned) 42 { 43 KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); 44 } 45 return STATUS_MORE_PROCESSING_REQUIRED; 46 } 47 48 NTSTATUS 49 NTAPI 50 HDA_SyncForwardIrp( 51 IN PDEVICE_OBJECT DeviceObject, 52 IN PIRP Irp) 53 { 54 KEVENT Event; 55 NTSTATUS Status; 56 57 /* Initialize event */ 58 KeInitializeEvent(&Event, NotificationEvent, FALSE); 59 60 /* Copy irp stack location */ 61 IoCopyCurrentIrpStackLocationToNext(Irp); 62 63 /* Set completion routine */ 64 IoSetCompletionRoutine(Irp, 65 HDA_SyncForwardIrpCompletionRoutine, 66 &Event, 67 TRUE, 68 TRUE, 69 TRUE); 70 71 /* Call driver */ 72 Status = IoCallDriver(DeviceObject, Irp); 73 74 /* Check if pending */ 75 if (Status == STATUS_PENDING) 76 { 77 /* Wait for the request to finish */ 78 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 79 80 /* Copy status code */ 81 Status = Irp->IoStatus.Status; 82 } 83 84 /* Done */ 85 return Status; 86 } 87 88 NTSTATUS 89 HDA_FdoPnp( 90 _In_ PDEVICE_OBJECT DeviceObject, 91 _Inout_ PIRP Irp) 92 { 93 NTSTATUS Status; 94 PIO_STACK_LOCATION IoStack; 95 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 96 97 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 98 IoStack = IoGetCurrentIrpStackLocation(Irp); 99 100 switch (IoStack->MinorFunction) 101 { 102 case IRP_MN_START_DEVICE: 103 Status = HDA_FDOStartDevice(DeviceObject, Irp); 104 break; 105 case IRP_MN_QUERY_DEVICE_RELATIONS: 106 /* handle bus device relations */ 107 if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations) 108 { 109 Status = HDA_FDOQueryBusRelations(DeviceObject, Irp); 110 } 111 else 112 { 113 Status = Irp->IoStatus.Status; 114 } 115 break; 116 default: 117 /* get default status */ 118 Status = Irp->IoStatus.Status; 119 break; 120 } 121 122 Irp->IoStatus.Status = Status; 123 IoCompleteRequest(Irp, IO_NO_INCREMENT); 124 125 return Status; 126 } 127 128 NTSTATUS 129 HDA_PdoPnp( 130 _In_ PDEVICE_OBJECT DeviceObject, 131 _Inout_ PIRP Irp) 132 { 133 NTSTATUS Status; 134 PIO_STACK_LOCATION IoStack; 135 PDEVICE_RELATIONS DeviceRelation; 136 137 IoStack = IoGetCurrentIrpStackLocation(Irp); 138 139 switch (IoStack->MinorFunction) 140 { 141 case IRP_MN_START_DEVICE: 142 /* no op for pdo */ 143 Status = STATUS_SUCCESS; 144 break; 145 case IRP_MN_QUERY_BUS_INFORMATION: 146 /* query bus information */ 147 Status = HDA_PDOQueryBusInformation(Irp); 148 break; 149 case IRP_MN_QUERY_PNP_DEVICE_STATE: 150 /* query pnp state */ 151 Status = HDA_PDOQueryBusDevicePnpState(Irp); 152 break; 153 case IRP_MN_QUERY_DEVICE_RELATIONS: 154 if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) 155 { 156 /* handle target device relations */ 157 ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation); 158 ASSERT(Irp->IoStatus.Information == 0); 159 160 /* allocate device relation */ 161 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS)); 162 if (DeviceRelation) 163 { 164 DeviceRelation->Count = 1; 165 DeviceRelation->Objects[0] = DeviceObject; 166 167 /* reference self */ 168 ObReferenceObject(DeviceObject); 169 170 /* store result */ 171 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation; 172 173 /* done */ 174 Status = STATUS_SUCCESS; 175 } 176 else 177 { 178 /* no memory */ 179 Status = STATUS_INSUFFICIENT_RESOURCES; 180 } 181 } 182 break; 183 case IRP_MN_QUERY_CAPABILITIES: 184 /* query capabilities */ 185 Status = HDA_PDOQueryBusDeviceCapabilities(Irp); 186 break; 187 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 188 /* no op */ 189 Status = STATUS_SUCCESS; 190 break; 191 case IRP_MN_QUERY_RESOURCES: 192 /* no op */ 193 Status = STATUS_SUCCESS; 194 break; 195 case IRP_MN_QUERY_ID: 196 Status = HDA_PDOQueryId(DeviceObject, Irp); 197 break; 198 case IRP_MN_QUERY_DEVICE_TEXT: 199 Status = HDA_PDOHandleQueryDeviceText(Irp); 200 break; 201 case IRP_MN_QUERY_INTERFACE: 202 Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp); 203 break; 204 default: 205 /* get default status */ 206 Status = Irp->IoStatus.Status; 207 break; 208 } 209 210 Irp->IoStatus.Status = Status; 211 IoCompleteRequest(Irp, IO_NO_INCREMENT); 212 213 return Status; 214 } 215 216 NTSTATUS 217 NTAPI 218 HDA_Pnp( 219 _In_ PDEVICE_OBJECT DeviceObject, 220 _Inout_ PIRP Irp) 221 { 222 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 223 224 FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); 225 226 if (FDODeviceExtension->IsFDO) 227 { 228 return HDA_FdoPnp(DeviceObject, Irp); 229 } 230 else 231 { 232 return HDA_PdoPnp(DeviceObject, Irp); 233 } 234 } 235 236 237 NTSTATUS 238 NTAPI 239 HDA_AddDevice( 240 _In_ PDRIVER_OBJECT DriverObject, 241 _In_ PDEVICE_OBJECT PhysicalDeviceObject) 242 { 243 PDEVICE_OBJECT DeviceObject; 244 PHDA_FDO_DEVICE_EXTENSION DeviceExtension; 245 NTSTATUS Status; 246 247 /* create device object */ 248 Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject); 249 if (!NT_SUCCESS(Status)) 250 { 251 /* failed */ 252 return Status; 253 } 254 255 /* get device extension*/ 256 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 257 258 /* init device extension*/ 259 DeviceExtension->IsFDO = TRUE; 260 DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); 261 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1)); 262 263 /* set device flags */ 264 DeviceObject->Flags |= DO_POWER_PAGABLE; 265 266 return Status; 267 } 268 extern "C" 269 { 270 NTSTATUS 271 NTAPI 272 DriverEntry( 273 _In_ PDRIVER_OBJECT DriverObject, 274 _In_ PUNICODE_STRING RegistryPathName) 275 { 276 DriverObject->DriverExtension->AddDevice = HDA_AddDevice; 277 DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp; 278 279 return STATUS_SUCCESS; 280 } 281 282 } 283