7. Code Migration Reference
This section provides side-by-side code comparisons between QDMA and MDB5 DMA implementations for key operations.
The code snippets shown below highlight the core functionality to illustrate the similarities and differences between QDMA and MDB5 DMA implementations.
7.1 Application Code
7.1.1 Register Access (dma-ctl)
Both use mmap on /sys/bus/pci/devices/.../resource<BAR>. QDMA falls back to netlink if mmap fails.
| QDMA (apps/dma-utils/dmactl_reg.c) | MDB5 DMA (client-apps/dma-utils/dma_common_utils.c) |
|---|---|
|
|
7.1.2 Queue/Channel Operations (dma-ctl)
QDMA uses netlink for queue management (add, start, stop, delete queues). In contrast, MDB5 DMA channels are always available and do not require explicit creation or destruction. The dma-ctl utility in MDB5 DMA provides various channel management capabilities including: configuring transfer modes (Simple or Scatter-Gather), setting aperture size for SG mode, displaying channel statistics, and reading/writing registers for debugging purposes.
| QDMA (apps/dma-utils/dmactl.c) | MDB5 DMA (client-apps/dma-ctl/dma_ctl.c) |
|---|---|
|
|
7.1.3 Channel/Queue Information Flow
Understanding how channel and queue information is passed through the application is crucial for migration:
QDMA Approach:
- Queue lifecycle:
add → start → (use) → stop → delete - Queue information passed via netlink commands and queue IDs
- Applications must explicitly manage queue lifecycle before transfers
- Device nodes created dynamically:
/dev/qdma<BDF>-MM-<QID>
MDB5 DMA Approach:
- Channels device nodes are created by client driver (8 read + 8 write)
- Channel information passed via standard file descriptors
- Applications simply open device nodes:
/dev/mdb5_read<00-07>,/dev/mdb5_write<00-07> - No explicit channel lifecycle management required
- Optional configuration via
/dev/mdb5_ctrlusing ioctl
| QDMA (apps/dma-xfer/dmaxfer.c) | MDB5 DMA (client-apps/dma-xfer/dma_xfer.c) |
|---|---|
|
|
7.1.4 Data Transfer (dma-to-device / dma-from-device)
The core data transfer functions in both drivers use standard POSIX I/O syscalls. The channel/queue information is implicitly passed through the file descriptor obtained by opening the appropriate device node (e.g., /dev/qdma... or /dev/mdb5_write00). The offset parameter specifies the target address on the device.
QDMA uses lseek() followed by write(), while MDB5 uses the combined pwrite() call.
H2C Transfer (write_from_buffer)
| QDMA (apps/dma-utils/dma_xfer_utils.c) | MDB5 DMA (client-apps/dma-utils/dma_common_utils.c) |
|---|---|
|
|
C2H Transfer (read_to_buffer)
Similarly, for reading data from device to host, both use POSIX read syscalls:
| QDMA (apps/dma-utils/dma_xfer_utils.c) | MDB5 DMA (client-apps/dma-utils/dma_common_utils.c) |
|---|---|
|
|
7.1.5 dma-xfer Tool
Both dma-xfer implementations share the same configuration file format and overall structure: parsing key=value pairs, validating parameters, setting up channels/queues, and executing transfers. The main difference lies in resource lifecycle management.
QDMA Approach:
- Parses config file for queue parameters (mode, direction, queue range, PCI bus/dev/function)
- Validates queue range against driver-assigned
qmax - Explicitly creates queues via netlink (add → start sequence)
- Opens device nodes for created queues
- Performs transfers using file descriptors
- Explicitly destroys queues (stop → delete sequence)
MDB5 DMA Approach:
- Parses config file for channel parameters (mode, direction, number of channels, transfer mode)
- Validates channel count against maximum supported channels
- Opens pre-existing channel device nodes directly
- Configures transfer mode (Simple/SG) via ioctl on control device
- Performs transfers using file descriptors
- Channels persist after application exits (no cleanup required)
Queue/Channel Setup and Transfer Execution
| QDMA (apps/dma-xfer/dmaxfer.c) | MDB5 DMA (client-apps/dma-xfer/dma_xfer.c) |
|---|---|
|
|