1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Kernel Streaming 4 * FILE: drivers/wdm/audio/backpln/portcls/api.cpp 5 * PURPOSE: Port api functions 6 * PROGRAMMER: Johannes Anderwald 7 */ 8 9 #include "private.hpp" 10 11 #ifndef YDEBUG 12 #define NDEBUG 13 #endif 14 15 #include <debug.h> 16 17 NTSTATUS 18 NTAPI 19 PcGetDeviceProperty( 20 IN PVOID DeviceObject, 21 IN DEVICE_REGISTRY_PROPERTY DeviceProperty, 22 IN ULONG BufferLength, 23 OUT PVOID PropertyBuffer, 24 OUT PULONG ResultLength) 25 { 26 PPCLASS_DEVICE_EXTENSION DeviceExtension; 27 28 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 29 30 DeviceExtension = (PPCLASS_DEVICE_EXTENSION)((PDEVICE_OBJECT)DeviceObject)->DeviceExtension; 31 32 return IoGetDeviceProperty(DeviceExtension->PhysicalDeviceObject, DeviceProperty, BufferLength, PropertyBuffer, ResultLength); 33 } 34 35 ULONGLONG 36 NTAPI 37 PcGetTimeInterval( 38 IN ULONGLONG Since) 39 { 40 LARGE_INTEGER CurrentTime; 41 42 KeQuerySystemTime(&CurrentTime); 43 44 return (CurrentTime.QuadPart - Since); 45 } 46 47 VOID 48 NTAPI 49 PcIoTimerRoutine( 50 IN PDEVICE_OBJECT DeviceObject, 51 IN PVOID Context) 52 { 53 PPCLASS_DEVICE_EXTENSION DeviceExtension; 54 KIRQL OldIrql; 55 PLIST_ENTRY ListEntry; 56 PTIMER_CONTEXT CurContext; 57 58 if (!DeviceObject || !DeviceObject->DeviceExtension) 59 return; 60 61 DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 62 63 KeAcquireSpinLock(&DeviceExtension->TimerListLock, &OldIrql); 64 65 ListEntry = DeviceExtension->TimerList.Flink; 66 while(ListEntry != &DeviceExtension->TimerList) 67 { 68 CurContext = (PTIMER_CONTEXT)CONTAINING_RECORD(ListEntry, TIMER_CONTEXT, Entry); 69 70 CurContext->pTimerRoutine(DeviceObject, CurContext->Context); 71 ListEntry = ListEntry->Flink; 72 } 73 74 KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql); 75 } 76 77 NTSTATUS 78 NTAPI 79 PcRegisterIoTimeout( 80 IN PDEVICE_OBJECT pDeviceObject, 81 IN PIO_TIMER_ROUTINE pTimerRoutine, 82 IN PVOID pContext) 83 { 84 NTSTATUS Status = STATUS_SUCCESS; 85 PTIMER_CONTEXT TimerContext, CurContext; 86 KIRQL OldIrql; 87 PLIST_ENTRY ListEntry; 88 BOOLEAN bFound; 89 PPCLASS_DEVICE_EXTENSION DeviceExtension; 90 91 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 92 93 if (!pDeviceObject || !pDeviceObject->DeviceExtension) 94 return STATUS_INVALID_PARAMETER; 95 96 DeviceExtension = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension; 97 98 TimerContext = (PTIMER_CONTEXT)AllocateItem(NonPagedPool, sizeof(TIMER_CONTEXT), TAG_PORTCLASS); 99 if (!TimerContext) 100 { 101 DPRINT("Failed to allocate memory\n"); 102 return STATUS_INSUFFICIENT_RESOURCES; 103 } 104 105 KeAcquireSpinLock(&DeviceExtension->TimerListLock, &OldIrql); 106 107 ListEntry = DeviceExtension->TimerList.Flink; 108 bFound = FALSE; 109 while(ListEntry != &DeviceExtension->TimerList) 110 { 111 CurContext = (PTIMER_CONTEXT)CONTAINING_RECORD(ListEntry, TIMER_CONTEXT, Entry); 112 113 if (CurContext->Context == pContext && CurContext->pTimerRoutine == pTimerRoutine) 114 { 115 bFound = TRUE; 116 Status = STATUS_UNSUCCESSFUL; 117 FreeItem(TimerContext, TAG_PORTCLASS); 118 break; 119 } 120 ListEntry = ListEntry->Flink; 121 } 122 123 if (!bFound) 124 { 125 TimerContext->Context = pContext; 126 TimerContext->pTimerRoutine = pTimerRoutine; 127 InsertTailList(&DeviceExtension->TimerList, &TimerContext->Entry); 128 } 129 130 KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql); 131 132 return Status; 133 } 134 135 NTSTATUS 136 NTAPI 137 PcUnregisterIoTimeout( 138 IN PDEVICE_OBJECT pDeviceObject, 139 IN PIO_TIMER_ROUTINE pTimerRoutine, 140 IN PVOID pContext) 141 { 142 PTIMER_CONTEXT CurContext; 143 KIRQL OldIrql; 144 PLIST_ENTRY ListEntry; 145 BOOLEAN bFound; 146 PPCLASS_DEVICE_EXTENSION DeviceExtension; 147 148 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 149 150 if (!pDeviceObject || !pDeviceObject->DeviceExtension) 151 return STATUS_INVALID_PARAMETER; 152 153 154 DeviceExtension = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension; 155 156 157 KeAcquireSpinLock(&DeviceExtension->TimerListLock, &OldIrql); 158 159 ListEntry = DeviceExtension->TimerList.Flink; 160 bFound = FALSE; 161 162 while(ListEntry != &DeviceExtension->TimerList) 163 { 164 CurContext = (PTIMER_CONTEXT)CONTAINING_RECORD(ListEntry, TIMER_CONTEXT, Entry); 165 166 if (CurContext->Context == pContext && CurContext->pTimerRoutine == pTimerRoutine) 167 { 168 bFound = TRUE; 169 RemoveEntryList(&CurContext->Entry); 170 FreeItem(CurContext, TAG_PORTCLASS); 171 break; 172 } 173 ListEntry = ListEntry->Flink; 174 } 175 176 KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql); 177 178 if (bFound) 179 return STATUS_SUCCESS; 180 else 181 return STATUS_NOT_FOUND; 182 } 183 184 185 186 NTSTATUS 187 NTAPI 188 PcCompletePendingPropertyRequest( 189 IN PPCPROPERTY_REQUEST PropertyRequest, 190 IN NTSTATUS NtStatus) 191 { 192 // sanity checks 193 PC_ASSERT_IRQL(DISPATCH_LEVEL); 194 195 if (!PropertyRequest || !PropertyRequest->Irp || NtStatus == STATUS_PENDING) 196 return STATUS_INVALID_PARAMETER; 197 198 // set the final status code 199 PropertyRequest->Irp->IoStatus.Status = NtStatus; 200 201 // complete the irp 202 IoCompleteRequest(PropertyRequest->Irp, IO_SOUND_INCREMENT); 203 204 // free the property request 205 FreeItem(PropertyRequest, TAG_PORTCLASS); 206 207 // return success 208 return STATUS_SUCCESS; 209 } 210 211 NTSTATUS 212 NTAPI 213 PcDmaMasterDescription( 214 IN PRESOURCELIST ResourceList OPTIONAL, 215 IN BOOLEAN ScatterGather, 216 IN BOOLEAN Dma32BitAddresses, 217 IN BOOLEAN IgnoreCount, 218 IN BOOLEAN Dma64BitAddresses, 219 IN DMA_WIDTH DmaWidth, 220 IN DMA_SPEED DmaSpeed, 221 IN ULONG MaximumLength, 222 IN ULONG DmaPort, 223 OUT PDEVICE_DESCRIPTION DeviceDescription) 224 { 225 226 RtlZeroMemory(DeviceDescription, sizeof(DEVICE_DESCRIPTION)); 227 228 DeviceDescription->Master = TRUE; 229 DeviceDescription->Version = DEVICE_DESCRIPTION_VERSION1; 230 DeviceDescription->ScatterGather= ScatterGather; 231 DeviceDescription->Dma32BitAddresses = Dma32BitAddresses; 232 DeviceDescription->IgnoreCount = IgnoreCount; 233 DeviceDescription->Dma64BitAddresses = Dma64BitAddresses; 234 DeviceDescription->DmaWidth = DmaWidth; 235 DeviceDescription->DmaSpeed = DmaSpeed; 236 DeviceDescription->MaximumLength = MaximumLength; 237 DeviceDescription->DmaPort = DmaPort; 238 239 return STATUS_SUCCESS; 240 } 241 242 NTSTATUS 243 NTAPI 244 PcDmaSlaveDescription( 245 IN PRESOURCELIST ResourceList OPTIONAL, 246 IN ULONG DmaIndex, 247 IN BOOLEAN DemandMode, 248 IN BOOLEAN AutoInitialize, 249 IN DMA_SPEED DmaSpeed, 250 IN ULONG MaximumLength, 251 IN ULONG DmaPort, 252 OUT PDEVICE_DESCRIPTION DeviceDescription) 253 { 254 255 RtlZeroMemory(DeviceDescription, sizeof(DEVICE_DESCRIPTION)); 256 257 DeviceDescription->Version = DEVICE_DESCRIPTION_VERSION1; 258 DeviceDescription->DemandMode = DemandMode; 259 DeviceDescription->AutoInitialize = AutoInitialize; 260 DeviceDescription->DmaSpeed = DmaSpeed; 261 DeviceDescription->MaximumLength = MaximumLength; 262 DeviceDescription->DmaPort = DmaPort; 263 264 return STATUS_SUCCESS; 265 } 266 267