usb gadget configfs分析

参考文章:https://www.cnblogs.com/linhaostudy/p/17016238.html

struct usb_udc {
	struct usb_gadget_driver	*driver;//代表一个gadget设备driver
	struct usb_gadget		*gadget;//代表一个udc设备
	struct device			dev;
	struct list_head		list;
	bool				vbus;
};

composite.c

  • usb_gadget_driver是function驱动和UDC驱动沟通的桥梁
static const struct usb_gadget_driver composite_driver_template = {
	.bind		= composite_bind,
	.unbind		= composite_unbind,

	.setup		= composite_setup,
	.reset		= composite_disconnect,
	.disconnect	= composite_disconnect,

	.suspend	= composite_suspend,
	.resume		= composite_resume,

	.driver	= {
		.owner		= THIS_MODULE,
	},
};
driver->gadget_driver = composite_driver_template//composite.c
	usb_composite_probe//composite.c
		usb_gadget_probe_driver(gadget_driver)//udc\core.c
			udc_bind_to_driver(udc, driver)//udc\core.c
				usb_gadget_udc_start(udc)//udc\core.c
				
static inline int usb_gadget_udc_start(struct usb_udc *udc)
{
	return udc->gadget->ops->udc_start(udc->gadget, udc->driver);
}		
		
			

configfs.c

  • usb_gadget_driver
static const struct usb_gadget_driver configfs_driver_template = {
	.bind           = configfs_composite_bind,
	.unbind         = configfs_composite_unbind,

	.setup          = configfs_composite_setup,
	.reset          = configfs_composite_disconnect,
	.disconnect     = configfs_composite_disconnect,

	.suspend	= configfs_composite_suspend,
	.resume		= configfs_composite_resume,

	.max_speed	= USB_SPEED_SUPER_PLUS,
	.driver = {
		.owner          = THIS_MODULE,
		.name		= "configfs-gadget",
	},
	.match_existing_only = 1,
};
gadgets_make
	gi->composite.gadget_driver = configfs_driver_template
		
  • Function驱动和UDC驱动绑定的时候通过调用usb_gadget_probe_driver间接调用usb_gadget_udc_start开启UDC
  • udc_bind_to_driver将usb_gadget_driver和底层的USB控制器绑定,usb_gadget_driver相当于一个桥梁,桥的两端分别是function驱动和UDC驱动
gadget_dev_desc_UDC_store//configfs.c
	usb_gadget_probe_driver(&gi->composite.gadget_driver)//core.c
		udc_bind_to_driver(udc, driver)//core.c
		  	driver->bind(udc->gadget, driver)//core.c  回调usb_gadget_driver的bind函数
		  	
			usb_gadget_udc_start(udc)usb_udc_connect_control  使能USB设备控制器
				udc->gadget->ops->udc_start(udc->gadget, udc->driver)//core.c
					ambarella_udc_start
						ambarella_udc_enable(udc)	/* Enable udc */
		
			usb_udc_connect_control(udc)//core.c   连接USB主机控制器,这样USB主机就能识别并枚举USB设备
			usb_gadget_connect(udc->gadget)//core.c 
static const struct usb_gadget_ops ambarella_ops = {
	.get_frame		= ambarella_udc_get_frame,
	.wakeup			= ambarella_udc_wakeup,
	.pullup			= ambarella_udc_pullup,
	.vbus_session		= ambarella_udc_vbus_session,
	/*.set_selfpowered: Always selfpowered */
	.udc_start		= ambarella_udc_start,
	.udc_stop		= ambarella_udc_stop,
};

分配端点0的usb_request

driver->bind(udc->gadget, driver)//core.c  回调usb_gadget_driver的bind函数
	composite_dev_prepare(composite, cdev)
		/*GFP_KERNEL是内核内存分配时最常用的,无内存可用时可引起休眠。*/
		cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL)//composite.c 
			req = ep->ops->alloc_request(ep, gfp_flags)//core.c  回调

GFP_KERNEL
是内核内存分配时最常用的,无内存可用时可引起休眠。
GFP_ATOMIC
用来从中断处理和进程上下文之外的其他代码中分配内存,从不睡眠。
GFP_KERNEL
内核内存的正常分配,可能睡眠。
GFP_USER
用来为用户空间页来分配内存,它可能睡眠。
GFP_HIGHUSER
如同 GFP_USER, 但是从高端内存分配, 如果有, 高端内存在下一个子节描述.
GFP_NOIO
根本不允许任何 I/O 初始化。
GFP_NOFS
这个标志功能如同 GFP_KERNEL, 但是它们增加限制到内核能做的来满足请求。一个 GFP_NOFS 分配不允许进行任何文件系统调用,而 GFP_NOIO 根本不允许任何 I/O 初始化。它们主要地用在文件系统和虚拟内存代码,那里允许一个分配睡眠,但是递归的文件系统调用会是一个坏主意。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃秃秃秃哇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值