用户操作
[即时聊天] [发私信] [加为好友]
fudan_abcID:fudan_abc
211323次访问,排名330好友0人,关注者35
fudan_abc的文章
原创 226 篇
翻译 0 篇
转载 0 篇
评论 321 篇
最近评论
小鸟:彼岸花的传说(四) 怎么没有啊。。大哥发出来吧!!!!
delta:我很奇怪,不知道博主用的是哪个发行版
要是2.6以上的内核,u盘热插拔应该支持了呀
可能是没有自动挂载,但以博主的能力,这个不是问题呀
呵呵,只是疑惑
很佩服楼主,1万多行的内核代码是很痛苦的
而且内核是个蜘蛛网
绕来绕去的
我看3500行的代码头就吃不消了
小鸟:彼岸花的传说(四)怎么没有???????????

??
小鸟:彼岸花的传说(四)怎么没有???????????

???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
小鸟:彼岸花的传说(四)怎么没有???????????

???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
文章分类
收藏
    相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky

    原创 Linux那些事儿之我是EHCI(4) data structure of ehci driver and device收藏

    新一篇: 内核中的死锁问题--当UHCI遇上OHCI | 旧一篇: Linux那些事儿之我是EHCI(3) pci match 和 probe

    阿扁"辞职"了,kde4发布了,更让我激动的是,英雄志过两天又有更新了,这部连载长达8年的小说,终于要进入精彩的大结局。卢云的命运究竟如何?观海云远,四个性格理念完全不同的人,谁是好,谁是坏,谁是对,谁是错?何谓正道?

    接着上回说,usb_hcd_pci_probe这个函数在"我是UHCI"中也有讨论,不过我想按照我的思路写下去。 

         46 /**
         47  * usb_hcd_pci_probe - initialize PCI-based HCDs
         48  * @dev: USB Host Controller being probed
         49  * @id: pci hotplug id connecting controller to HCD framework
         50  * Context: !in_interrupt()
         51  *
         52  * Allocates basic PCI resources for this USB host controller, and
         53  * then invokes the start() method for the HCD associated with it
         54  * through the hotplug entry's driver_data.
         55  *
         56  * Store this function in the HCD's struct pci_driver as probe().
         57  
    */

         
    58 int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
         
    59 {
         
    60         struct hc_driver        *driver;
         
    61         struct usb_hcd          *hcd;
         
    62         int                     retval;
         
    63
         
    64         if (usb_disabled())
         
    65                 return -ENODEV;
         
    66
         
    67         if (!id || !(driver = (struct hc_driver *) id->driver_data))
         
    68                 return -EINVAL;
         
    69
         
    70         if (pci_enable_device (dev) < 0)
         
    71                 return -ENODEV;
         
    72         dev->current_state = PCI_D0;
         
    73         dev->dev.power.power_state = PMSG_ON;
         
    74
         
    75         if (!dev->irq) {
         
    76                 dev_err (&dev->dev,
         
    77                         "Found HC with no IRQ.  Check BIOS/PCI %s setup! ",
         
    78                         pci_name(dev));
         
    79                 retval = -ENODEV;
         
    80                 goto err1;
         
    81         }

         
    82
         
    83         hcd = usb_create_hcd (driver, &dev->dev, pci_name(dev));
         
    84         if (!hcd) {
         
    85                 retval = -ENOMEM;
         
    86                 goto err1;
         
    87         }

         
    88
         
    89         if (driver->flags & HCD_MEMORY) {       // EHCI, OHCI
         90                 hcd->rsrc_start = pci_resource_start (dev, 0);
         
    91                 hcd->rsrc_len = pci_resource_len (dev, 0);
         
    92                 if (!request_mem_region (hcd->rsrc_start, hcd->rsrc_len,
         
    93                                 driver->description)) {
         
    94                         dev_dbg (&dev->dev, "controller already in use ");
         
    95                         retval = -EBUSY;
         
    96                         goto err2;
         
    97                 }

         
    98                 hcd->regs = ioremap_nocache (hcd->rsrc_start, hcd->rsrc_len);
         
    99                 if (hcd->regs == NULL) {
        
    100                         dev_dbg (&dev->dev, "error mapping memory ");
        
    101                         retval = -EFAULT;
        
    102                         goto err3;
        
    103                 }

        
    104
        
    105         }
     else {                                // UHCI
        106                 int     region;
        
    107
        
    108                 for (region = 0; region < PCI_ROM_RESOURCE; region++{
        
    109                         if (!(pci_resource_flags (dev, region) &
        
    110                                         IORESOURCE_IO))
        
    111                                 continue;
        
    112
        
    113                         hcd->rsrc_start = pci_resource_start (dev, region);
        
    114                         hcd->rsrc_len = pci_resource_len (dev, region);
        
    115                         if (request_region (hcd->rsrc_start, hcd->rsrc_len,
        
    116                                         driver->description))
        
    117                                 break;
        
    118                 }

        
    119                 if (region == PCI_ROM_RESOURCE) {
        
    120                         dev_dbg (&dev->dev, "no i/o regions available ");
        
    121                         retval = -EBUSY;
        
    122                         goto err1;
        
    123                 }

        
    124         }

        
    125
        
    126         pci_set_master (dev);
        
    127
        
    128         retval = usb_add_hcd (hcd, dev->irq, IRQF_SHARED);
        
    129         if (retval != 0)
        
    130                 goto err4;
        
    131         return retval;
        
    132
        
    133  err4:
        
    134         if (driver->flags & HCD_MEMORY) {
        
    135                 iounmap (hcd->regs);
        
    136  err3:
        
    137                 release_mem_region (hcd->rsrc_start, hcd->rsrc_len);
        
    138         }
     else
        
    139                 release_region (hcd->rsrc_start, hcd->rsrc_len);
        
    140  err2:
        
    141         usb_put_hcd (hcd);
        
    142  err1:
        
    143         pci_disable_device (dev);
        
    144         dev_err (&dev->dev, "init %s fail, %d ", pci_name(dev), retval);
        
    145         return retval;
        
    146 }

     

    64行,usb_disabled()判断内核有没有开启支持usb,要是这都不支持,一切都免谈。

    70行,pci_enable_device()这是对ehci三类接口中的pci configuration space进行操作,设置其中某个寄存器的值,使设备处于工作状态。调用pci_read_config_word()pci_write_config_word来读写pci配置空间的寄存器。pci_enable_device -> pci_enable_device_bars -> do_pci_enable_device ...  原理不难,只要对照spec可以看懂。

    7273是电源管理的内容。75判断设备的中断号是否为空。
    83usb_create_hcd() 创建一个usb_hcd机构体。
     
       1480 /**
       1481  * usb_create_hcd - create and initialize an HCD structure
       1482  * @driver: HC driver that will use this hcd
       1483  * @dev: device for this HC, stored in hcd->self.controller
       1484  * @bus_name: value to store in hcd->self.bus_name
       1485  * Context: !in_interrupt()
       1486  *
       1487  * Allocate a struct usb_hcd, with extra space at the end for the
       1488  * HC driver's private data.  Initialize the generic members of the
       1489  * hcd structure.
       1490  *
       1491  * If memory is unavailable, returns NULL.
       1492  
    */

       
    1493 struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
       
    1494                 struct device *dev, char *bus_name)
       
    1495 {
       
    1496         struct usb_hcd *hcd;
       
    1497
       
    1498         hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);
       
    1499         if (!hcd) {
       
    1500                 dev_dbg (dev, "hcd alloc failed ");
       
    1501                 return NULL;
       
    1502         }

       
    1503         dev_set_drvdata(dev, hcd);
       
    1504         kref_init(&hcd->kref);
       
    1505
       
    1506         usb_bus_init(&hcd->self);
       
    1507         hcd->self.controller = dev;
       
    1508         hcd->self.bus_name = bus_name;
       
    1509         hcd->self.uses_dma = (dev->dma_mask != NULL);
       
    1510
       
    1511         init_timer(&hcd->rh_timer);
       
    1512         hcd->rh_timer.function = rh_timer_func;
       
    1513         hcd->rh_timer.data = (unsigned long) hcd;
       
    1514 #ifdef CONFIG_PM
       
    1515         INIT_WORK(&hcd->wakeup_work, hcd_resume_work);
       
    1516 #endif
       
    1517
       
    1518         hcd->driver = driver;
       
    1519         hcd->product_desc = (driver->product_desc) ? driver->product_desc :
       
    1520                         "USB Host Controller";
       
    1521
       
    1522         return hcd;
       
    1523 }

     
    一下子出现了很多数据结构,现在有必要捋一捋它们之间的关系。
    (1)描述驱动的数据结构
     
    ehci主控器的驱动程序需要包括些什么东西?站在pci总线的角度来说,ehci是一个pci的设备,驱动程序里面必须提供操作ehci设备,比如开启(start),关闭(stop),重启(reset),中断的函数。另外,站在usb控制器的角度来说,驱动程序里面还要与底层usb系统交互的函数,如插入\删除urb(rb_enqueue, urb_dequeue)。
     
    pci_driver ehci_pci_driver{
               .........
               .id_table = pci_ids,       ------------>driver_data = (unsigned long) &ehci_pci_hc_driver,
              .probe = usb_hcd_pci_probe
     
    }
    hc_driver ehci_pci_hc_driver{
            ........
           .hcd_priv_size = sizeof(struct ehci_hcd),
     
           .irq =   ehci_irq,
           .reset =  ehci_pci_setup,
           .start =  ehci_run,
           .stop =   ehci_stop,
           .shutdown =  ehci_shutdown,
     
           .urb_enqueue =  ehci_urb_enqueue,
           .urb_dequeue =  ehci_urb_dequeue,
    }
    (2)描述设备的数据结构
     
    usb_hcd{
            ........
            usb_bus .self
           .hcd_priv = ehci_hcd
    }
     
    usb_hcd交大人甲有过论述:linux那些事儿 之 戏说USB(28)设备的生命线 (七) http://blog.csdn.net/fudan_abc/archive/2007/10/18/1831459.aspx
     
    usb_hcd注释上说USB Host Controller Driver,但我更愿意认为它是一个描述一个usb主控制器设备的数据结构。usb_hcd描述了usb主控制器共有的属性,usb_hcd.hcd_priv指向了特定的主控制器数据结构,它描述各自特有的属性。对ehci,是ehci_hcd,对uhci,是uhci_hcd。usb_hcd的成员usb_bus self 是HCD bus-glue layer,usb主控器与总线之间粘合剂。
    这样,1498就好理解了。1506行usb_bus_init初始化usb_hcd.self。 1511-1513初始化 root harbor 计时器。然后就有返回到usb_hcd_pci_probe()

    发表于 @ 2008年01月13日 20:55:00|评论(loading...)|编辑

    新一篇: 内核中的死锁问题--当UHCI遇上OHCI | 旧一篇: Linux那些事儿之我是EHCI(3) pci match 和 probe

    评论

    #javanewbie 发表于2008-07-21 21:40:00  IP: 222.91.180.*
    英雄志,好遥远的名字,孙晓当年不是号称早就写完了吗,怎么还连载了8年,恰如猛虎卧荒丘,潜伏爪牙忍受。
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © fudan_abc