Previous Next

IDmaChannel

The IDmaChannel interface provides an abstraction of a DMA channel and its associated DMA buffer and usage parameters. A WaveCyclic or WavePci port driver implements this interface and exposes it to the WaveCyclic or WavePci miniport driver. The miniport driver obtains a reference to the port driver's implementation of an IDmaChannel object by calling one of the port driver's NewXxxDmaChannel methods (see list below). A miniport driver also has the option of implementing its own IDmaChannel interface if it requires capabilities that are not in the port driver's default implementation (for more information, see Wave Filters). When the port driver calls the miniport driver's NewStream method (for example, IMiniportWaveCyclic::NewStream), the method outputs the miniport driver's IDmaChannel object to the port driver. IDmaChannel inherits from the IUnknown interface.

An IDmaChannel object encapsulates the following:

Ports and miniport drivers use DMA-channel objects to communicate information regarding DMA-channel usage. Typically, a miniport driver allocates a set of DMA channels during initialization or during the creation of a stream. At the time that a new stream is created, the miniport driver tells the port driver which DMA-channel object will be used for the stream.

DMA-channel objects can be created for master or slave devices:

For more information on master and slave devices, see Introduction to Adapter Objects. A master DMA-channel object is little more than a backboard for sharing information about the DMA channel between the port and miniport drivers. The DMA-channel object for a master or slave device exposes the following:

The adapter object is a DMA-adapter structure for a physical device object (PDO). The adapter object is automatically created when the DMA-channel object is created by one of the following methods:

IPortWavePci::NewMasterDmaChannel

IPortWaveCyclic::NewMasterDmaChannel

IPortWaveCyclic::NewSlaveDmaChannel

The method IDmaChannel::GetAdapterObject can be used to obtain a pointer to the adapter object.

In the case of a DMA channel for a slave device, the IDmaChannel::TransferCount method returns the maximum transfer size (the MapSize parameter) that was specified in the call to IDmaChannelSlave::Start. Also, the adapter object provides some methods for manipulating and querying the DMA device. None of these methods are meaningful for master DMA channels.

IDmaChannel::AllocateBuffer and IDmaChannel::FreeBuffer are used to manage the single common buffer that is associated with the DMA-channel object. The buffer that is allocated by the object is guaranteed to be accessible by both the driver (with kernel virtual-memory addresses) and DMA device (with physical-memory addresses). In addition, the buffer will be physically contiguous. Typically, the best strategy is to allocate the DMA buffer during miniport-driver initialization when physically contiguous memory is most plentiful. IDmaChannel::AllocatedBufferSize returns the size of the buffer as it was specified in the call to IDmaChannel::AllocateBuffer.

IDmaChannel::MaximumBufferSize indicates the actual maximum buffer size that can be used. This might exceed the allocated size if the allocated size is not an even multiple of the page size. It might be less than the allocated size if the DMA device cannot support transfers of the allocated size. IDmaChannel::BufferSize and IDmaChannel::SetBufferSize are used to query and set the size of the buffer to be used for DMA transfers. When the buffer is allocated, the buffer size is set to the maximum buffer size. After initialization, both the port driver and miniport driver have the opportunity to change the buffer size and discover its current value. The miniport driver uses the result of IDmaChannel::BufferSize to determine the transfer size for DMA operations when the DMA channel is started. IDmaChannel::SystemAddress and IDmaChannel::PhysicalAddress are used to obtain the virtual and physical addresses of the buffer, respectively.

IDmaChannel::CopyTo and IDmaChannel::CopyFrom copy sample data to and from the DMA buffer.

The DMA buffer is not necessarily used to transfer the streamed data. In the case of the WavePci port driver, the streamed data is delivered to (or from) the miniport driver using scatter/gather mappings. However, the miniport driver might still make use of the buffer as a shared memory space for communicating with the adapter driver.

Port drivers provide miniport drivers with functions that they can use to create DMA channels. Unless otherwise noted in the description of the port driver, it is not absolutely necessary to use DMA objects allocated from the port driver. The port driver simply requires a pointer to an IDmaChannel interface that supports the methods it needs. Check the documentation for each port driver for a list of the DMA-channel methods that the port driver requires.

Typically, the easiest path is to use the DMA-channel allocation functions that are offered by the port driver. In some rare cases, the miniport-driver developer will want to implement the DMA-channel object in some special way that meets the needs of a particular adapter. This sometimes requires the implementation of a new object. At other times, it is sufficient to have the miniport driver's stream object expose an IDmaChannel interface and implement the DMA-channel methods itself.

In addition to the methods that IDmaChannel inherits from the IUnknown interface, IDmaChannel supports the following methods:

IDmaChannel::AllocateBuffer

IDmaChannel::AllocatedBufferSize

IDmaChannel::BufferSize

IDmaChannel::CopyFrom

IDmaChannel::CopyTo

IDmaChannel::FreeBuffer

IDmaChannel::GetAdapterObject

IDmaChannel::MaximumBufferSize

IDmaChannel::PhysicalAddress

IDmaChannel::SetBufferSize

IDmaChannel::SystemAddress

IDmaChannel::TransferCount