文章目录

  • DTS中定义
  • usb driver
  • bind
  • fastboot
  • fastboot命令处理
  • fastboot触发

介绍usb device设备驱动

uboot在init_dm中会扫描dtb和代码中driver进行匹配,匹配成功就调用driver驱动进行bind
以dwc3为例进行介绍

DTS中定义

usb0: usb0@ff9d0000 {#address-cells = <2>;#size-cells = <2>;status = "disabled";compatible = "xlnx,zynqmp-dwc3"; //匹配的compatible reg = <0x0 0xff9d0000 0x0 0x100>;clock-names = "bus_clk", "ref_clk";power-domains = <&pd_usb0>;ranges;nvmem-cells = <&soc_revision>;nvmem-cell-names = "soc_revision";dwc3_0: dwc3@fe200000 {compatible = "snps,dwc3";status = "disabled";reg = <0x0 0xfe200000 0x0 0x40000>;interrupt-parent = <&gic>;interrupts = <0 65 4>, <0 69 4>;#stream-id-cells = <1>;iommus = <&smmu 0x860>;snps,quirk-frame-length-adjustment = <0x20>;snps,refclk_fladj;snps,enable_guctl1_resume_quirk;snps,enable_guctl1_ipd_quirk;snps,xhci-stream-quirk;/* dma-coherent; */};
};usb1: usb1@ff9e0000 {#address-cells = <2>;#size-cells = <2>;status = "disabled";compatible = "xlnx,zynqmp-dwc3";reg = <0x0 0xff9e0000 0x0 0x100>;clock-names = "bus_clk", "ref_clk";power-domains = <&pd_usb1>;ranges;nvmem-cells = <&soc_revision>;nvmem-cell-names = "soc_revision";dwc3_1: dwc3@fe300000 {compatible = "snps,dwc3";status = "disabled";reg = <0x0 0xfe300000 0x0 0x40000>;interrupt-parent = <&gic>;interrupts = <0 70 4>, <0 74 4>;#stream-id-cells = <1>;iommus = <&smmu 0x861>;snps,quirk-frame-length-adjustment = <0x20>;snps,refclk_fladj;snps,enable_guctl1_resume_quirk;snps,enable_guctl1_ipd_quirk;snps,xhci-stream-quirk;/* dma-coherent; */};
};

usb driver

drivers\usb\dwc3\dwc3-generic.c

用于match的compatible
static const struct udevice_id dwc3_generic_ids[] = {{ .compatible = "xlnx,zynqmp-dwc3" },{ }
};定义了driver
U_BOOT_DRIVER(dwc3_generic_wrapper) = {.name   = "dwc3-generic-wrapper",.id = UCLASS_MISC,.of_match = dwc3_generic_ids,.bind = dwc3_generic_bind,
};

bind

compatible = “xlnx,zynqmp-dwc3” ,dts和driver匹配成功,定义driver->bind,即dwc3_generic_bind

