3.9. pl08x_prep_slave_sg

struct dma_async_tx_descriptor *pl08x_prep_slave_sg1(
		struct dma_chan *chan, struct scatterlist *sgl,
		unsigned int sg_len, enum dma_data_direction direction,
		unsigned long flags)
{
	struct pl08x_txd *local_txd;
	unsigned int reg = 0;
	int i;

	/*
	 * Current implementation ASSUMES only one sg
	 */
	if (sg_len != 1)
		BUG();

	local_txd = kmalloc(sizeof(struct pl08x_txd), GFP_KERNEL);
	if (!local_txd)	{
		dev_err(&pd.dmac->dev, "%s - no local_txd\n", __func__);
		return NULL;
	} else {
		struct pl08x_dma_chan *local_chan =
			container_of(chan, struct pl08x_dma_chan, chan);

		dma_async_tx_descriptor_init(&local_txd->tx, chan);

		if (direction == DMA_TO_DEVICE) {

			local_txd->srcbus.addr	= sgl->dma_address;
			local_txd->dstbus.addr	=
				reg = local_chan->slave->tx_reg;

		} else if (direction == DMA_FROM_DEVICE) {
			local_txd->srcbus.addr	=
				reg = local_chan->slave->rx_reg;
			local_txd->dstbus.addr	= sgl->dma_address;
		} else {
			dev_err(&pd.dmac->dev,
				"%s - direction unsupported\n", __func__);
			return NULL;
		}
		/*
		 * Find the device array entry for this txd
		 * so that the txd has access to the peripheral data
		 */
		for (i = 0; i < PL08X_DMA_SIGNALS; i++) {
			if (reg == (((unsigned int)(pd.pd->sd[i].io_addr))))2
				break;
		}
		local_txd->pcd = &pd.pd->sd[i];
		local_txd->tx.tx_submit	= pl08x_tx_submit;
		local_txd->len = sgl->length;
		INIT_LIST_HEAD(&local_txd->txd_list);
	}

	return &local_txd->tx;
}
        

1

上层程序调用此函数,对提出的DMA请求和scatter/gather list 信息进行预处理,其实主要就是根据你当前的一些参数,包括设备的DMA的地址进行匹配,找到合适的配置参数,用于以后的DMA各个参数的设置

2

找到和自己的匹配的那个参数,这些参数是之前在amba设备注册时候,已经设置和初始化好的一堆设置参数