1. dwc3 and dummy gadget

debug:

ls /sys/class/udc        //查看系统注册了的udc驱动

1.1 gadegt 初始化

1.1.1 dwc3 gadget 初始化

== dwc3_gadget_init(struct dwc3 *dwc);== dwc3_gadget_init_endpoints(dwc, dwc->num_eps);   // num_eps 从设备硬件中读取== dwc3_gadget_init_endpoint(dwc, epnum);      // 初始化端点==    struct dwc3_ep          *dep;           // 对usb_ep 封装成dwc3_epdep->number = epnum;                   // dep 数量最多32 个dep->regs = dwc->regs + DWC3_DEP_BASE(epnum);    // 对应寄存器地址dwc->eps[epnum] = dep;== dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep);== dep->endpoint.ops = &dwc3_gadget_ep_ops;        //usb_ep 的ops== usb_add_gadget(dwc->gadget);       //gadget设备:struct usb_gadget *gadget; == device_add(&gadget->dev);  // 注册gadget 设备== list_add_tail(&udc->list, &udc_list); //将该udc 添加到udc_list 链表,与后期gadget 匹配== device_add(&udc->dev);        // 注册udc 设备

1.1.2 dummy gadget 初始化

== dummy_udc_probe(struct platform_device *pdev);== dum->gadget.ops = &dummy_ops;== init_dummy_udc_hw(dum);== struct dummy_ep    *ep = &dum->ep[i];      // 对usb_ep 封装成dummy_epep->ep.ops = &dummy_ep_ops;               // usb_ep 的opsdum->gadget.ep0 = &dum->ep[0].ep;      // 端点0 比较特殊== usb_add_gadget_udc(&pdev->dev, &dum->gadget);== usb_add_gadget_udc_release(parent, gadget, NULL);== usb_initialize_gadget(parent, gadget, release);== usb_add_gadget(gadget);

1.1.3 端点 ep

usb_gadget 结构体为共有信息,含有端点0(ep0),所有设备都必须含有端点0,用于控制传输

struct usb_gadget {struct usb_udc            *udc;/* readonly to gadget driver */const struct usb_gadget_ops *ops;struct usb_ep          *ep0;struct list_head       ep_list;    /* of usb_ep */enum usb_device_speed        speed;enum usb_device_speed     max_speed;enum usb_device_state     state;const char            *name;struct device         dev;
}

dwc3 属于私有设备信息,包含usb_gadget 信息,并含有其他端点的信息dw3_ep(封装的usb_ep)。

struct dwc3 {struct device       *dev;struct device      *sysdev;struct platform_device  *xhci;struct resource       xhci_resources[DWC3_XHCI_RESOURCES_NUM];struct dwc3_ep      *eps[DWC3_ENDPOINTS_NUM];struct usb_gadget  *gadget;
}

同样的,dummy 属于私有设备信息,包含usb_gadget 信息,并含有其他端点的信息dummy_ep(封装的usb_ep)。

struct dummy {// DEVICE/GADGET side supportstruct dummy_ep           ep[DUMMY_ENDPOINTS];int             address;int             callback_usage;struct usb_gadget        gadget;struct usb_gadget_driver *driver;struct dummy_request        fifo_req;u8             fifo_buf[FIFO_SIZE];u16             devstatus;// HOST side supportstruct dummy_hcd      *hs_hcd;struct dummy_hcd        *ss_hcd;
}

1.2 gadget 发送数据(dwc3)

1.2.1 function 向gadget 申请req

\drivers\usb\gadget\function\f_fs.c
(1) 申请req

ffs->ep0req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);     //端点0 的传输
ffs->ep0req->complete = ffs_ep0_complete;    // req的完成函数

or

ep = usb_ep_autoconfig(func->gadget, ds);        // 从gadget 获取与description 对应的端点
req = usb_ep_alloc_request(ep, GFP_KERNEL);

(2) 将req 提交到dwc3 gadget core

== usb_ep_queue(ffs->gadget->ep0, req, GFP_ATOMIC);      //提交到ep0
== ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC);           //提交到非0 端点== ret = ep->ops->queue(ep, req, gfp_flags);== dwc3_gadget_ep_queue();

1.2.2 dwc3 gadget core 处理req (写寄存器)

== dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, gfp_t gfp_flags)== __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)== __dwc3_gadget_start_isoc(struct dwc3_ep *dep)== __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)== dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, struct dwc3_gadget_ep_cmd_params *params)     // This function will issue @cmd with given @params to @dep and wait for its completion.== dwc3_writel(void __iomem *base, u32 offset, u32 value)

1.2.3 core 返回req (中断回调函数)

== udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver)== usb_gadget_udc_start(struct usb_udc *udc);udc->gadget->ops->udc_start(udc->gadget, udc->driver);== dwc3_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver)  //注册中断== request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, IRQF_SHARED, "dwc3", dwc->ev_buf);== dwc3_thread_interrupt(int irq, void *_evt)     //中断产生,调用回调函数== dwc3_process_event_buf(struct dwc3_event_buffer *evt)      //处理中断事件buf== dwc3_process_event_entry(struct dwc3 *dwc, const union dwc3_event *event)== dwc3_endpoint_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event)== dwc3_gadget_endpoint_transfer_complete()     //调用req完成函数== dwc3_gadget_endpoint_trbs_complete()== dwc3_gadget_ep_cleanup_completed_requests()== dwc3_gadget_giveback(dep, req, status);                //数据返回== usb_gadget_giveback_request()    // give the request back to the gadget layer== req->complete(ep, req);== ffs_ep0_complete(struct usb_ep *ep, struct usb_request *req)    // function的完成函数

1.3 gadget 发送数据(dummy)

1.2.1 function 向gadget 申请req

dwc3 一样。

1.2.2 dummy gadget core 处理req (memcpy)

== dummy_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t mem_flags);/* implement an emulated single-request FIFO */== memcpy(dum->fifo_buf, _req->buf, _req->length);  == req->req.context = dum;== req->req.complete = fifo_complete;         //完成函数== list_add_tail(&req->queue, &ep->queue);== usb_gadget_giveback_request(_ep, _req);        //返回req,调用完成函数== req->complete(ep, req);

1.4 usb_gadget_ops

usb_gadget_ops函数集,这些函数主要是操作UDC设备的一些特性(针对设备)。
enable/disable gadget 的时候,会调用到相关接口。

1.4.1 dwc3

== dwc3_gadget_init(struct dwc3 *dwc)== dwc->gadget->ops       = &dwc3_gadget_ops;        //初始化static const struct usb_gadget_ops dwc3_gadget_ops = {.get_frame      = dwc3_gadget_get_frame,.wakeup            = dwc3_gadget_wakeup,.set_selfpowered  = dwc3_gadget_set_selfpowered,.pullup          = dwc3_gadget_pullup,.udc_start        = dwc3_gadget_start,.udc_stop      = dwc3_gadget_stop,.udc_set_speed      = dwc3_gadget_set_speed,.udc_set_ssp_rate  = dwc3_gadget_set_ssp_rate,.get_config_params  = dwc3_gadget_config_params,.vbus_draw     = dwc3_gadget_vbus_draw,.check_config      = dwc3_gadget_check_config,.udc_async_callbacks    = dwc3_gadget_async_callbacks,
};

1.4.2 dummy

static const struct usb_gadget_ops dummy_ops = {.get_frame  = dummy_g_get_frame,.wakeup        = dummy_wakeup,.set_selfpowered = dummy_set_selfpowered,.pullup       = dummy_pullup,.udc_start  = dummy_udc_start,.udc_stop    = dummy_udc_stop,.udc_set_speed    = dummy_udc_set_speed,
};

1.5 usb_ep_ops

1.5.1 dwc3

== dwc3_gadget_init(struct dwc3 *dwc)== dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)== dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)== dep->endpoint.ops = &dwc3_gadget_ep_ops;static const struct usb_ep_ops dwc3_gadget_ep_ops = {.enable        = dwc3_gadget_ep_enable,.disable   = dwc3_gadget_ep_disable,.alloc_request    = dwc3_gadget_ep_alloc_request,.free_request   = dwc3_gadget_ep_free_request,.queue       = dwc3_gadget_ep_queue,.dequeue    = dwc3_gadget_ep_dequeue,.set_halt = dwc3_gadget_ep_set_halt,.set_wedge   = dwc3_gadget_ep_set_wedge,
};

1.5.2 dummy

static const struct usb_ep_ops dummy_ep_ops = {.enable      = dummy_enable,.disable    = dummy_disable,.alloc_request = dummy_alloc_request,.free_request    = dummy_free_request,.queue        = dummy_queue,.dequeue = dummy_dequeue,.set_halt  = dummy_set_halt,.set_wedge    = dummy_set_wedge,
};

2. dummy hcd

== dummy_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)== usb_hcd_link_urb_to_ep(hcd, urb);== timer_pending(&dum_hcd->timer)timer_setup(&dum_hcd->timer, dummy_timer, 0);== dummy_timer(struct timer_list *t)== handle_control_request(dum_hcd, urb, &setup, &status);       //handle control requests== transfer(dum_hcd, urb, ep, limit, &status);       //non-control requests == dummy_perform_transfer(urb, req, len);== memcpy(ubuf, rbuf, len);                 //拷贝数据== usb_gadget_giveback_request(&ep->ep, &req->req);== req->complete(ep, req);== usb_hcd_unlink_urb_from_ep(dummy_hcd_to_hcd(dum_hcd), urb);        //return urb== usb_hcd_giveback_urb(dummy_hcd_to_hcd(dum_hcd), urb, status);

