mini2440 usb host device controller驱动分析(三)-----root hub驱动的分析(一)

本文深入分析了mini2440平台上的USB Root Hub驱动,重点探讨了如何检测设备的插拔。内容包括Root Hub的物理电路、端口功能设定、hub的初始化过程以及设备插拔感应的机制。通过hub_irq、hub_thread和hub_events等关键函数,揭示了Root Hub在设备连接和断开时的响应流程。
摘要由CSDN通过智能技术生成

    在我看来,roothub的功能主要有两个:一是感应设备的插拔,在一个是对新插入的设备进行配置。 

     root hub 是怎么感应到设备的插拔的?

     这里开始分析root hub的驱动。之前已经提到过每个host controller都集成有一个root hub。通过看2440的datasheet中的host controller部分,我们可以看到root hub是有相应的物理电路的,并不是host controller虚拟了一个root hub。2440的root hub共有两个port,但是在mini2440上面只连了一个host的接口。

从旁边的图上可以看出,DN0和DP0是第一个host port的引脚。DN1和DP1是第二个host port的引脚,但是这两个引脚是和udc 的引脚PDN0\PDP0复用的,在mini2440中这个复用的引脚用作了udc的port。但是这里有个问题,是怎么设定这两个复用的引脚的功能的?

root hub的一个很重要的功能就是检测到设备的插拔,有usb device插入时,对设备进行一定部分的初始化。但是有一个需要注意的是,读写usb device,并不需要通过usb root hub,都是hcd直接读写寄存器进行的,不需要通过root hub的传递。root hub对插入的设备进行读写也是通过submit urb来实现的。

先看root hub的表示。与root hub相关的结构体有两个usb_hub和hub_driver。

struct usb_hub {
	struct device		*intfdev;	/* the "interface" device */
	struct usb_device	*hdev;
	struct kref		kref;
	struct urb		*urb;		/* for interrupt polling pipe */

	/* buffer for urb ... with extra space in case of babble */
	char			(*buffer)[8];
	dma_addr_t		buffer_dma;	/* DMA address for buffer */
	union {
		struct usb_hub_status	hub;
		struct usb_port_status	port;
	}  *status;	                            /* buffer for status reports */
	struct mutex		status_mutex;	/* for the status buffer */

	int			error;		/* last reported error */
	int			nerrors;	/* track consecutive errors */

	struct list_head	event_list;	/* hubs w/data or errs ready */
	unsigned long		event_bits[1];	/* status change bitmask */
	unsigned long		change_bits[1];	/* ports with logical connect
							status change */
	unsigned long		busy_bits[1];	/* ports being reset or
							resumed */
#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
#error event_bits[] is too short!
#endif

	struct usb_hub_descriptor *descriptor;	/* class descriptor */
	struct usb_tt		tt;		/* Transaction Translator */

	unsigned		mA_per_port;	/* current for each child */

	unsigned		limited_power:1;
	unsigned		quiescing:1;
	unsigned		disconnected:1;

	unsigned		has_indicators:1;
	u8			indicator[USB_MAXCHILDREN];
	struct delayed_work	leds;
	struct delayed_work	init_work;
	void			**port_owners;
};

在内核中实现了专门针对usb hub的驱动,叫hub_driver。

static struct usb_driver hub_driver = {
	.name =		"hub",
	.probe =	hub_probe,
	.disconnect =	hub_disconnect,
	.suspend =	hub_suspend,
	.resume =	hub_resume,
	.reset_resume =	hub_reset_resume,
	.pre_reset =	hub_pre_reset,
	.post_reset =	hub_post_reset,
	.ioctl =	hub_ioctl,
	.id_table =	hub_id_table,
	.supports_autosuspend =	1,
};



 之前在hcd的初始化驱动中有register_root_hub,这个函数经过device_add等一系列调用,最终会调用到usb hub的probe函数,即hub_probe。(调用到hub_probe时候,可以看到这个函数参数就已经变成了usb_interface,这个过程还需要以后的分析)。

 

static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_host_interface *desc;
	struct usb_endpoint_descriptor *endpoint;
	struct usb_device *hdev;
	struct usb_hub *hub;

	desc = intf->cur_altsetting;
	hdev = interface_to_usbdev(intf);

	endpoint = &desc->endpoint[0].desc;

	/* We found a hub */
	dev_info (&intf->dev, "USB hub found\n");

	hub = kzalloc(sizeof(*hub), GFP_KERNEL);
	if (!hub) {
		dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n");
		return -ENOMEM;
	}

	kref_i
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值