Re: [PATCH v2 0/4] RFC: dmaengine: Add error reporting infrastructure

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

 



On 07/13/2016 12:24 AM, Dave Jiang wrote:
> Lars,
> Here's the reworked code per your comment. Let me know if this matches
> what you are thinking. Patch 2/4 shows how the driver provides the
> error, and patch 3,4/4 show how the errors are received by upper layer.
> The callback is an addition so people should be able to transition
> to the new one when convenient and the old callback still remains for
> compatibility. We should be able to expand on the new callback as
> needed since I don't know much about the slave DMA side of things. If
> you are ok with it I'll clean it up and add the proper comments/docs
> etc and resubmit.

Looks OK.

For the dispatching between the two callback functions there should be a
helper function in the core and all drivers should be update to use this
helper, so that clients can rely on that the right callback will be called.
If no result is provided by the driver the helper function should provide a
dummy result with no errors and no residue.

What makes the whole thing slightly tricky is that some drivers store the
callback on the stack and free (or recycle) the descriptor before the
callback is called. Since this is actually required for correct operation we
have to work with it.

Something like this might work.

struct dma_desc_callback {
	dma_async_tx_callback callback;
	void *callback_param;
};

static inline void dmaengine_desc_get_callback(
	struct dma_async_tx_descriptor *tx,
	struct dma_desc_callback *cb)
{
	cb->callback = tx->callback;
	cb->callback_param = tx->callback_param;
}

static inline void dmaengine_desc_callback_invoke(
	struct dma_desc_callback *cb, void *result)
{
	if (cb->callback)
		cb->callback(cb->callback_param);
}

And then update the drivers to something like:

	struct dmaengine_desc_callback cb;
	...
	dmaengine_desc_get_callback(tx, &cb);
	kfree(tx);
	dmaengine_desc_callback_invoke(&cb, NULL);
	...

This should result in the same generated code, but will allow to make changes.

And then when implementing the result callback update those helper functions to.

struct dma_desc_callback {
	dma_async_tx_callback callback;
	dma_async_tx_callback_result callback_result;
	void *callback_param;
};

static inline void dmaengine_desc_get_callback(
	struct dma_async_tx_descriptor *tx,
	struct dma_desc_callback *cb)
{
	cb->callback = tx->callback;
	cb->callback_result = tx->callback_result;
	cb->callback_param = tx->callback_param;
}

static inline void dmaengine_desc_callback_invoke(
	struct dma_desc_callback *cb, struct dmaengine_result *result)
{
	static const 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);
	}
}
--
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