Generic interface operation flow:
```
/* Get xDMA controller */
sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
/* Allocate virtual channel */
sc->xchan_tx = xdma_channel_alloc(sc->xdma_tx, caps);
/* Setup transfer status callback. */
xdma_setup_intr(sc->xchan_tx, my_tx_intr, sc, &sc->ih_tx);
/* Request a transfer */
ret = xdma_request(sc->xchan_tx, &req);
/* Free the channel */
xdma_channel_free(sc->xdma_tx);
/* Free the controller */
xdma_put(sc->xdma_tx);
```
Less generic (scatter-gather application based on xDMA interface) operation flow:
```
/* Get xDMA controller */
sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
/* Allocate virtual channel */
sc->xchan_tx = xdma_channel_alloc(sc->xdma_tx, caps);
```
```
int
atse_xdma_tx_intr(void *arg, xdma_transfer_status_t *status)
{
for (;;) {
err = xdma_dequeue_mbuf(sc->xchan_tx, &m, &st);
if (err != 0) {
break;
}
}
}
/* Setup interrupt handler. */
xdma_setup_intr(sc->xchan_tx, atse_xdma_tx_intr, sc, &sc->ih_tx);
/* Prepare SG transfer */
xdma_prep_sg(sc->xchan_tx, TX_QUEUE_SIZE, ...);
```
```
/* Enqueue (multiple) mbufs to receive */
m = m_getcl();
xdma_enqueue_mbuf(sc->xchan_rx, &m, 0, 4, 4, XDMA_DEV_TO_MEM);
m = m_getcl();
xdma_enqueue_mbuf(sc->xchan_rx, &m, 0, 4, 4, XDMA_DEV_TO_MEM);
...
xdma_queue_submit(sc->xchan_rx);
```
```
/* Enqueue mbuf to transmit */
xdma_enqueue_mbuf(sc->xchan_tx, &m, 0, 4, 4, XDMA_MEM_TO_DEV);
xdma_queue_submit(sc->xchan_tx);
```
**DMA engine driver interface. These functions have to be implemented in DMA engine driver **
```
/* Allocate real hardware channel */
int
msgdma_channel_alloc(device_t dev, struct xdma_channel *xchan)
{
}
/* Request a transfer */
static int
pdma_channel_request(device_t dev, struct xdma_channel *xchan, struct xdma_request *req)
{
}
/* Free the channel */
static int
msgdma_channel_free(device_t dev, struct xdma_channel *xchan)
{
}
/* Start/stop DMA operation */
static int
msgdma_channel_control(device_t dev, xdma_channel_t *xchan, int cmd)
{
}
```
**Scatter-gather DMA engine driver interface**
```
/* Prepare a channel for SG transfer */
softdma_channel_prep_sg(device_t dev, struct xdma_channel *xchan)
{
...
}
/* Submit sg list */
softdma_channel_submit_sg(device_t dev, struct xdma_channel *xchan,
struct xdma_sglist *sg, uint32_t sg_n)
{
...
}
/* Provide the amount of free entries for requests. */
softdma_channel_capacity(device_t dev, xdma_channel_t *xchan,
uint32_t *capacity)
{
...
}
/* Start/stop DMA operation */
static int
msgdma_channel_control(device_t dev, xdma_channel_t *xchan, int cmd)
{
}
```