drivers/crypto/ccp/ccp-dmaengine.c

Source file repositories/reference/linux-study-clean/drivers/crypto/ccp/ccp-dmaengine.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/ccp/ccp-dmaengine.c
Extension
.c
Size
19114 bytes
Lines
792
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (desc) {
			/* Remove the DMA command from the list and free it */
			ccp_free_active_cmd(desc);

			if (!list_empty(&desc->pending)) {
				/* No errors, keep going */
				if (desc->status != DMA_ERROR)
					return desc;

				/* Error, free remaining commands and move on */
				ccp_free_cmd_resources(desc->ccp,
						       &desc->pending);
			}

			tx_desc = &desc->tx_desc;
		} else {
			tx_desc = NULL;
		}

		spin_lock_irqsave(&chan->lock, flags);

		if (desc) {
			if (desc->status != DMA_ERROR)
				desc->status = DMA_COMPLETE;

			dev_dbg(desc->ccp->dev,
				"%s - tx %d complete, status=%u\n", __func__,
				desc->tx_desc.cookie, desc->status);

			dma_cookie_complete(tx_desc);
			dma_descriptor_unmap(tx_desc);
		}

		desc = __ccp_next_dma_desc(chan, desc);

		spin_unlock_irqrestore(&chan->lock, flags);

		if (tx_desc) {
			dmaengine_desc_get_callback_invoke(tx_desc, NULL);

			dma_run_dependencies(tx_desc);
		}
	} while (desc);

	return NULL;
}

static struct ccp_dma_desc *__ccp_pending_to_active(struct ccp_dma_chan *chan)
{
	struct ccp_dma_desc *desc;

	if (list_empty(&chan->pending))
		return NULL;

	desc = list_empty(&chan->active)
		? list_first_entry(&chan->pending, struct ccp_dma_desc, entry)
		: NULL;

	list_splice_tail_init(&chan->pending, &chan->active);

	return desc;
}

static void ccp_cmd_callback(void *data, int err)
{
	struct ccp_dma_desc *desc = data;
	struct ccp_dma_chan *chan;
	int ret;

	if (err == -EINPROGRESS)
		return;

	chan = container_of(desc->tx_desc.chan, struct ccp_dma_chan,
			    dma_chan);

	dev_dbg(chan->ccp->dev, "%s - tx %d callback, err=%d\n",
		__func__, desc->tx_desc.cookie, err);

	if (err)
		desc->status = DMA_ERROR;

	while (true) {
		/* Check for DMA descriptor completion */
		desc = ccp_handle_active_desc(chan, desc);

		/* Don't submit cmd if no descriptor or DMA is paused */
		if (!desc || (chan->status == DMA_PAUSED))
			break;

		ret = ccp_issue_next_cmd(desc);

Annotation

Implementation Notes