现在的位置: 首页 > 综合 > 正文

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

2013年09月10日 ⁄ 综合 ⁄ 共 6492字 ⁄ 字号 评论关闭

阿扁"辞职"了,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                         "

抱歉!评论已关闭.