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 NTAPI 90 HDA_Pnp( 91 _In_ PDEVICE_OBJECT DeviceObject, 92 _Inout_ PIRP Irp) 93 { 94 NTSTATUS Status = STATUS_NOT_SUPPORTED; 95 PIO_STACK_LOCATION IoStack; 96 PDEVICE_RELATIONS DeviceRelation; 97 PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 98 //PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension; 99 100 FDODeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 101 //ChildDeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 102 103 IoStack = IoGetCurrentIrpStackLocation(Irp); 104 if (FDODeviceExtension->IsFDO) 105 { 106 if (IoStack->MinorFunction == IRP_MN_START_DEVICE) 107 { 108 Status = HDA_FDOStartDevice(DeviceObject, Irp); 109 } 110 else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS) 111 { 112 /* handle bus device relations */ 113 if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations) 114 { 115 Status = HDA_FDOQueryBusRelations(DeviceObject, Irp); 116 } 117 else 118 { 119 Status = Irp->IoStatus.Status; 120 } 121 } 122 else 123 { 124 /* get default status */ 125 Status = Irp->IoStatus.Status; 126 } 127 } 128 else 129 { 130 if (IoStack->MinorFunction == IRP_MN_START_DEVICE) 131 { 132 /* no op for pdo */ 133 Status = STATUS_SUCCESS; 134 } 135 else if (IoStack->MinorFunction == IRP_MN_QUERY_BUS_INFORMATION) 136 { 137 /* query bus information */ 138 Status = HDA_PDOQueryBusInformation(Irp); 139 } 140 else if (IoStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE) 141 { 142 /* query pnp state */ 143 Status = HDA_PDOQueryBusDevicePnpState(Irp); 144 } 145 else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS) 146 { 147 if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) 148 { 149 /* handle target device relations */ 150 ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation); 151 ASSERT(Irp->IoStatus.Information == 0); 152 153 /* allocate device relation */ 154 DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS)); 155 if (DeviceRelation) 156 { 157 DeviceRelation->Count = 1; 158 DeviceRelation->Objects[0] = DeviceObject; 159 160 /* reference self */ 161 ObReferenceObject(DeviceObject); 162 163 /* store result */ 164 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation; 165 166 /* done */ 167 Status = STATUS_SUCCESS; 168 } 169 else 170 { 171 /* no memory */ 172 Status = STATUS_INSUFFICIENT_RESOURCES; 173 } 174 } 175 } 176 else if (IoStack->MinorFunction == IRP_MN_QUERY_CAPABILITIES) 177 { 178 /* query capabilities */ 179 Status = HDA_PDOQueryBusDeviceCapabilities(Irp); 180 } 181 else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCE_REQUIREMENTS) 182 { 183 /* no op */ 184 Status = STATUS_SUCCESS; 185 } 186 else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCES) 187 { 188 /* no op */ 189 Status = STATUS_SUCCESS; 190 } 191 else if (IoStack->MinorFunction == IRP_MN_QUERY_ID) 192 { 193 Status = HDA_PDOQueryId(DeviceObject, Irp); 194 } 195 else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_TEXT) 196 { 197 Status = HDA_PDOHandleQueryDeviceText(Irp); 198 } 199 else if (IoStack->MinorFunction == IRP_MN_QUERY_INTERFACE) 200 { 201 Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp); 202 } 203 else 204 { 205 /* get default status */ 206 Status = Irp->IoStatus.Status; 207 } 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_AddDevice( 219 _In_ PDRIVER_OBJECT DriverObject, 220 _In_ PDEVICE_OBJECT PhysicalDeviceObject) 221 { 222 PDEVICE_OBJECT DeviceObject; 223 PHDA_FDO_DEVICE_EXTENSION DeviceExtension; 224 NTSTATUS Status; 225 226 /* create device object */ 227 Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject); 228 if (!NT_SUCCESS(Status)) 229 { 230 /* failed */ 231 return Status; 232 } 233 234 /* get device extension*/ 235 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 236 237 /* init device extension*/ 238 DeviceExtension->IsFDO = TRUE; 239 DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); 240 RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1)); 241 242 /* set device flags */ 243 DeviceObject->Flags |= DO_POWER_PAGABLE; 244 245 return Status; 246 } 247 extern "C" 248 { 249 NTSTATUS 250 NTAPI 251 DriverEntry( 252 _In_ PDRIVER_OBJECT DriverObject, 253 _In_ PUNICODE_STRING RegistryPathName) 254 { 255 DriverObject->DriverExtension->AddDevice = HDA_AddDevice; 256 DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp; 257 258 return STATUS_SUCCESS; 259 } 260 261 } 262