musb dma 部分

本文探讨了musb_core.c文件中musb_init_controller()函数如何调用dma_controller_create()进行DMA通道预分配,主要关注struct、descriptor、callback、null buffer及C语言实现。
摘要由CSDN通过智能技术生成

musb_core.c 中的 musb_init_controller() 中,会调用到 dma_controller_create(),代码 如下:

#ifndef CONFIG_MUSB_PIO_ONLY                     //如果没有选上 PIO 模式,则使能 DMA 模式
	if (use_dma && dev->dma_mask) {
		struct dma_controller	*c;

		c = dma_controller_create(musb, musb->mregs);
		musb->dma_controller = c;
		if (c)
			(void) c->start(c);
	}
#endif
1. dma_controller_create() 定义在 cartesio_dma.c 中:

struct dma_controller *__init
dma_controller_create(struct musb *musb, void __iomem *base)
{
	struct musb_dma_controller *controller;
	struct device *dev = musb->controller;
	struct platform_device *pdev = to_platform_device(dev);
	struct musb_hdrc_platform_data *plat = dev->platform_data;
	struct resource *res;

	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
	if (!controller)
		return NULL;

	controller->dma_client = plat->dma_slave;
	controller->channel_count = MUSB_DMA_CHANNELS;
	controller->private_data = musb;

	/* need to set physical address in case of DMA */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	controller->musb_base_phy = (unsigned int *)res->start;

	controller->controller.start = dma_controller_start;
	controller->controller.stop = dma_controller_stop;
	controller->controller.channel_alloc = dma_channel_allocate;
	controller->controller.channel_release = dma_channel_release;
	controller->controller.channel_program = dma_channel_program;
	controller->controller.channel_abort = dma_channel_abort;

	return &controller->controller;
}
2. dma_controller_start() / dma_controller_stop()

static int dma_controller_start(struct dma_controller *c)
{
	struct musb_dma_controller *controller = container_of(c,
			struct musb_dma_controller, controller);

	/* Preallocate 1 bulk TX and 1 bulk RX dma channels. */
	controller->bulk_dma_channels[0] = dma_channel_preallocate(c, 1);
	controller->bulk_dma_channels[1] = dma_channel_preallocate(c, 0);

	return 0;
}

static struct dma_channel *dma_channel_preallocate(struct dma_controller *c,
        u8 transmit)

static struct dma_channel *dma_channel_preallocate(struct dma_controller *c,
		u8 transmit)
{
	struct musb_dma_controller *controller = container_of(c,
			struct musb_dma_controller, controller);
	struct musb *musb = controller->private_data;
	struct musb_dma_channel *musb_channel;
	struct dma_channel *channel;
	struct pl080_dma_slave *client;
	dma_cap_mask_t  mask;
	u8 bit;

	for (bit = 0; bit < MUSB_DMA_CHANNELS; bit++) {
		if (!(controller->used_channels & (1 << bit)))
			break;
	}

	if (bit == MUSB_DMA_CHANNELS) {
		dev_err(musb->controller, "No USB DMA channel free\n");
		return NULL;
	}

	controller->used_channels |= (1 << bit);
	musb_channel = &(controller->channel[bit]);
	musb_channel->controller = controller;
	musb_channel->idx = bit;
	musb_channel->transmit = transmit;

	channel = &(musb_channel->channel);
	channel->private_data = musb_channel;
	channel->status = MUSB_DMA_STATUS_UNKNOWN;
	/* dma max_len is not used, as we use scatter gather. */
	channel->max_len = 0x10000;
	/* dma mode 1 => 1; dma mode 0 => 0 always use 1*/
	channel->desired_mode = 1;
	channel->actual_len = 0;

	client = &controller->dma_client;
	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);
	musb_channel-
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值