usb udc 驱动相关推荐

  1. USB UDC驱动 gadget驱动

    UDC(USB设备控制器) USB设备控制器(UDC)驱动指的是作为其他USB主机控制器外设的USB硬件设备上底层硬件控制器的驱动,该硬件和驱动负责将一个USB设备依附于一个USB主机控制器上.例如, ...

  2. 第16章 USB主机、设备与Gadget驱动之USB UDC与Gadget驱动(一)

    16.4.1 UDC(USB设备控制器)和Gadget(小配件)驱动的关键数据结构与API USB设备控制器(UDC)驱动指的是作为其他USB主机控制器外设的USB硬件设备上底层硬件控制器的驱动,该硬 ...

  3. USB总线-Linux内核USB3.0设备控制器之UDC驱动分析(六)

    1.概述 UDC驱动的接口都定义在drivers/usb/gadget/udc/core.c文件中.USB Function驱动通过调用这些接口匹配及访问USB设备控制器,而底层USB控制器驱动要实现 ...

  4. usb设备驱动之uvc设备

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

  5. uboot usb设备驱动

    文章目录 DTS中定义 usb driver bind fastboot fastboot命令处理 fastboot触发 介绍usb device设备驱动 uboot在init_dm中会扫描dtb和代 ...

  6. linux usb gadget驱动详解(三)

    本文将对linux4.4.19版本usb gadget源码进行简单分析.鉴于前文反复测试U盘设备驱动,现从linux-4.4.19/drivers/usb/gadget/legacy/mass_sto ...

  7. USB设备驱动学习记录

    0:EHCI主控架构 1.关于设备地址SET_ADDRESS设置的逻辑: 可以看到set_address命令最终通过USB_DRV_WriteReg8(&musb->faddr, g_u ...

  8. USB 网卡驱动数据流

    1. peripheral 1.1 发数据 tx (1)应用层通过系统调用,进入到内核层: (2)内核的数据链路层将数据送入驱动层: (3)USB 网卡驱动将数据发送到 UDC控制器:(将req 写入 ...

  9. Linux-USB驱动笔记(七)--设备控制器(UDC)驱动

    Linux-USB驱动笔记(七)--设备控制器UDC驱动 1.前言 2.设备控制器(UDC) 2.1.usb_gadget -- USB从机设备 2.2.usb_gadget_ops -- UDC操作 ...

最新文章

  1. 来自Mozilla的CSS书写规范建议
  2. 经典角点检测算法实现
  3. 作业(二)—python实现wc命令
  4. BMP图片格式。1,4,8,16,24位与windows分辨率没关系
  5. 巨头纷纷看上的中国Robobus又获1亿美元投资
  6. wordpress 主机伪静态404.php seo,wordpress开启伪静态之后,出现404是什么原因?
  7. 【机器视觉】 ifelse算子(已废弃)
  8. 如何用Python发送通知到微信?
  9. php 解析 标记,如何使用PHP-simple-HTML DOM解析器获取标记的属性
  10. 应用挂载beegfs指定目录_BeeGFS源码分析1-元数据服务概要分析
  11. php ajax国家时间,php ajax 实时显示时间
  12. DelphiX中的DXSprite单元中涉及到修改
  13. 基于React技术栈打造炫酷个人简历实战-郭永峰-专题视频课程
  14. [VCS] coverage hierachy exclude
  15. sprinboot打包jar后读取不到/resource/data/ip2region.xdb的文件.
  16. 2019 deecamp B题不完全的记录
  17. axure怎么制作聊天页面
  18. python从srt文件中只提取歌词
  19. jack分享的1-3开wifi 零火版本智能开关解决方案
  20. android 触摸 唤醒屏幕,android 怎么通过触摸屏幕来唤醒屏幕。

热门文章

  1. 【测试新人必备】测试报告如何编写?
  2. 【图(上)】六度空间
  3. TC的优化--HDB--java api
  4. 土壤含水量仪的监测方法
  5. PIPI OJ 1334: PIPI计数(unordered_map的应用)
  6. 音视频封装格式、编码格式
  7. 每个初恋女子都是相似的
  8. 数学建模的四大基本类型
  9. logdet函数的凹凸性和遍历速率
  10. 分布式架构与Dubbo-1-快速开始