debug:
ls /sys/class/udc //查看系统注册了的udc驱动
== 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_ep
dep->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 设备
== 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_ep
ep->ep.ops = &dummy_ep_ops; // usb_ep 的ops
dum->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);
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 support
struct 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 support
struct dummy_hcd *hs_hcd;
struct dummy_hcd *ss_hcd;
}
\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();
== 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)
== 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的完成函数
与dwc3
一样。
== 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);
usb_gadget_ops
函数集,这些函数主要是操作UDC
设备的一些特性(针对设备)。
当enable/disable gadget
的时候,会调用到相关接口。
== 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,
};
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,
};
== 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,
};
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,
};
== 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);