Chinaunix首页 | 论坛 | 博客
  • 博客访问: 216829
  • 博文数量: 32
  • 博客积分: 410
  • 博客等级: 一等列兵
  • 技术积分: 396
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-03 16:58
文章分类

全部博文(32)

文章存档

2013年(17)

2012年(15)

我的朋友

分类: LINUX

2013-04-02 11:51:25

代码追溯:
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) |
给主人留下些什么吧!~~