代码追溯:
module_init(ehci_hcd_init);
-->static int __init ehci_hcd_init(void)
-->retval = pci_register_driver(&PCI_DRIVER);(此处为 ehci_pci_driver)
/*******************************************************************************/
PCI驱动
static struct pci_driver ehci_pci_driver = {
.name = (char *) hcd_name,
.id_table = pci_ids,
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
.shutdown = usb_hcd_pci_shutdown,
......
};
//BUS总线
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
.uevent = pci_uevent,
.probe = pci_device_probe,
.remove = pci_device_remove,
.shutdown = pci_device_shutdown,
.dev_attrs = pci_dev_attrs,
.bus_attrs = pci_bus_attrs,
.pm = PCI_PM_OPS_PTR,
};
//设备列表
static const struct pci_device_id pci_ids [] = { {
/* handle any USB 2.0 EHCI controller */
PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
.driver_data = (unsigned long) &ehci_pci_hc_driver,
},
{ /* end: all zeroes */ }
};
//
特定host control 驱动;
static const struct hc_driver ehci_pci_hc_driver = {
.description = hcd_name,
.product_desc = "EHCI Host Controller",
.hcd_priv_size = sizeof(struct ehci_hcd),
/*
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2,
/*
* basic lifecycle operations
*/
.reset = ehci_pci_setup,
.start = ehci_run,
#ifdef CONFIG_PM
.pci_suspend = ehci_pci_suspend,
.pci_resume = ehci_pci_resume,
#endif
.stop = ehci_stop,
.shutdown = ehci_shutdown,
/*
* managing i/o requests and associated device resources
*/
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
/*
* scheduling support
*/
.get_frame_number = ehci_get_frame,
/*
* root hub support
*/
.hub_status_data = ehci_hub_status_data,
.hub_control = ehci_hub_control,
.bus_suspend = ehci_bus_suspend,
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
/*******************************************************************************/
驱动套路
driver_register(struct device_driver * drv) -> bus_add_driver() -> driver_attach() ->
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
bus_for_each_dev 遍历该总线上所有的 device ,执行一次__driver_attach() ,看能不能将驱动关联(attach)到某个设备上去。
__driver_attach()
->driver_probe_device()
->drv->bus->match(dev, drv), // 调用 bus 的match函数,看device 和driver 匹不匹配。
在此处执行pci_bus_match
如果匹配上, 继续执行really_probe() 。
->really_probe()
->dev->bus->probe(dev):(如果bus->probe 非空,则调用 bus->probe)
在此处执行pci_device_probe
->driver->probe() :(如果driver->probe 非空,则调用 driver->probe)
在此处不执行任何代码
pci_device_probe执行:
pci_device_probe()
---> __pci_device_probe()
---> pci_call_probe()
---> ( pci_driver->probe() )
在此处执行ehci_pci_driver->probe = usb_hcd_pci_probe() ;(pci_driver)
/....................................................................................../
如此重要的函数:
int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct usb_hcd *hcd;
driver = (struct hc_driver *)id->driver_data;//指向ehci_pci_hc_driver
........
hub的诞生;不是讲历史,仅仅是讲如何生出来的;如何由泥土变砖头,然后再去砌墙;
不管是UHCI,还是 EHCI,一般来说都是 PCI 设备,是PCI 设备都应该有个 struct pci_driver
结构体,都应该有一个属于自己的 probe 。在这个probe 里,也都会调用usb_create_hcd()
来创建一个属于自己的usb_hcd,也都会调用 usb_add_hcd() 将这个刚刚创建的usb_hcd注册到usb 组织里。
//生成一个host control对象;一个控制器就一条总线;
hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));//创建hcd对象;指定的驱动ehci_pci_hc_driver,和找到的设备;
//此函数中重要赋值hcd->self.controller = dev; hcd->driver = driver;
..........
pci_set_master(dev);
//添加此控制器,登记此条总线;分配和初始化roothub
retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED);
..........
}
//
int usb_add_hcd(struct usb_hcd *hcd,unsigned int irqnum, unsigned long irqflags)
{
int retval;
struct usb_device *rhdev;
.......
//buffer created
if ((retval = hcd_buffer_create(hcd)) != 0) {
dev_dbg(hcd->self.controller, "pool alloc failed\n");
return retval;
}
if ((retval = usb_register_bus(&hcd->self)) < 0)
goto err_register_bus;
//每一个USB控制器都有一个根集线器.这里也要为总线下的根集钱器创建相应的结构, usb_alloc_dev()用来生成并初始化的usb_device结构
if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
dev_err(hcd->self.controller, "unable to allocate root hub\n");
retval = -ENOMEM;
goto err_allocate_root_hub;
}
switch (hcd->driver->flags & HCD_MASK) {
case HCD_USB11:
rhdev->speed = USB_SPEED_FULL;
break;
case HCD_USB2:
rhdev->speed = USB_SPEED_HIGH;
break;
case HCD_USB3:
rhdev->speed = USB_SPEED_SUPER;
break;
default:
goto err_allocate_root_hub;
}
hcd->self.root_hub = rhdev;
device_init_wakeup(&rhdev->dev, 1);
if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
dev_err(hcd->self.controller, "can't setup\n");
goto err_hcd_driver_setup;
}
if ((retval = hcd->driver->start(hcd)) < 0) {
dev_err(hcd->self.controller, "startup error %d\n", retval);
goto err_hcd_driver_start;
}
/* starting here, usbcore will pay attention to this root hub */
rhdev->bus_mA = min(500u, hcd->power_budget);
if ((retval = register_root_hub(hcd)) != 0)
goto err_register_root_hub;
if (hcd->uses_new_polling && hcd->poll_rh)
usb_hcd_poll_rh_status(hcd);
return retval;
return retval;
}
//PCI--->HCD--->(EHCI)--->ROOTHUB--->(USB)
usb控制器驱动为PCI驱动;roothub驱动为usb驱动;
ehci_hcd_init()通过注册PCI驱动(ehci_pci_driver),引用到PCI总线匹配(pci_bus_match)和总线探测(pci_device_probe),总线的探测又会引发PCI驱动的探测(ehci_pci_driver->probe)==ehci_pci_driver->probe = usb_hcd_pci_probe() ,最终在此处同通过usb_create_hcd创建host控制器,初始化,usb_add_hcd创建roothub对象,勾搭到usb驱动上去;
阅读(1762) | 评论(0) | 转发(0) |