aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2007-01-02 13:10:43 -0500
committerDan Williams <dan.j.williams@intel.com>2007-07-13 11:06:11 -0400
commit7405f74badf46b5d023c5d2b670b4471525f6c91 (patch)
tree20dd20571637dba1c2b04c7b13ac208c33b5706b /include/linux
parent428ed6024fa74a271142f3257966e9b5e1cb37a1 (diff)
dmaengine: refactor dmaengine around dma_async_tx_descriptor
The current dmaengine interface defines mutliple routines per operation, i.e. dma_async_memcpy_buf_to_buf, dma_async_memcpy_buf_to_page etc. Adding more operation types (xor, crc, etc) to this model would result in an unmanageable number of method permutations. Are we really going to add a set of hooks for each DMA engine whizbang feature? - Jeff Garzik The descriptor creation process is refactored using the new common dma_async_tx_descriptor structure. Instead of per driver do_<operation>_<dest>_to_<src> methods, drivers integrate dma_async_tx_descriptor into their private software descriptor and then define a 'prep' routine per operation. The prep routine allocates a descriptor and ensures that the tx_set_src, tx_set_dest, tx_submit routines are valid. Descriptor creation and submission becomes: struct dma_device *dev; struct dma_chan *chan; struct dma_async_tx_descriptor *tx; tx = dev->device_prep_dma_<operation>(chan, len, int_flag) tx->tx_set_src(dma_addr_t, tx, index /* for multi-source ops */) tx->tx_set_dest(dma_addr_t, tx, index) tx->tx_submit(tx) In addition to the refactoring, dma_async_tx_descriptor also lays the groundwork for definining cross-channel-operation dependencies, and a callback facility for asynchronous notification of operation completion. Changelog: * drop dma mapping methods, suggested by Chris Leech * fix ioat_dma_dependency_added, also caught by Andrew Morton * fix dma_sync_wait, change from Andrew Morton * uninline large functions, change from Andrew Morton * add tx->callback = NULL to dmaengine calls to interoperate with async_tx calls * hookup ioat_tx_submit * convert channel capabilities to a 'cpumask_t like' bitmap * removed DMA_TX_ARRAY_INIT, no longer needed * checkpatch.pl fixes * make set_src, set_dest, and tx_submit descriptor specific methods * fixup git-ioat merge * move group_list and phys to dma_async_tx_descriptor Cc: Jeff Garzik <jeff@garzik.org> Cc: Chris Leech <christopher.leech@intel.com> Signed-off-by: Shannon Nelson <shannon.nelson@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Acked-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/dmaengine.h237
1 files changed, 149 insertions, 88 deletions
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c94d8f1d62e5..3de1cf71031a 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -21,13 +21,12 @@
21#ifndef DMAENGINE_H 21#ifndef DMAENGINE_H
22#define DMAENGINE_H 22#define DMAENGINE_H
23 23
24#ifdef CONFIG_DMA_ENGINE
25
26#include <linux/device.h> 24#include <linux/device.h>
27#include <linux/uio.h> 25#include <linux/uio.h>
28#include <linux/kref.h> 26#include <linux/kref.h>
29#include <linux/completion.h> 27#include <linux/completion.h>
30#include <linux/rcupdate.h> 28#include <linux/rcupdate.h>
29#include <linux/dma-mapping.h>
31 30
32/** 31/**
33 * enum dma_event - resource PNP/power managment events 32 * enum dma_event - resource PNP/power managment events
@@ -65,6 +64,31 @@ enum dma_status {
65}; 64};
66 65
67/** 66/**
67 * enum dma_transaction_type - DMA transaction types/indexes
68 */
69enum dma_transaction_type {
70 DMA_MEMCPY,
71 DMA_XOR,
72 DMA_PQ_XOR,
73 DMA_DUAL_XOR,
74 DMA_PQ_UPDATE,
75 DMA_ZERO_SUM,
76 DMA_PQ_ZERO_SUM,
77 DMA_MEMSET,
78 DMA_MEMCPY_CRC32C,
79 DMA_INTERRUPT,
80};
81
82/* last transaction type for creation of the capabilities mask */
83#define DMA_TX_TYPE_END (DMA_INTERRUPT + 1)
84
85/**
86 * dma_cap_mask_t - capabilities bitmap modeled after cpumask_t.
87 * See linux/cpumask.h
88 */
89typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t;
90
91/**
68 * struct dma_chan_percpu - the per-CPU part of struct dma_chan 92 * struct dma_chan_percpu - the per-CPU part of struct dma_chan
69 * @refcount: local_t used for open-coded "bigref" counting 93 * @refcount: local_t used for open-coded "bigref" counting
70 * @memcpy_count: transaction counter 94 * @memcpy_count: transaction counter
@@ -157,48 +181,106 @@ struct dma_client {
157 struct list_head global_node; 181 struct list_head global_node;
158}; 182};
159 183
184typedef void (*dma_async_tx_callback)(void *dma_async_param);
185/**
186 * struct dma_async_tx_descriptor - async transaction descriptor
187 * ---dma generic offload fields---
188 * @cookie: tracking cookie for this transaction, set to -EBUSY if
189 * this tx is sitting on a dependency list
190 * @ack: the descriptor can not be reused until the client acknowledges
191 * receipt, i.e. has has a chance to establish any dependency chains
192 * @phys: physical address of the descriptor
193 * @tx_list: driver common field for operations that require multiple
194 * descriptors
195 * @chan: target channel for this operation
196 * @tx_submit: set the prepared descriptor(s) to be executed by the engine
197 * @tx_set_dest: set a destination address in a hardware descriptor
198 * @tx_set_src: set a source address in a hardware descriptor
199 * @callback: routine to call after this operation is complete
200 * @callback_param: general parameter to pass to the callback routine
201 * ---async_tx api specific fields---
202 * @depend_list: at completion this list of transactions are submitted
203 * @depend_node: allow this transaction to be executed after another
204 * transaction has completed, possibly on another channel
205 * @parent: pointer to the next level up in the dependency chain
206 * @lock: protect the dependency list
207 */
208struct dma_async_tx_descriptor {
209 dma_cookie_t cookie;
210 int ack;
211 dma_addr_t phys;
212 struct list_head tx_list;
213 struct dma_chan *chan;
214 dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx);
215 void (*tx_set_dest)(dma_addr_t addr,
216 struct dma_async_tx_descriptor *tx, int index);
217 void (*tx_set_src)(dma_addr_t addr,
218 struct dma_async_tx_descriptor *tx, int index);
219 dma_async_tx_callback callback;
220 void *callback_param;
221 struct list_head depend_list;
222 struct list_head depend_node;
223 struct dma_async_tx_descriptor *parent;
224 spinlock_t lock;
225};
226
160/** 227/**
161 * struct dma_device - info on the entity supplying DMA services 228 * struct dma_device - info on the entity supplying DMA services
162 * @chancnt: how many DMA channels are supported 229 * @chancnt: how many DMA channels are supported
163 * @channels: the list of struct dma_chan 230 * @channels: the list of struct dma_chan
164 * @global_node: list_head for global dma_device_list 231 * @global_node: list_head for global dma_device_list
232 * @cap_mask: one or more dma_capability flags
233 * @max_xor: maximum number of xor sources, 0 if no capability
165 * @refcount: reference count 234 * @refcount: reference count
166 * @done: IO completion struct 235 * @done: IO completion struct
167 * @dev_id: unique device ID 236 * @dev_id: unique device ID
237 * @dev: struct device reference for dma mapping api
168 * @device_alloc_chan_resources: allocate resources and return the 238 * @device_alloc_chan_resources: allocate resources and return the
169 * number of allocated descriptors 239 * number of allocated descriptors
170 * @device_free_chan_resources: release DMA channel's resources 240 * @device_free_chan_resources: release DMA channel's resources
171 * @device_memcpy_buf_to_buf: memcpy buf pointer to buf pointer 241 * @device_prep_dma_memcpy: prepares a memcpy operation
172 * @device_memcpy_buf_to_pg: memcpy buf pointer to struct page 242 * @device_prep_dma_xor: prepares a xor operation
173 * @device_memcpy_pg_to_pg: memcpy struct page/offset to struct page/offset 243 * @device_prep_dma_zero_sum: prepares a zero_sum operation
174 * @device_memcpy_complete: poll the status of an IOAT DMA transaction 244 * @device_prep_dma_memset: prepares a memset operation
175 * @device_memcpy_issue_pending: push appended descriptors to hardware 245 * @device_prep_dma_interrupt: prepares an end of chain interrupt operation
246 * @device_dependency_added: async_tx notifies the channel about new deps
247 * @device_issue_pending: push pending transactions to hardware
176 */ 248 */
177struct dma_device { 249struct dma_device {
178 250
179 unsigned int chancnt; 251 unsigned int chancnt;
180 struct list_head channels; 252 struct list_head channels;
181 struct list_head global_node; 253 struct list_head global_node;
254 dma_cap_mask_t cap_mask;
255 int max_xor;
182 256
183 struct kref refcount; 257 struct kref refcount;
184 struct completion done; 258 struct completion done;
185 259
186 int dev_id; 260 int dev_id;
261 struct device *dev;
187 262
188 int (*device_alloc_chan_resources)(struct dma_chan *chan); 263 int (*device_alloc_chan_resources)(struct dma_chan *chan);
189 void (*device_free_chan_resources)(struct dma_chan *chan); 264 void (*device_free_chan_resources)(struct dma_chan *chan);
190 dma_cookie_t (*device_memcpy_buf_to_buf)(struct dma_chan *chan, 265
191 void *dest, void *src, size_t len); 266 struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)(
192 dma_cookie_t (*device_memcpy_buf_to_pg)(struct dma_chan *chan, 267 struct dma_chan *chan, size_t len, int int_en);
193 struct page *page, unsigned int offset, void *kdata, 268 struct dma_async_tx_descriptor *(*device_prep_dma_xor)(
194 size_t len); 269 struct dma_chan *chan, unsigned int src_cnt, size_t len,
195 dma_cookie_t (*device_memcpy_pg_to_pg)(struct dma_chan *chan, 270 int int_en);
196 struct page *dest_pg, unsigned int dest_off, 271 struct dma_async_tx_descriptor *(*device_prep_dma_zero_sum)(
197 struct page *src_pg, unsigned int src_off, size_t len); 272 struct dma_chan *chan, unsigned int src_cnt, size_t len,
198 enum dma_status (*device_memcpy_complete)(struct dma_chan *chan, 273 u32 *result, int int_en);
274 struct dma_async_tx_descriptor *(*device_prep_dma_memset)(
275 struct dma_chan *chan, int value, size_t len, int int_en);
276 struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)(
277 struct dma_chan *chan);
278
279 void (*device_dependency_added)(struct dma_chan *chan);
280 enum dma_status (*device_is_tx_complete)(struct dma_chan *chan,
199 dma_cookie_t cookie, dma_cookie_t *last, 281 dma_cookie_t cookie, dma_cookie_t *last,
200 dma_cookie_t *used); 282 dma_cookie_t *used);
201 void (*device_memcpy_issue_pending)(struct dma_chan *chan);