#include <sys/cdefs.h>
#include "opt_platform.h"
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <dev/xdma/xdma.h>
int
xdma_dequeue(xdma_channel_t *xchan, void **user,
xdma_transfer_status_t *status)
{
struct xdma_request *xr_tmp;
struct xdma_request *xr;
QUEUE_OUT_LOCK(xchan);
TAILQ_FOREACH_SAFE(xr, &xchan->queue_out, xr_next, xr_tmp) {
TAILQ_REMOVE(&xchan->queue_out, xr, xr_next);
break;
}
QUEUE_OUT_UNLOCK(xchan);
if (xr == NULL)
return (-1);
*user = xr->user;
status->error = xr->status.error;
status->transferred = xr->status.transferred;
xchan_bank_put(xchan, xr);
return (0);
}
int
xdma_enqueue(xdma_channel_t *xchan, uintptr_t src, uintptr_t dst,
uint8_t src_width, uint8_t dst_width, bus_size_t len,
enum xdma_direction dir, void *user)
{
struct xdma_request *xr;
KASSERT(xchan->xdma != NULL, ("xdma is NULL"));
xr = xchan_bank_get(xchan);
if (xr == NULL)
return (-1);
xr->user = user;
xr->direction = dir;
xr->m = NULL;
xr->bp = NULL;
xr->block_num = 1;
xr->block_len = len;
xr->req_type = XR_TYPE_VIRT;
xr->src_addr = src;
xr->dst_addr = dst;
xr->src_width = src_width;
xr->dst_width = dst_width;
QUEUE_IN_LOCK(xchan);
TAILQ_INSERT_TAIL(&xchan->queue_in, xr, xr_next);
QUEUE_IN_UNLOCK(xchan);
return (0);
}
int
xdma_queue_submit(xdma_channel_t *xchan)
{
int ret;
KASSERT(xchan->xdma != NULL, ("xdma is NULL"));
ret = 0;
XCHAN_LOCK(xchan);
if (xchan->flags & XCHAN_TYPE_SG)
ret = xdma_queue_submit_sg(xchan);
XCHAN_UNLOCK(xchan);
return (ret);
}