static int dwc3_generic_bind(struct udevice *parent)
{const void *fdt = gd->fdt_blob;int node;int ret;遍历dts中usb device,一个soc可能包含多个usb控制器for (node = fdt_first_subnode(fdt, parent->of_offset); node > 0;node = fdt_next_subnode(fdt, node)) {const char *name = fdt_get_name(fdt, node, NULL);enum usb_dr_mode dr_mode;struct udevice *dev;debug("%s: subnode name: %s\n", __func__, name);if (strncmp(name, "dwc3@", 4))continue;dr_mode = usb_get_dr_mode(node);//usb 控制器模式,device模式或主机模式switch (dr_mode) {case USB_DR_MODE_PERIPHERAL://device模式case USB_DR_MODE_OTG://otg模式//进一步进行device和driver匹配,驱动name为 "dwc3-generic-peripheral",ret = device_bind_driver_to_node(parent,"dwc3-generic-peripheral",name, node, &dev);break;case USB_DR_MODE_HOST:debug("%s: dr_mode: HOST\n", __func__);ret = device_bind_driver_to_node(parent,"dwc3-generic-host",name, node, &dev);break;default:break;};}return 0;
}

device_bind_driver_to_node–》device_bind–》device_bind_common:匹配了device和驱动,调用uclass-bind和driver bind。

"dwc3-generic-peripheral"驱动

U_BOOT_DRIVER(dwc3_generic_peripheral) = {.name = "dwc3-generic-peripheral",.id  = UCLASS_USB_DEV_GENERIC,.ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata,.probe = dwc3_generic_peripheral_probe,.remove = dwc3_generic_peripheral_remove,.bind = dwc3_generic_peripheral_bind,.platdata_auto_alloc_size = sizeof(struct usb_platdata),.priv_auto_alloc_size = sizeof(struct dwc3),.flags    = DM_FLAG_ALLOC_PRIV_DMA,
};

dwc3_generic_peripheral_bind–》device_probe–》dev->drv->probe》dwc3_generic_peripheral_probe
调用了dwc3_generic_peripheral_probe–》dwc3_init进行dwc3初始化

–》dwc3_core_init_mode–》dwc3_gadget_init–》usb_add_gadget_udc
初始了gadget功能,并向udc core注册。
具体初始化过程不再描述。
完成了底层usb device和驱动初始化,上层抽象功能在进行初始化,比如,网络,鼠标等等。

fastboot

以fastboot为例,分析function驱动初始注册。
f_fastboot.c
DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add);
声明定义了g_dnl_bind_callback 结构的fastboot function功能。

/** @usb_fname: unescaped USB function name* @callback_ptr: bind callback, one per function name*/
#define DECLARE_GADGET_BIND_CALLBACK(usb_fname, callback_ptr) \ll_entry_declare(struct g_dnl_bind_callback, \__usb_function_name_##usb_fname, \g_dnl_bind_callbacks) = { \.usb_function_name = #usb_fname, \.fptr = callback_ptr \}typedef int (*g_dnl_bind_callback_f)(struct usb_configuration *);/* used in Gadget downloader callback linker list */
struct g_dnl_bind_callback {const char *usb_function_name;g_dnl_bind_callback_f fptr;
};

do_fastboot中调用注册了fastboot驱动,

do_fastboot--》g_dnl_register("usb_dnl_fastboot");--》
g_dnl_driver.name = name;
usb_composite_register(&g_dnl_driver);--》
composite = driver;
usb_gadget_register_driver(&composite_driver);
--》usb_gadget_probe_driver
找到一个udc,前面usb初始化已经向usb core注册了udc
list_for_each_entry(udc, &udc_list, list) {/* For now we take the first one */if (!udc->driver)goto found;}ret = udc_bind_to_driver(udc, driver);---》driver->bind(udc->gadget); 回调g_dnl_bindusb_gadget_udc_start(udc); 开启usb func功能,触发usb device和usb host交互usb_gadget_connect(udc->gadget);

g_dnl_bind–》g_dnl_config_register

一些usb 设备的configconfig->label = name;config->bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER;config->bConfigurationValue = CONFIGURATION_NUMBER;config->iConfiguration = STRING_USBDOWN;config->bind = g_dnl_do_config;
usb_add_config--》config->bind(config);--》 g_dnl_do_config
static int g_dnl_do_config(struct usb_configuration *c)
{const char *s = c->cdev->driver->name;struct g_dnl_bind_callback *callback = g_dnl_bind_callback_first();for (; callback != g_dnl_bind_callback_end(); callback++)if (!strcmp(s, callback->usb_function_name))return callback->fptr(c); //回调所有dnl类型的function功能return -ENODEV;
}
--》fastboot_add进行functiong功能注册
以上过程就是function对应设备接口,配置和端点注册过程
static inline int usb_gadget_udc_start(struct usb_udc *udc)
{return udc->gadget->ops->udc_start(udc->gadget, udc->driver);
}

fastboot_add功能添加

