Linux那些事儿之我是EHCI(5) 2008年的这一场雪

来源:互联网 发布:imovie在mac上怎么导出 编辑:程序博客网 时间:2024/05/22 19:42
2008年的这一场雪,比以往时候来的要大一些。以前是买不到票,这次有票也走不了了。
此时此刻,多少兄弟姐妹被困在路上,饥寒交迫,多少城市停电停水,物价飞涨。我真是忍不住破口大骂,好一个和谐盛世!虽说是天灾,但岂无人祸?直接原因是那该死的冻雨。但我认为罪魁乃是三峡工程,以及所谓南水北调。
祝愿那些困在铁路,公路上的人们早日回家团圆,大家过个好年。
还是先看看股市,有消息称,"导致大盘暴跌的原因是因为大面积的降雪, 导致大量的股民滞留车站,机场.无法进入股市抄底, 待在家中人员又因大面积的停电而无法上网操作, 导致了今天的大资金无法介入, 请大家不要恐慌。据不完全统计有60%的基金操盘手被困在机场吃方便面。"
闲话少讲,先补上一张图,
我们接着usb_hcd_pci_probe()往下走,89 - 108行,是为EHCI申请io内存,92行request_mem_region()申请,98行做一次mapping,在EHCI(1)中曾经提到过,EHCI的接口有3种,第一种是PCI配置寄存器,第二种是io内存,第三种就是普通的内存。这里先把EHCI的io内存登记,再做一次ioremap映射成虚拟地址。
接下来126 pci_set_master() 见UHCI 4 http://blog.csdn.net/fudan_abc/archive/2007/10/04/1811451.aspx
128行进入了 usb_add_hcd()
   1548 /** 
   1549 * usb_add_hcd - finish generic HCD structure initialization and register  
   1550 * @hcd: the usb_hcd structure to initialize
   1551 * @irqnum: Interrupt line to allocate
   1552 * @irqflags: Interrupt type flags
   1553 *
   1554 * Finish the remaining parts of generic HCD initialization: allocate the
   1555 * buffers of consistent memory, register the bus, request the IRQ line,
   1556 * and call the driver's reset() and start() routines.
   1557 */
   1558 int usb_add_hcd(struct usb_hcd *hcd,
   1559                 unsigned int irqnum, unsigned long irqflags)
   1560 {
   1561         int retval;
   1562         struct usb_device *rhdev;
   1563
   1564         dev_info(hcd->self.controller, "%s/n", hcd->product_desc);
   1565
   1566         set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
   1567
   1568         /* HC is in reset state, but accessible. Now do the one-time init,
   1569          * bottom up so that hcds can customize the root hubs before khubd
   1570          * starts talking to them. (Note, bus id is assigned early too.)
   1571          */
   1572         if ((retval = hcd_buffer_create(hcd)) != 0) {
   1573                 dev_dbg(hcd->self.controller, "pool alloc failed/n");
   1574                 return retval;
   1575         }
   1576
   1577         if ((retval = usb_register_bus(&hcd->self)) < 0)
   1578                 goto err_register_bus;
   1579
   1580         if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
   1581                 dev_err(hcd->self.controller, "unable to allocate root hub/n");
   1582                 retval = -ENOMEM;
   1583                 goto err_allocate_root_hub;
  1584         }
   1585         rhdev->speed = (hcd->driver->flags & HCD_USB2) ?USB_SPEED_HIGH :
   1586                         USB_SPEED_FULL;
   1587         hcd->self.root_hub = rhdev;
   1588
   1589         /* wakeup flag init defaults to "everything works" for root hubs,
   1590          * but drivers can override it in reset() if needed, along with
   1591          * recording the overall controller's system wakeup capability.
   1592          */
   1593         device_init_wakeup(&rhdev->dev, 1);
   1594
   1595         /* "reset" is misnamed; its role is now one-time init. the controller
   1596          * should already have been reset (and boot firmware kicked off etc).
   1597          */
   1598         if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
   1599                 dev_err(hcd->self.controller, "can't setup/n");
   1600                 goto err_hcd_driver_setup;
   1601         }
   1602
   1603         /* NOTE: root hub and controller capabilities may not be the same */
   1604         if (device_can_wakeup(hcd->self.controller)
   1605                         && device_can_wakeup(&hcd->self.root_hub->dev))
   1606                 dev_dbg(hcd->self.controller, "supports USB remote wakeup/n");
   1607
   1608         /* enable irqs just before we start the controller */
   1609         if (hcd->driver->irq) {
   1610                 snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
   1611                                 hcd->driver->description, hcd->self.busnum);
   1612                 if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
   1613                                 hcd->irq_descr, hcd)) != 0) {
   1614                         dev_err(hcd->self.controller,
   1615                                         "request interrupt %d failed/n", irqnum);
   1616                         goto err_request_irq;
   1617                 }
  1618                 hcd->irq = irqnum;
   1619                 dev_info(hcd->self.controller, "irq %d, %s 0x%08llx/n", irqnum,
   1620                                 (hcd->driver->flags & HCD_MEMORY) ?
   1621                                         "io mem" : "io base",
   1622                                         (unsigned long long)hcd->rsrc_start);
   1623         } else {
   1624                 hcd->irq = -1;
   1625                 if (hcd->rsrc_start)
   1626                         dev_info(hcd->self.controller, "%s 0x%08llx/n", 1627                                         (hcd->driver->flags & HCD_MEMORY) ?
 
   1628                                         "io mem" : "io base",
   1629                                         (unsigned long long)hcd->rsrc_start);
   1630         }
   1631
   1632         if ((retval = hcd->driver->start(hcd)) < 0) {
   1633                 dev_err(hcd->self.controller, "startup error %d/n", retval);
   1634                 goto err_hcd_driver_start;
   1635         }
   1636
   1637         /* starting here, usbcore will pay attention to this root hub */
   1638         rhdev->bus_mA = min(500u, hcd->power_budget);
   1639         if ((retval = register_root_hub(hcd)) != 0)
   1640                 goto err_register_root_hub;
   1641
   1642         if (hcd->uses_new_polling && hcd->poll_rh)
   1643                 usb_hcd_poll_rh_status(hcd);
   1644         return retval;
   1645
   1646 err_register_root_hub:
   1647         hcd->driver->stop(hcd);
   1648 err_hcd_driver_start:
   1649         if (hcd->irq >= 0)
   1650                 free_irq(irqnum, hcd);
   1651 err_request_irq:
   1652 err_hcd_driver_setup:
   1653         hcd->self.root_hub = NULL;
   1654         usb_put_dev(rhdev);
   1655 err_allocate_root_hub:
   1656         usb_deregister_bus(&hcd->self);
   1657 err_register_bus:
   1658         hcd_buffer_destroy(hcd);
   1659         return retval;
   1660 }
1572行hcd_buffer_create()见 UHCI 5 http://blog.csdn.net/fudan_abc/archive/2007/10/10/1818462.aspx。简单总结一下,创建, 摧毁buffur: hcd_buffer_create() / hcd_buffer_destroy(),创建之后,从池子里索取或者把索取的释放回去,usb_buffer_alloc()/usb_buffer_free()。
1577行usb_register_bus见UHCI 6 http://blog.csdn.net/fudan_abc/archive/2007/10/13/1823287.aspx。简单来说,把自己连入到全局变量usb_bus_list中,并调用class_device_create往sysfs新加入一个class。
1580行usb_alloc_dev(),UHCI 7 http://blog.csdn.net/fudan_abc/archive/2007/10/16/1827449.aspx。
1598行之前,都和UHCI没有什么分别,hcd->driver->reset指向的是,ehci_pci_hc_driver.ehci_pci_setup()


转至http://blog.csdn.net/fudan_abc/article/details/2070570