ReactOS 0.4.15-dev-7906-g1b85a5f
dma_slave.cpp
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/dma_init.c
5 * PURPOSE: portcls dma support object
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9#include "private.hpp"
10
11#define NDEBUG
12#include <debug.h>
13
14class CDmaChannelInit : public CUnknownImpl<IDmaChannelInit>
15{
16public:
17 inline
18 PVOID
19 operator new(
20 size_t Size,
22 ULONG Tag)
23 {
25 }
26
28
30 CDmaChannelInit(IUnknown * OuterUnknown) :
31 m_pDeviceObject(nullptr),
32 m_pAdapter(nullptr),
34 m_MapSize(0),
35 m_MapRegisterBase(nullptr),
40 m_BufferSize(0),
41 m_Address({0}),
42 m_Buffer(nullptr),
43 m_Mdl(nullptr),
45 {
46 }
47 virtual ~CDmaChannelInit(){}
48
49protected:
50
53
55
58
60
65
70
72};
73
74//---------------------------------------------------------------
75// IUnknown methods
76//
77
79
83 IN REFIID refiid,
85{
86 if (IsEqualGUIDAligned(refiid, IID_IUnknown) ||
87 IsEqualGUIDAligned(refiid, IID_IDmaChannel))
88 //IsEqualGUIDAligned(refiid, IID_IDmaChannelSlave)) // HACK
89 {
90 *Output = PVOID(PUNKNOWN(this));
91 PUNKNOWN(*Output)->AddRef();
92 return STATUS_SUCCESS;
93 }
94 DPRINT("No interface!!!\n");
96}
97
98//---------------------------------------------------------------
99// IDmaChannel methods
100//
101
103NTAPI
104CDmaChannelInit::AllocateBuffer(
106 IN PPHYSICAL_ADDRESS PhysicalAddressConstraint OPTIONAL)
107{
109
110 // Did the caller already allocate a buffer ?*/
111 if (m_Buffer)
112 {
113 DPRINT("CDmaChannelInit_AllocateBuffer free common buffer first \n");
114 return STATUS_UNSUCCESSFUL;
115 }
116
118 if (!m_Buffer)
119 {
120 DPRINT("CDmaChannelInit_AllocateBuffer fAllocateCommonBuffer failed \n");
121 return STATUS_UNSUCCESSFUL;
122 }
123
126 DPRINT("CDmaChannelInit::AllocateBuffer Success Buffer %p BufferSize %u Address %x\n", m_Buffer, BufferSize, m_Address);
127
128 return STATUS_SUCCESS;
129}
130
131ULONG
132NTAPI
133CDmaChannelInit::AllocatedBufferSize()
134{
135 DPRINT("CDmaChannelInit_AllocatedBufferSize: this %p BufferSize %u\n", this, m_BufferSize);
137}
138
139VOID
140NTAPI
141CDmaChannelInit::CopyFrom(
145 )
146{
147 DPRINT("CDmaChannelInit_CopyFrom: this %p Destination %p Source %p ByteCount %u\n", this, Destination, Source, ByteCount);
148
149 CopyTo(Destination, Source, ByteCount);
150}
151
152VOID
153NTAPI
154CDmaChannelInit::CopyTo(
158 )
159{
160 DPRINT("CDmaChannelInit_CopyTo: this %p Destination %p Source %p ByteCount %u\n", this, Destination, Source, ByteCount);
162}
163
164VOID
165NTAPI
166CDmaChannelInit::FreeBuffer()
167{
168 DPRINT("CDmaChannelInit_FreeBuffer: this %p\n", this);
169
171
172 if (!m_Buffer)
173 {
174 DPRINT("CDmaChannelInit_FreeBuffer allocate common buffer first \n");
175 return;
176 }
177
179 m_Buffer = NULL;
182
183 if (m_Mdl)
184 {
186 m_Mdl = NULL;
187 }
188}
189
191NTAPI
192CDmaChannelInit::GetAdapterObject()
193{
194 DPRINT("CDmaChannelInit_GetAdapterObject: this %p\n", this);
196}
197
198ULONG
199NTAPI
200CDmaChannelInit::MaximumBufferSize()
201{
202 DPRINT("CDmaChannelInit_MaximumBufferSize: this %p\n", this);
203 return m_MaximumBufferSize;
204}
205
206#ifdef _MSC_VER
207
209NTAPI
210CDmaChannelInit::PhysicalAddress()
211{
212 DPRINT("CDmaChannelInit_PhysicalAddress: this %p Virtual %p Physical High %x Low %x%\n", this, m_Buffer, m_Address.HighPart, m_Address.LowPart);
213
214 return m_Address;
215}
216
217#else
218
220NTAPI
221CDmaChannelInit::PhysicalAddress(
223{
224 DPRINT("CDmaChannelInit_PhysicalAddress: this %p Virtual %p Physical High %x Low %x%\n", this, m_Buffer, m_Address.HighPart, m_Address.LowPart);
225
227
228 Address->QuadPart = m_Address.QuadPart;
229 Result.QuadPart = (ULONG_PTR)Address;
230 return Result;
231}
232
233#endif
234
235VOID
236NTAPI
237CDmaChannelInit::SetBufferSize(
239{
240 DPRINT("CDmaChannelInit_SetBufferSize: this %p\n", this);
242
243}
244
245ULONG
246NTAPI
247CDmaChannelInit::BufferSize()
248{
249 DPRINT("BufferSize %u\n", m_BufferSize);
251 return m_BufferSize;
252}
253
254PVOID
255NTAPI
256CDmaChannelInit::SystemAddress()
257{
258 DPRINT("CDmaChannelInit_SystemAddress: this %p\n", this);
259 return m_Buffer;
260}
261
262ULONG
263NTAPI
264CDmaChannelInit::TransferCount()
265{
266 DPRINT("CDmaChannelInit_TransferCount: this %p\n", this);
267 return m_LastTransferCount;
268}
269
270ULONG
271NTAPI
272CDmaChannelInit::ReadCounter()
273{
275
277
278 Counter = m_pAdapter->DmaOperations->ReadDmaCounter(m_pAdapter);
279
281 Counter = 0;
282
283 DPRINT("ReadCounter %u\n", Counter);
284
285 return Counter;
286}
287
289NTAPI
292 IN PIRP Irp,
295{
298
299 Length = This->m_MapSize;
300 This->m_MapRegisterBase = MapRegisterBase;
301
302 This->m_pAdapter->DmaOperations->MapTransfer(This->m_pAdapter,
303 This->m_Mdl,
305 (PVOID)((ULONG_PTR)This->m_Mdl->StartVa + This->m_Mdl->ByteOffset),
306 &Length,
307 This->m_WriteToDevice);
308
309 if (Length == This->m_BufferSize)
310 {
311 This->m_DmaStarted = TRUE;
312 }
313
314 return KeepObject;
315}
316
318NTAPI
319CDmaChannelInit::Start(
320 ULONG MapSize,
322{
324 ULONG MapRegisters;
326
327 DPRINT("CDmaChannelInit_Start: this %p\n", this);
328
330
331 if (m_DmaStarted)
332 return STATUS_UNSUCCESSFUL;
333
334 if (!m_Mdl)
335 {
337 if (!m_Mdl)
338 {
340 }
342 }
343
344 m_MapSize = MapSize;
346 m_LastTransferCount = MapSize;
347
348 //FIXME
349 // synchronize access
350 //
352
353 MapRegisters = ADDRESS_AND_SIZE_TO_SPAN_PAGES(m_Buffer, MapSize);
354 Status = m_pAdapter->DmaOperations->AllocateAdapterChannel(m_pAdapter, m_pDeviceObject, MapRegisters, AdapterControl, (PVOID)this);
356
357 if(!NT_SUCCESS(Status))
359
360 return Status;
361}
362
364NTAPI
365CDmaChannelInit::Stop()
366{
368
369 DPRINT("CDmaChannelInit::Stop: this %p\n", this);
371
372 if (!m_DmaStarted)
373 return STATUS_SUCCESS;
374
375 m_pAdapter->DmaOperations->FlushAdapterBuffers(m_pAdapter,
376 m_Mdl,
378 (PVOID)((ULONG_PTR)m_Mdl->StartVa + m_Mdl->ByteOffset),
379 m_MapSize,
381
383
384 m_pAdapter->DmaOperations->FreeAdapterChannel(m_pAdapter);
385
387
389
391 m_Mdl = NULL;
392
393 return STATUS_SUCCESS;
394}
395
397NTAPI
398CDmaChannelInit::WaitForTC(
400{
401 ULONG RetryCount;
402 ULONG BytesRemaining;
403 ULONG PrevBytesRemaining;
404
406
407 BytesRemaining = m_pAdapter->DmaOperations->ReadDmaCounter(m_pAdapter);
408 if (!BytesRemaining)
409 {
410 return STATUS_SUCCESS;
411 }
412
413 RetryCount = Timeout / 10;
414 PrevBytesRemaining = 0xFFFFFFFF;
415 do
416 {
417 BytesRemaining = m_pAdapter->DmaOperations->ReadDmaCounter(m_pAdapter);
418
419 if (!BytesRemaining)
420 break;
421
422 if (PrevBytesRemaining == BytesRemaining)
423 break;
424
426 PrevBytesRemaining = BytesRemaining;
427
428 }while(RetryCount-- >= 1);
429
430 if (BytesRemaining)
431 {
432 return STATUS_UNSUCCESSFUL;
433 }
434
435 return STATUS_SUCCESS;
436
437}
438
440NTAPI
441CDmaChannelInit::Init(
444{
447 PDMA_ADAPTER Adapter;
448 PPCLASS_DEVICE_EXTENSION DeviceExt;
449 ULONG MapRegisters;
451
452 // Get bus type
454 if (NT_SUCCESS(Status))
455 {
456 DeviceDescription->InterfaceType = BusType;
457 }
458 // Fetch device extension
459 DeviceExt = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
460 // Acquire dma adapter
461 Adapter = IoGetDmaAdapter(DeviceExt->PhysicalDeviceObject, DeviceDescription, &MapRegisters);
462 if (!Adapter)
463 {
464 FreeItem(this, TAG_PORTCLASS);
466 }
467
468 // initialize object
469 m_pAdapter = Adapter;
471 m_MaximumBufferSize = DeviceDescription->MaximumLength;
472 m_MaxMapRegisters = MapRegisters;
473
474 return STATUS_SUCCESS;
475}
476
478NTAPI
480 OUT PDMACHANNEL* OutDmaChannel,
481 IN PUNKNOWN OuterUnknown OPTIONAL,
485{
488
489 DPRINT("OutDmaChannel %p OuterUnknown %p PoolType %p DeviceDescription %p DeviceObject %p\n",
490 OutDmaChannel, OuterUnknown, PoolType, DeviceDescription, DeviceObject);
491
492 This = new(PoolType, TAG_PORTCLASS)CDmaChannelInit(OuterUnknown);
493 if (!This)
495
496 Status = This->QueryInterface(IID_IDmaChannel, (PVOID*)OutDmaChannel);
497
498 if (!NT_SUCCESS(Status))
499 {
500 delete This;
501 return Status;
502 }
503
505
506 if (!NT_SUCCESS(Status))
507 {
508 delete This;
509 return Status;
510 }
511
512 return Status;
513}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define STDMETHODIMP
Definition: basetyps.h:43
const GUID IID_IUnknown
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:992
PVOID m_MapRegisterBase
Definition: dma_slave.cpp:57
ULONG m_LastTransferCount
Definition: dma_slave.cpp:59
PHYSICAL_ADDRESS m_Address
Definition: dma_slave.cpp:66
PDEVICE_OBJECT m_pDeviceObject
Definition: dma_slave.cpp:51
PDMA_ADAPTER m_pAdapter
Definition: dma_slave.cpp:52
ULONG m_BufferSize
Definition: dma_slave.cpp:64
friend IO_ALLOCATION_ACTION NTAPI AdapterControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
Definition: dma_slave.cpp:290
virtual ~CDmaChannelInit()
Definition: dma_slave.cpp:47
ULONG m_MaxMapRegisters
Definition: dma_slave.cpp:62
ULONG m_AllocatedBufferSize
Definition: dma_slave.cpp:63
BOOLEAN m_WriteToDevice
Definition: dma_slave.cpp:69
ULONG m_MaximumBufferSize
Definition: dma_slave.cpp:61
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
Definition: dma_slave.cpp:82
CDmaChannelInit(IUnknown *OuterUnknown)
Definition: dma_slave.cpp:30
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define BufferSize
Definition: mmc.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI PcNewDmaChannel(OUT PDMACHANNEL *OutDmaChannel, IN PUNKNOWN OuterUnknown OPTIONAL, IN POOL_TYPE PoolType, IN PDEVICE_DESCRIPTION DeviceDescription, IN PDEVICE_OBJECT DeviceObject)
Definition: dma_slave.cpp:479
IO_ALLOCATION_ACTION NTAPI AdapterControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
Definition: dma_slave.cpp:290
GUID IID_IDmaChannelSlave
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
unsigned int BOOL
Definition: ntddk_ex.h:94
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
Status
Definition: gdiplustypes.h:25
enum _INTERFACE_TYPE INTERFACE_TYPE
ULONG AddRef()
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:619
static WCHAR Address[46]
Definition: ping.c:68
static ULONG Timeout
Definition: ping.c:61
PDMA_ADAPTER NTAPI IoGetDmaAdapter(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PDEVICE_DESCRIPTION DeviceDescription, IN OUT PULONG NumberOfMapRegisters)
Definition: pnpdma.c:23
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:1382
IDmaChannel * PDMACHANNEL
Definition: portcls.h:784
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
#define PC_ASSERT_IRQL(x)
Definition: private.hpp:30
struct PCLASS_DEVICE_EXTENSION * PPCLASS_DEVICE_EXTENSION
#define TAG_PORTCLASS
Definition: private.hpp:24
#define PC_ASSERT(exp)
Definition: private.hpp:26
#define REFIID
Definition: guiddef.h:118
@ Output
Definition: arc.h:85
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PDEVICE_OBJECT PhysicalDeviceObject
Definition: private.hpp:402
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2295
static LARGE_INTEGER Counter
Definition: clock.c:43
#define LL
Definition: tui.h:167
INT POOL_TYPE
Definition: typedefs.h:78
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceDescription
Definition: wdfpdo.h:432
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE BusType
Definition: halfuncs.h:159
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:213
enum _IO_ALLOCATION_ACTION IO_ALLOCATION_ACTION
@ KeepObject
Definition: iotypes.h:202
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099
@ DevicePropertyLegacyBusType
Definition: iotypes.h:1208
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)