Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2a092ea authored by Thomas Petazzoni's avatar Thomas Petazzoni Committed by Greg Kroah-Hartman
Browse files

dmaengine: mv_xor_v2: do not use descriptors not acked by async_tx



commit bc473da1ed726c975ad47f8d7d27631de11356d8 upstream.

Descriptors that have not been acknowledged by the async_tx layer
should not be re-used, so this commit adjusts the implementation of
mv_xor_v2_prep_sw_desc() to skip descriptors for which
async_tx_test_ack() is false.

Fixes: 19a340b1 ("dmaengine: mv_xor_v2: new driver")
Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 67b1684c
Loading
Loading
Loading
Loading
+22 −10
Original line number Diff line number Diff line
@@ -344,6 +344,7 @@ static struct mv_xor_v2_sw_desc *
mv_xor_v2_prep_sw_desc(struct mv_xor_v2_device *xor_dev)
{
	struct mv_xor_v2_sw_desc *sw_desc;
	bool found = false;

	/* Lock the channel */
	spin_lock_bh(&xor_dev->lock);
@@ -355,19 +356,23 @@ mv_xor_v2_prep_sw_desc(struct mv_xor_v2_device *xor_dev)
		return NULL;
	}

	/* get a free SW descriptor from the SW DESQ */
	sw_desc = list_first_entry(&xor_dev->free_sw_desc,
				   struct mv_xor_v2_sw_desc, free_list);
	list_for_each_entry(sw_desc, &xor_dev->free_sw_desc, free_list) {
		if (async_tx_test_ack(&sw_desc->async_tx)) {
			found = true;
			break;
		}
	}

	if (!found) {
		spin_unlock_bh(&xor_dev->lock);
		return NULL;
	}

	list_del(&sw_desc->free_list);

	/* Release the channel */
	spin_unlock_bh(&xor_dev->lock);

	/* set the async tx descriptor */
	dma_async_tx_descriptor_init(&sw_desc->async_tx, &xor_dev->dmachan);
	sw_desc->async_tx.tx_submit = mv_xor_v2_tx_submit;
	async_tx_ack(&sw_desc->async_tx);

	return sw_desc;
}

@@ -785,8 +790,15 @@ static int mv_xor_v2_probe(struct platform_device *pdev)

	/* add all SW descriptors to the free list */
	for (i = 0; i < MV_XOR_V2_DESC_NUM; i++) {
		xor_dev->sw_desq[i].idx = i;
		list_add(&xor_dev->sw_desq[i].free_list,
		struct mv_xor_v2_sw_desc *sw_desc =
			xor_dev->sw_desq + i;
		sw_desc->idx = i;
		dma_async_tx_descriptor_init(&sw_desc->async_tx,
					     &xor_dev->dmachan);
		sw_desc->async_tx.tx_submit = mv_xor_v2_tx_submit;
		async_tx_ack(&sw_desc->async_tx);

		list_add(&sw_desc->free_list,
			 &xor_dev->free_sw_desc);
	}