/*
* First make the LLIs (could/should we do this earlier??)
* slave (m/p) - no queued transactions allowed at present
* TODO allow queued transactions for non circular buffers
* Set up the channel active txd as inactive
* m2m - transactions may be queued
* If no active txd on channel
* set it up as inactive
* - issue_pending() will set active & start
* else
* queue it
* Lock channel since there may be (at least for m2m) multiple calls
*
* Return < 0 for error
*/
static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
{
int num_llis;
unsigned long flags;
struct pl08x_txd *local_txd = container_of(tx, struct pl08x_txd, tx);
struct pl08x_dma_chan *local_chan =
container_of(tx->chan, struct pl08x_dma_chan, chan);
int pl08x_chan_num = local_chan->chan_id;
num_llis = fill_LLIS_for_desc(local_txd, pl08x_chan_num);
if (num_llis) {
spin_lock_irqsave(&local_chan->lock, flags);
atomic_inc(&local_chan->last_issued);
tx->cookie = atomic_read(&local_chan->last_issued);
if (local_chan->at) {
/*
* If this device not using a circular buffer then
* queue this new descriptor.
* The descriptor for a circular buffer continues
* to be used until the channel is freed
*/
if (local_txd->pcd->circular_buffer)
dev_err(&pd.dmac->dev,
"%s - attempting to queue a circular buffer\n",
__func__);
else
list_add_tail(&local_txd->txd_list,
&local_chan->desc_list);
} else {
local_txd->slave = local_chan->slave;
local_chan->at = local_txd;
local_txd->active = 0;
}
spin_unlock_irqrestore(&local_chan->lock, flags);
return tx->cookie;
} else
return -EINVAL;
}
| 此submit函数是你之前准备好了一切后,最后调用此函数提交你的请求,但是实际并没开始真正的DMA传输,要等到最后的issue pending才真正开始 |
| 为当前的desc描述符,填充好对应的LLI |