参考:
USB芯片到底完成了哪些工作?
usb-phy
ehci0: usb@01c1a000 {
compatible = "allwinner,sun8i-v3s-ehci", "generic-ehci";
reg = <0x01c1a000 0x100>;
interrupts = ;
clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>;
resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
status = "disabled";
};
ohci0: usb@01c1a400 {
compatible = "allwinner,sun8i-v3s-ohci", "generic-ohci";
reg = <0x01c1a400 0x100>;
interrupts = ;
clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>,
<&ccu CLK_USB_OHCI0>;
resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
status = "disabled";
};
linux-5.1.0\drivers\usb\host\ohci-platform.c
linux-5.1.0\drivers\usb\host\ehci-platform.c
linux-5.1.0\include\linux\usb\hcd.h
struct usb_hcd; // usb_hcd —— USB Host Controller Driver
通过usb_create_hcd创建一个usb_hcd对象。
linux-5.1.0\drivers\usb\core\hcd.c
int usb_add_hcd(struct usb_hcd *hcd, unsigned int irqnum, unsigned long irqflags);
将usb_hcd对象加入到usb核心层
linux-5.1.0\drivers\usb\core\usb.c
static int __init usb_init(void)
retval = bus_register(&usb_bus_type); // struct bus_type usb_bus_typ,其中有match函数匹配驱动与设备
retval = usb_hub_init();
linux-5.1.0\drivers\usb\core\hub.c
if (usb_register(&hub_driver) < 0);
.probe = hub_probe, // 等待hub device (usb_new_device)
hub_wq = alloc_workqueue("usb_hub_wq", WQ_FREEZABLE, 0); // hub_wq 该wq暂时未跑起来
linux-5.1.0\drivers\usb\host\ohci-platform.c
static int ohci_platform_probe(struct platform_device *dev)
linux-5.1.0\drivers\usb\core\hcd.c
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
/* starting here, usbcore will pay attention to this root hub */
retval = register_root_hub(hcd); // root register也是core的hcd中提供
retval = usb_new_device (usb_dev);
linux-5.1.0\drivers\usb\core\hub.c
err = device_add(&udev->dev); // 添加设备,hub_probe会被调用
hub_probe
// hub event的初始化
INIT_WORK(&hub->events, hub_event); // hub_event 会被queue_work触发,传递的参数是hub->events
hub_event // 当queue_work触发
hub = container_of(work, struct usb_hub, events); // events只是用来传usb_hub(子类与父类)
// hub 的配置
if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)
// hub usb中断事件
usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,hub, endpoint->bInterval);
// 当hub usb 中断触发
static void hub_irq(struct urb *urb)
// 触发hub event
kick_hub_wq(hub);
usb_hc_died (hcd)
linux-5.1.0\drivers\usb\core\hub.c // hub与hcd一样,是core中独立的一个文件
/* make hub_wq clean up old urbs and devices */
usb_set_device_state (hcd->self.root_hub, USB_STATE_NOTATTACHED);
usb_kick_hub_wq(hcd->self.root_hub);
// 触发hub event
kick_hub_wq(hub);
if (queue_work(hub_wq, &hub->events)) // hub_wq, 就是core层初始化时候的wq
static void hub_event(struct work_struct *work) // 处理hub事件