1/* 2 * Copyright (c) 2014 ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#ifndef DMA_CHANNEL_INTERNAL_H 11#define DMA_CHANNEL_INTERNAL_H 12 13#include <dma/dma_channel.h> 14 15struct dma_req_setup; 16 17/* 18 * 19 */ 20typedef errval_t (*memcpy_fn_t)(struct dma_channel *chan, 21 struct dma_req_setup *setup, 22 dma_req_id_t *id); 23 24typedef errval_t (*memset_fn_t)(struct dma_channel *chan, 25 struct dma_req_setup *setup, 26 dma_req_id_t *id); 27 28typedef errval_t (*chan_poll_fn_t)(struct dma_channel *chan); 29 30/** 31 * 32 */ 33struct dma_channel_fn 34{ 35 memcpy_fn_t memcpy; 36 memset_fn_t memset; 37 chan_poll_fn_t poll; 38}; 39 40/** 41 * Represents the generic part of a DMA channel 42 */ 43struct dma_channel 44{ 45 dma_chan_id_t id; ///< unique DMA channel id 46 dma_chan_st_t state; ///< channel state 47 struct dma_device *device; ///< DMA device this channel belongs to 48 uint32_t max_xfer_size; ///< maximum number of bytes per transfer 49 50 struct dma_mem mmio; 51 52 struct { 53 dma_irq_t type; 54 dma_irq_fn_t fn; 55 void *arg; 56 } irq; ///< Device level interrupt 57 58 struct { 59 uint32_t count; ///< number of requests in the list 60 struct dma_request *head; ///< start of the request list 61 struct dma_request *tail; ///< end of the request list 62 } req_list; ///< list of submitted requests 63 64 uint64_t req_counter; ///< number of requests issued so far 65 66 struct dma_channel_fn f; ///< function pointers to channels 67}; 68 69/* 70 * ---------------------------------------------------------------------------- 71 * Request List Management 72 * ---------------------------------------------------------------------------- 73 */ 74 75/** 76 * \brief returns the first request on the submitted request queue of the channel 77 * 78 * \param chan DMA channel 79 * 80 * \returns pointer to the DMA request 81 * NULL if queue was empty 82 */ 83struct dma_request *dma_channel_deq_request_head(struct dma_channel *chan); 84 85/** 86 * \brief returns the request with the given request ID 87 * 88 * \param chan DMA channel 89 * \param id DMA request id 90 * 91 * \returns pointer to the DMA request 92 * NULL if queue was empty 93 */ 94struct dma_request *dma_channel_deq_request_by_id(struct dma_channel *chan, 95 dma_req_id_t id); 96 97/** 98 * \brief inserts a request into the head of a channel's request list 99 * 100 * \param chan DMA channel 101 * \param req DMA request to be inserted 102 */ 103void dma_channel_enq_request_head(struct dma_channel *chan, 104 struct dma_request *req); 105 106/** 107 * \brief inserts a request at the end of the channels request list 108 * 109 * \param chan DMA channel 110 * \param req DMA request to be inserted 111 */ 112void dma_channel_enq_request_tail(struct dma_channel *chan, 113 struct dma_request *req); 114 115/** 116 * \brief Submits the pending descriptors to the hardware queue 117 * 118 * \param chan IOAT DMA channel 119 * 120 * \returns number of submitted descriptors 121 */ 122uint16_t dma_channel_submit_pending(struct dma_channel *chan); 123 124 125/** 126 * \brief returns the next DMA request counter value to generate the req id. 127 * 128 * \param chan DMA channel 129 * 130 * \returns request counter value 131 */ 132static inline uint64_t dma_channel_incr_req_count(struct dma_channel *chan) 133{ 134 return ++chan->req_counter; 135} 136 137 138#endif /* DMA_CHANNEL_INTERNAL_H */ 139