@@ -219,6 +219,62 @@ typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t;
219219 * @bytes_transferred: byte counter
220220 */
221221
222+ /**
223+ * enum dma_desc_metadata_mode - per descriptor metadata mode types supported
224+ * @DESC_METADATA_CLIENT - the metadata buffer is allocated/provided by the
225+ * client driver and it is attached (via the dmaengine_desc_attach_metadata()
226+ * helper) to the descriptor.
227+ *
228+ * Client drivers interested to use this mode can follow:
229+ * - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
230+ * 1. prepare the descriptor (dmaengine_prep_*)
231+ * construct the metadata in the client's buffer
232+ * 2. use dmaengine_desc_attach_metadata() to attach the buffer to the
233+ * descriptor
234+ * 3. submit the transfer
235+ * - DMA_DEV_TO_MEM:
236+ * 1. prepare the descriptor (dmaengine_prep_*)
237+ * 2. use dmaengine_desc_attach_metadata() to attach the buffer to the
238+ * descriptor
239+ * 3. submit the transfer
240+ * 4. when the transfer is completed, the metadata should be available in the
241+ * attached buffer
242+ *
243+ * @DESC_METADATA_ENGINE - the metadata buffer is allocated/managed by the DMA
244+ * driver. The client driver can ask for the pointer, maximum size and the
245+ * currently used size of the metadata and can directly update or read it.
246+ * dmaengine_desc_get_metadata_ptr() and dmaengine_desc_set_metadata_len() is
247+ * provided as helper functions.
248+ *
249+ * Note: the metadata area for the descriptor is no longer valid after the
250+ * transfer has been completed (valid up to the point when the completion
251+ * callback returns if used).
252+ *
253+ * Client drivers interested to use this mode can follow:
254+ * - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
255+ * 1. prepare the descriptor (dmaengine_prep_*)
256+ * 2. use dmaengine_desc_get_metadata_ptr() to get the pointer to the engine's
257+ * metadata area
258+ * 3. update the metadata at the pointer
259+ * 4. use dmaengine_desc_set_metadata_len() to tell the DMA engine the amount
260+ * of data the client has placed into the metadata buffer
261+ * 5. submit the transfer
262+ * - DMA_DEV_TO_MEM:
263+ * 1. prepare the descriptor (dmaengine_prep_*)
264+ * 2. submit the transfer
265+ * 3. on transfer completion, use dmaengine_desc_get_metadata_ptr() to get the
266+ * pointer to the engine's metadata area
267+ * 4. Read out the metadata from the pointer
268+ *
269+ * Note: the two mode is not compatible and clients must use one mode for a
270+ * descriptor.
271+ */
272+ enum dma_desc_metadata_mode {
273+ DESC_METADATA_NONE = 0 ,
274+ DESC_METADATA_CLIENT = BIT (0 ),
275+ DESC_METADATA_ENGINE = BIT (1 ),
276+ };
277+
222278struct dma_chan_percpu {
223279 /* stats */
224280 unsigned long memcpy_count ;
@@ -475,6 +531,18 @@ struct dmaengine_unmap_data {
475531 dma_addr_t addr [0 ];
476532};
477533
534+ struct dma_async_tx_descriptor ;
535+
536+ struct dma_descriptor_metadata_ops {
537+ int (* attach )(struct dma_async_tx_descriptor * desc , void * data ,
538+ size_t len );
539+
540+ void * (* get_ptr )(struct dma_async_tx_descriptor * desc ,
541+ size_t * payload_len , size_t * max_len );
542+ int (* set_len )(struct dma_async_tx_descriptor * desc ,
543+ size_t payload_len );
544+ };
545+
478546/**
479547 * struct dma_async_tx_descriptor - async transaction descriptor
480548 * ---dma generic offload fields---
@@ -488,6 +556,11 @@ struct dmaengine_unmap_data {
488556 * descriptor pending. To be pushed on .issue_pending() call
489557 * @callback: routine to call after this operation is complete
490558 * @callback_param: general parameter to pass to the callback routine
559+ * @desc_metadata_mode: core managed metadata mode to protect mixed use of
560+ * DESC_METADATA_CLIENT or DESC_METADATA_ENGINE. Otherwise
561+ * DESC_METADATA_NONE
562+ * @metadata_ops: DMA driver provided metadata mode ops, need to be set by the
563+ * DMA driver if metadata mode is supported with the descriptor
491564 * ---async_tx api specific fields---
492565 * @next: at completion submit this descriptor
493566 * @parent: pointer to the next level up in the dependency chain
@@ -504,6 +577,8 @@ struct dma_async_tx_descriptor {
504577 dma_async_tx_callback_result callback_result ;
505578 void * callback_param ;
506579 struct dmaengine_unmap_data * unmap ;
580+ enum dma_desc_metadata_mode desc_metadata_mode ;
581+ struct dma_descriptor_metadata_ops * metadata_ops ;
507582#ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH
508583 struct dma_async_tx_descriptor * next ;
509584 struct dma_async_tx_descriptor * parent ;
@@ -666,6 +741,7 @@ struct dma_filter {
666741 * @global_node: list_head for global dma_device_list
667742 * @filter: information for device/slave to filter function/param mapping
668743 * @cap_mask: one or more dma_capability flags
744+ * @desc_metadata_modes: supported metadata modes by the DMA device
669745 * @max_xor: maximum number of xor sources, 0 if no capability
670746 * @max_pq: maximum number of PQ sources and PQ-continue capability
671747 * @copy_align: alignment shift for memcpy operations
@@ -733,6 +809,7 @@ struct dma_device {
733809 struct list_head global_node ;
734810 struct dma_filter filter ;
735811 dma_cap_mask_t cap_mask ;
812+ enum dma_desc_metadata_mode desc_metadata_modes ;
736813 unsigned short max_xor ;
737814 unsigned short max_pq ;
738815 enum dmaengine_alignment copy_align ;
@@ -910,6 +987,41 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_memcpy(
910987 len , flags );
911988}
912989
990+ static inline bool dmaengine_is_metadata_mode_supported (struct dma_chan * chan ,
991+ enum dma_desc_metadata_mode mode )
992+ {
993+ if (!chan )
994+ return false;
995+
996+ return !!(chan -> device -> desc_metadata_modes & mode );
997+ }
998+
999+ #ifdef CONFIG_DMA_ENGINE
1000+ int dmaengine_desc_attach_metadata (struct dma_async_tx_descriptor * desc ,
1001+ void * data , size_t len );
1002+ void * dmaengine_desc_get_metadata_ptr (struct dma_async_tx_descriptor * desc ,
1003+ size_t * payload_len , size_t * max_len );
1004+ int dmaengine_desc_set_metadata_len (struct dma_async_tx_descriptor * desc ,
1005+ size_t payload_len );
1006+ #else /* CONFIG_DMA_ENGINE */
1007+ static inline int dmaengine_desc_attach_metadata (
1008+ struct dma_async_tx_descriptor * desc , void * data , size_t len )
1009+ {
1010+ return - EINVAL ;
1011+ }
1012+ static inline void * dmaengine_desc_get_metadata_ptr (
1013+ struct dma_async_tx_descriptor * desc , size_t * payload_len ,
1014+ size_t * max_len )
1015+ {
1016+ return NULL ;
1017+ }
1018+ static inline int dmaengine_desc_set_metadata_len (
1019+ struct dma_async_tx_descriptor * desc , size_t payload_len )
1020+ {
1021+ return - EINVAL ;
1022+ }
1023+ #endif /* CONFIG_DMA_ENGINE */
1024+
9131025/**
9141026 * dmaengine_terminate_all() - Terminate all active DMA transfers
9151027 * @chan: The channel for which to terminate the transfers
0 commit comments