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