static int fastboot_add(struct usb_configuration *c)
{struct f_fastboot *f_fb = fastboot_func;int status;debug("%s: cdev: 0x%p\n", __func__, c->cdev);if (!f_fb) {f_fb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_fb));if (!f_fb)return -ENOMEM;fastboot_func = f_fb;memset(f_fb, 0, sizeof(*f_fb));}f_fb->usb_function.name = "f_fastboot";f_fb->usb_function.bind = fastboot_bind;f_fb->usb_function.unbind = fastboot_unbind;f_fb->usb_function.set_alt = fastboot_set_alt;f_fb->usb_function.disable = fastboot_disable;f_fb->usb_function.strings = fastboot_strings;status = usb_add_function(c, &f_fb->usb_function);return status;
}

在接口配置设置时回调f_fb->usb_function.set_alt = fastboot_set_alt;
fastboot_set_alt中配置了端点回调函数,并且使能了端点。
f_fb->out_req->complete = rx_handler_command; 从host接收到usb包,回调函数
f_fb->in_req->complete = fastboot_complete; 发送一个usb包,回调函数

fastboot命令处理

rx_handler_command中解析接收到usb数据,并匹配是否含有定义的fastboot协议命令

static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
{char *cmdbuf = req->buf;void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;int i;匹配命令for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) {if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) {func_cb = cmd_dispatch_info[i].cb;break;}}if (req->actual < req->length) {u8 *buf = (u8 *)req->buf;buf[req->actual] = 0;func_cb(ep, req); //处理命令}*cmdbuf = '\0';req->actual = 0;usb_ep_queue(ep, req, 0);
}
static const struct cmd_dispatch_info cmd_dispatch_info[] = {{.cmd = "reboot",.cb = cb_reboot,}, {.cmd = "getvar:",.cb = cb_getvar,}, {.cmd = "download:",.cb = cb_download,}, {.cmd = "boot",.cb = cb_boot,}, {.cmd = "continue",.cb = cb_continue,},
#ifdef CONFIG_FASTBOOT_FLASH{.cmd = "flash",.cb = cb_flash,}, {.cmd = "erase",.cb = cb_erase,},
#endif{.cmd = "oem",.cb = cb_oem,},
};

fastboot触发

上一节分析了fastboot功能的注册。
命令fastboot触发fastboot功能进行初始化注册,并继续后续处理。

U_BOOT_CMD(fastboot, 2, 1, do_fastboot,"use USB Fastboot protocol","<USB_controller>\n""    - run as a fastboot usb device"
);
static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{int controller_index;char *usb_controller;int ret;if (argc < 2)return CMD_RET_USAGE;usb_controller = argv[1];controller_index = simple_strtoul(usb_controller, NULL, 0);ret = board_usb_init(controller_index, USB_INIT_DEVICE);if (ret) {error("USB init failed: %d", ret);return CMD_RET_FAILURE;}g_dnl_clear_detach();ret = g_dnl_register("usb_dnl_fastboot");if (ret)return ret;if (!g_dnl_board_usb_cable_connected()) {puts("\rUSB cable not detected.\n" \"Command exit.\n");ret = CMD_RET_FAILURE;goto exit;}前面注册usb fastboot驱动下面是和host交互命令处理while (1) {if (g_dnl_detach())break;if (ctrlc())break;usb_gadget_handle_interrupts(controller_index); 中断处理,处理event buf,回调上面的out_req->complete和in_req->complete}ret = CMD_RET_SUCCESS;return ret;
}

