Linux USB subsystem --- USB create HCD

Linux USB subsystem --- USB create HCD

[Linux-3.2][drivers/usb/core/hcd.c]

函数:usb_create_hcd(const struct hc_driver *driver, struct device *dev, const char *bus_name)

其中hc_driver是ehci_atmel_hc_driver,

[cpp] view plain copy
  1. static const struct hc_driver ehci_atmel_hc_driver = {  
  2.     .description        = hcd_name,  
  3.     .product_desc       = "Atmel EHCI UHP HS",  
  4.     .hcd_priv_size      = sizeof(struct ehci_hcd),  
  5.   
  6.     /* generic hardware linkage */  
  7.     .irq            = ehci_irq,  
  8.     .flags          = HCD_MEMORY | HCD_USB2,  
  9.   
  10.     /* basic lifecycle operations */  
  11.     .reset          = ehci_atmel_setup,  
  12.     .start          = ehci_run,  
  13.     .stop           = ehci_stop,  
  14.     .shutdown       = ehci_shutdown,  
  15.   
  16.     /* managing i/o requests and associated device resources */  
  17.     .urb_enqueue        = ehci_urb_enqueue,  
  18.     .urb_dequeue        = ehci_urb_dequeue,  
  19.     .endpoint_disable   = ehci_endpoint_disable,  
  20.     .endpoint_reset     = ehci_endpoint_reset,  
  21.   
  22.     /* scheduling support */  
  23.     .get_frame_number   = ehci_get_frame,  
  24.   
  25.     /* root hub support */  
  26.     .hub_status_data    = ehci_hub_status_data,  
  27.     .hub_control        = ehci_hub_control,  
  28.     .bus_suspend        = ehci_bus_suspend,  
  29.     .bus_resume     = ehci_bus_resume,  
  30.     .relinquish_port    = ehci_relinquish_port,  
  31.     .port_handed_over   = ehci_port_handed_over,  
  32.   
  33.     .clear_tt_buffer_complete   = ehci_clear_tt_buffer_complete,  
  34. };  
其中dev是,如下的dev

[cpp] view plain copy
  1. static struct platform_device at91_usbh_ehci_device = {  
  2.     .name       = "atmel-ehci",  
  3.     .id     = -1,  
  4.     .dev        = {  
  5.                 .dma_mask       = &ehci_dmamask,  
  6.                 .coherent_dma_mask  = DMA_BIT_MASK(32),  
  7.                 .platform_data      = &usbh_ehci_data,  
  8.     },  
  9.     .resource   = usbh_ehci_resources,  
  10.     .num_resources  = ARRAY_SIZE(usbh_ehci_resources),  
  11. };  

bus_name是atmel-ehci.

[cpp] view plain copy
  1. /** 
  2.  * usb_create_hcd - create and initialize an HCD structure 
  3.  * @driver: HC driver that will use this hcd 
  4.  * @dev: device for this HC, stored in hcd->self.controller 
  5.  * @bus_name: value to store in hcd->self.bus_name 
  6.  * Context: !in_interrupt() 
  7.  * 
  8.  * Allocate a struct usb_hcd, with extra space at the end for the 
  9.  * HC driver's private data.  Initialize the generic members of the 
  10.  * hcd structure. 
  11.  * 
  12.  * If memory is unavailable, returns NULL. 
  13.  */  
  14. struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,  
  15.         struct device *dev, const char *bus_name)  
  16. {  
  17.     return usb_create_shared_hcd(driver, dev, bus_name, NULL);  
  18. }  
  19. EXPORT_SYMBOL_GPL(usb_create_hcd);  
usb_create_hcd的目的:创建并且初始化一个HCD结构体。实际是调用usb_create_shared_hcd来实现。

[cpp] view plain copy
  1. /** 
  2.  * usb_create_shared_hcd - create and initialize an HCD structure 
  3.  * @driver: HC driver that will use this hcd 
  4.  * @dev: device for this HC, stored in hcd->self.controller 
  5.  * @bus_name: value to store in hcd->self.bus_name 
  6.  * @primary_hcd: a pointer to the usb_hcd structure that is sharing the 
  7.  *              PCI device.  Only allocate certain resources for the primary HCD 
  8.  * Context: !in_interrupt() 
  9.  * 
  10.  * Allocate a struct usb_hcd, with extra space at the end for the 
  11.  * HC driver's private data.  Initialize the generic members of the 
  12.  * hcd structure. 
  13.  * 
  14.  * If memory is unavailable, returns NULL. 
  15.  */  
  16. struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,  
  17.         struct device *dev, const char *bus_name,  
  18.         struct usb_hcd *primary_hcd)  
  19. {  
  20.     struct usb_hcd *hcd;  
  21.     hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);  
  22.     if (!hcd) {  
  23.         dev_dbg (dev, "hcd alloc failed\n");  
  24.         return NULL;  
  25.     }  
  26.     if (primary_hcd == NULL) {  
  27.         hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),  
  28.                 GFP_KERNEL);  
  29.         if (!hcd->bandwidth_mutex) {  
  30.             kfree(hcd);  
  31.             dev_dbg(dev, "hcd bandwidth mutex alloc failed\n");  
  32.             return NULL;  
  33.         }  
  34.         mutex_init(hcd->bandwidth_mutex);  
  35.         dev_set_drvdata(dev, hcd);  
  36.     } else {  
  37.         hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex;  
  38.         hcd->primary_hcd = primary_hcd;  
  39.         primary_hcd->primary_hcd = primary_hcd;  
  40.         hcd->shared_hcd = primary_hcd;  
  41.         primary_hcd->shared_hcd = hcd;  
  42.     }  
  43.     kref_init(&hcd->kref);  
  44.     usb_bus_init(&hcd->self);  
  45.     hcd->self.controller = dev;  
  46.     hcd->self.bus_name = bus_name;  
  47.     hcd->self.uses_dma = (dev->dma_mask != NULL);  
  48.     init_timer(&hcd->rh_timer);  
  49.     hcd->rh_timer.function = rh_timer_func;  
  50.     hcd->rh_timer.data = (unsigned long) hcd;  
  51. #ifdef CONFIG_USB_SUSPEND  
  52.     INIT_WORK(&hcd->wakeup_work, hcd_resume_work);  
  53. #endif  
  54.     hcd->driver = driver;  
  55.     hcd->speed = driver->flags & HCD_MASK;  
  56.     hcd->product_desc = (driver->product_desc) ? driver->product_desc :  
  57.             "USB Host Controller";  
  58.     return hcd;  
  59. }  
  60. EXPORT_SYMBOL_GPL(usb_create_shared_hcd);  
usb_create_shared_hcd(driver, dev, bus_name, NULL);
1. 首先分配一个hcd的内存空间,包含私有数据空间。

2. primary_hcd == NULL,分配一个互斥。并且初始化一个互斥。

3. 引用计数加1;

4. dev_set_drvdata(dev, hcd);

因为dev->p为空,所以调用device_private_init(dev)。

5. usb_bus_init

6. return hcd


你可能感兴趣的:(Linux USB subsystem --- USB create HCD)