[PATCH v4 36/41] dmaengine: add support to provide error result from a DMA transation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Adding a new callback that will provide the error result for a transaction.
The result is allocated on the stack and the callback should create a copy
if it wishes to retain the information after exiting. The result parameter
is now defined and takes over the dummy void pointer we placed in the
helper functions previously. dmaengine drivers should start converting
to the new "callback_result" callback in order to receive transaction
results.

Signed-off-by: Dave Jiang <dave.jiang@xxxxxxxxx>
---
 drivers/dma/dmaengine.h   |   22 +++++++++++++++++-----
 include/linux/dmaengine.h |   16 ++++++++++++++++
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
index 94a4379..882ff94 100644
--- a/drivers/dma/dmaengine.h
+++ b/drivers/dma/dmaengine.h
@@ -88,6 +88,7 @@ static inline void dma_set_residue(struct dma_tx_state *state, u32 residue)
 
 struct dmaengine_desc_callback {
 	dma_async_tx_callback callback;
+	dma_async_tx_callback_result callback_result;
 	void *callback_param;
 };
 
@@ -105,13 +106,14 @@ dmaengine_desc_get_callback(struct dma_async_tx_descriptor *tx,
 			    struct dmaengine_desc_callback *cb)
 {
 	cb->callback = tx->callback;
+	cb->callback_result = tx->callback_result;
 	cb->callback_param = tx->callback_param;
 }
 
 /**
  * dmaengine_desc_callback_invoke - call the callback function in cb struct
  * @cb: temp struct that is holding the callback info
- * @result: dummy pointer for now
+ * @result: transaction result
  *
  * Call the callback function provided in the cb struct with the parameter
  * in the cb struct.
@@ -119,17 +121,27 @@ dmaengine_desc_get_callback(struct dma_async_tx_descriptor *tx,
  */
 static inline void
 dmaengine_desc_callback_invoke(struct dmaengine_desc_callback *cb,
-			       const void *result)
+			       const struct dmaengine_result *result)
 {
-	if (cb->callback)
+	struct dmaengine_result dummy_result = {
+		.result = DMA_TRANS_NOERROR,
+		.residue = 0
+	};
+
+	if (cb->callback_result) {
+		if (!result)
+			result = &dummy_result;
+		cb->callback_result(cb->callback_param, result);
+	} else if (cb->callback) {
 		cb->callback(cb->callback_param);
+	}
 }
 
 /**
  * dmaengine_desc_get_callback_invoke - get the callback in tx descriptor and
  * 					then immediately call the callback.
  * @tx: dma async tx descriptor
- * @result: dummy pointer for now
+ * @result: transaction result
  *
  * Call dmaengine_desc_get_callback() and dmaengine_desc_callback_invoke()
  * in a single function since no work is necessary in between for the driver.
@@ -137,7 +149,7 @@ dmaengine_desc_callback_invoke(struct dmaengine_desc_callback *cb,
  */
 static inline void
 dmaengine_desc_get_callback_invoke(struct dma_async_tx_descriptor *tx,
-				   const void *result)
+				   const struct dmaengine_result *result)
 {
 	struct dmaengine_desc_callback cb;
 
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 30de019..cc535a4 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -441,6 +441,21 @@ typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
 
 typedef void (*dma_async_tx_callback)(void *dma_async_param);
 
+enum dmaengine_tx_result {
+	DMA_TRANS_NOERROR = 0,		/* SUCCESS */
+	DMA_TRANS_READ_FAILED,		/* Source DMA read failed */
+	DMA_TRANS_WRITE_FAILED,		/* Destination DMA write failed */
+	DMA_TRANS_ABORTED,		/* Op never submitted / aborted */
+};
+
+struct dmaengine_result {
+	enum dmaengine_tx_result result;
+	u32 residue;
+};
+
+typedef void (*dma_async_tx_callback_result)(void *dma_async_param,
+				const struct dmaengine_result *result);
+
 struct dmaengine_unmap_data {
 	u8 map_cnt;
 	u8 to_cnt;
@@ -478,6 +493,7 @@ struct dma_async_tx_descriptor {
 	dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx);
 	int (*desc_free)(struct dma_async_tx_descriptor *tx);
 	dma_async_tx_callback callback;
+	dma_async_tx_callback_result callback_result;
 	void *callback_param;
 	struct dmaengine_unmap_data *unmap;
 #ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH

--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux