[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,
- static const struct hc_driver ehci_atmel_hc_driver = {
- .description = hcd_name,
- .product_desc = "Atmel EHCI UHP HS",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- /* generic hardware linkage */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
- /* basic lifecycle operations */
- .reset = ehci_atmel_setup,
- .start = ehci_run,
- .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,
- };
- static struct platform_device at91_usbh_ehci_device = {
- .name = "atmel-ehci",
- .id = -1,
- .dev = {
- .dma_mask = &ehci_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &usbh_ehci_data,
- },
- .resource = usbh_ehci_resources,
- .num_resources = ARRAY_SIZE(usbh_ehci_resources),
- };
bus_name是atmel-ehci.
- /**
- * usb_create_hcd - create and initialize an HCD structure
- * @driver: HC driver that will use this hcd
- * @dev: device for this HC, stored in hcd->self.controller
- * @bus_name: value to store in hcd->self.bus_name
- * Context: !in_interrupt()
- *
- * Allocate a struct usb_hcd, with extra space at the end for the
- * HC driver's private data. Initialize the generic members of the
- * hcd structure.
- *
- * If memory is unavailable, returns NULL.
- */
- struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
- struct device *dev, const char *bus_name)
- {
- return usb_create_shared_hcd(driver, dev, bus_name, NULL);
- }
- EXPORT_SYMBOL_GPL(usb_create_hcd);
- /**
- * usb_create_shared_hcd - create and initialize an HCD structure
- * @driver: HC driver that will use this hcd
- * @dev: device for this HC, stored in hcd->self.controller
- * @bus_name: value to store in hcd->self.bus_name
- * @primary_hcd: a pointer to the usb_hcd structure that is sharing the
- * PCI device. Only allocate certain resources for the primary HCD
- * Context: !in_interrupt()
- *
- * Allocate a struct usb_hcd, with extra space at the end for the
- * HC driver's private data. Initialize the generic members of the
- * hcd structure.
- *
- * If memory is unavailable, returns NULL.
- */
- struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
- struct device *dev, const char *bus_name,
- struct usb_hcd *primary_hcd)
- {
- struct usb_hcd *hcd;
- hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);
- if (!hcd) {
- dev_dbg (dev, "hcd alloc failed\n");
- return NULL;
- }
- if (primary_hcd == NULL) {
- hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),
- GFP_KERNEL);
- if (!hcd->bandwidth_mutex) {
- kfree(hcd);
- dev_dbg(dev, "hcd bandwidth mutex alloc failed\n");
- return NULL;
- }
- mutex_init(hcd->bandwidth_mutex);
- dev_set_drvdata(dev, hcd);
- } else {
- hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex;
- hcd->primary_hcd = primary_hcd;
- primary_hcd->primary_hcd = primary_hcd;
- hcd->shared_hcd = primary_hcd;
- primary_hcd->shared_hcd = hcd;
- }
- kref_init(&hcd->kref);
- usb_bus_init(&hcd->self);
- hcd->self.controller = dev;
- hcd->self.bus_name = bus_name;
- hcd->self.uses_dma = (dev->dma_mask != NULL);
- init_timer(&hcd->rh_timer);
- hcd->rh_timer.function = rh_timer_func;
- hcd->rh_timer.data = (unsigned long) hcd;
- #ifdef CONFIG_USB_SUSPEND
- INIT_WORK(&hcd->wakeup_work, hcd_resume_work);
- #endif
- hcd->driver = driver;
- hcd->speed = driver->flags & HCD_MASK;
- hcd->product_desc = (driver->product_desc) ? driver->product_desc :
- "USB Host Controller";
- return hcd;
- }
- EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
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