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