关闭

Linux USB subsystem --- USB create HCD

标签: linuxstructresourcesstructurenulltimer
3174人阅读 评论(0) 收藏 举报
分类:

目的:对USB作深入学习,在此留下笔记。欢迎讨论。


[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,
};
其中dev是,如下的dev

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_hcd的目的:创建并且初始化一个HCD结构体。实际是调用usb_create_shared_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);
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



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:388747次
    • 积分:5317
    • 等级:
    • 排名:第5092名
    • 原创:132篇
    • 转载:17篇
    • 译文:7篇
    • 评论:57条
    博客专栏
    最新评论