uboot usb设备驱动相关推荐

  1. Linux USB设备驱动程序设计 和 USB下载线驱动设计

    Linux USB设备驱动程序设计 和 USB下载线驱动设计 USB设备驱动模型 USB设备包括配置(configuration).接口(interface)和端点(endpoint),一个USB设备 ...

  2. usb linux 内核,Linux内核USB驱动架构:USB设备驱动架构.pdf

    USB 设备驱动架构 LK 版本:2.6.35.3 2013 年1 月14 日  任务目标: 分析整理插入一个USB 设备的处理过程.  USB 设备.配置.接口.设置以及端点的五者关系图: 一个 ...

  3. usb设备驱动之uvc设备

    usb设备驱动之uvc设备 声明:涉及相关内容包括v4l2框架/drivers/media/v4l2-core/,usb设备控制器驱动/drivers/usb/dwc3/,usb composite驱 ...

  4. 浅谈Linux USB设备驱动

    1.USB基础介绍 1-1.USB硬件接口介绍 USB接口在硬件上总共有四根线组成VCC.D+.D-.GND,通过计算D+和D-的差值来确定数据.USB设备在传输速率上可以分为低速(1.5Mbps). ...

  5. WDF开发USB设备驱动教程(2)

    PDF全文下载:http://bbs.driverdevelop.com/read.php?tid-120461.html 3.2 获取描述符 上一小节认识了USB 的描述符后,这一节就来讲如何从 U ...

  6. WDF开发USB设备驱动教程(1)

    PDF下载地址(1.2版):链接地址 CY001开发板讨论帖:链接地址 注:本文档新版本已出,请在博客中查找,或下载PDF全文文档. 链接地址WDF开发USB设备驱动教程 by 张佩 文档说明 作者写 ...

  7. Linux设备驱动之usb设备驱动详解

    原文地址:http://blog.csdn.net/chenjin_zhong/article/details/6329316 1.Linux usb设备驱动框架 USB是通用串行总线的总称,Linu ...

  8. 第八章 USB 设备驱动移植

    8.1 USB协议     USB协议系统主要组成,总线拓扑结构,内部层次关系,数据流模式,USB调度等等         8.1.1 主要组成部分             USB的连接部分,USB的 ...

  9. windows 7 出现MTP usb设备驱动安装问题解决方法

    连接电脑提示MTP USB设备驱动失败,网上搜到了解决方案: http://11643599.blog.hexun.com/61703464_d.html 这个设备是用来同步媒体的,windows m ...

最新文章

  1. ​rsync应用拓展多模块同步13
  2. 软件分享:将应用一键打包成dmg文件
  3. boost::mp11::mp_fill相关用法的测试程序
  4. RUNOOB python练习题 35 python print各色字体及背景
  5. Oracle基础语句
  6. TFS Training for Kunlun bank (http://www.klb.cn/) 微软研发流程(ALM)管理培训会议(昆仑银行) 2016.09.21...
  7. 用c语言写三个人打鱼问题,用c语言解决三天打鱼,两天晒网的问题要用到什么函数...
  8. 【es】使用ElasticSearch的44条建议 性能优化
  9. flask 上传excel 前端_flask 笔记
  10. 微软VC/MFC FAQ(转)
  11. 何时该开始写测试代码
  12. Kconfig中select与depends on原理
  13. 什么是通配符 计算机网络,通配符
  14. 会计做什么副业好?分享几个适合会计的副业
  15. 【日记本砸】21.06.11-20 复杂的式子和角标只是一个符号一个标记而已
  16. 《程序员修炼之道:从小工到专家》读书笔记
  17. C3D:视频动作分类demo实现
  18. 我的世界服务器物品栏变小了,我的世界如何改变物品大小 | 手游网游页游攻略大全...
  19. 二代测序linux软件,二代测序数据分析软件包大全
  20. DELPHI学习笔记1

热门文章

  1. 移动端地图技术分享 百度高德SDK
  2. 微信小程序抓包方法汇总
  3. 阿里云OSS服务端签名前端JS直传(php)示例
  4. Power BI 学习笔记(一)
  5. 基于SSM婚恋网交友平台
  6. 手机裂脑纪:中国式审美还有救吗?
  7. zoj3716Ribbon Gymnastics
  8. chrome 一进入调试页面就会自动打断点
  9. 二分查找-递归和非递归
  10. yaml语法 关于key为中文时的问题