一、usb子系统

一、usb子系统相关结构体

 1. usb总线

struct usb_bus {
	struct device *controller;	
	int busnum;	//总线号
	const char *bus_name;	//总线名
	u8 uses_dma;
	u8 uses_pio_for_control;
	u8 otg_port;
	unsigned is_b_host:1;
	unsigned b_hnp_enable:1;
	unsigned sg_tablesize;
	int devnum_next;	//下一个地址
	struct usb_devmap devmap;	//usb设备地址表
	struct usb_device *root_hub;	//根hub
	struct usb_bus *hs_companion;
	struct list_head bus_list;	//总线链表
	int bandwidth_allocated;
	int bandwidth_int_reqs;
	int bandwidth_isoc_reqs;
#ifdef CONFIG_USB_DEVICEFS
	struct dentry *usbfs_dentry;
#endif
#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
	struct mon_bus *mon_bus;
	int monitored;
#endif
};

2. usb hub

struct usb_hub {
	struct device	*intfdev;
	struct usb_device	*hdev;	//usb设备
	struct kref	kref;
	struct urb	*urb;	
	char	(*buffer)[8];
	union {
		struct usb_hub_status	hub;
		struct usb_port_status	port;
	}*status;
	struct mutex	status_mutex;
	int	error;	//出错标志
	int	nerrors;
	struct list_head	event_list;	//事件链表
	unsigned long	event_bits[1];
	unsigned long	change_bits[1];
	unsigned long	busy_bits[1];
	unsigned long	removed_bits[1];
#if USB_MAXCHILDREN > 31
#error event_bits[] is too short!
#endif
	struct usb_hub_descriptor *descriptor;	//hub描述符
	struct usb_tt	tt;
	unsigned	mA_per_port;	//每个端口电流量
	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;
};

3. usb主控器驱动

struct hc_driver {
	const char *description;	//主控器类型
	const char *product_desc;	//厂商字串
	size_t hcd_priv_size;	//私有数据大小
	irqreturn_t	(*irq) (struct usb_hcd *hcd);
	int flags;	//版本标志
	int (*reset) (struct usb_hcd *hcd);	//重置
	int (*start) (struct usb_hcd *hcd);	//启动
	int (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup);
	int (*pci_resume)(struct usb_hcd *hcd, bool hibernated);
	void (*stop) (struct usb_hcd *hcd);	//停止
	void (*shutdown) (struct usb_hcd *hcd);	//关闭
	int (*get_frame_number) (struct usb_hcd *hcd);
	int (*urb_enqueue)(struct usb_hcd *hcd,struct urb *urb, gfp_t mem_flags);
	int (*urb_dequeue)(struct usb_hcd *hcd,struct urb *urb, int status);
	void (*endpoint_disable)(struct usb_hcd *hcd,struct usb_host_endpoint *ep);
	void (*endpoint_reset)(struct usb_hcd *hcd,struct usb_host_endpoint *ep);
	int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
	int (*hub_control) (struct usb_hcd *hcd,u16 typeReq, u16 wValue, u16 wIndex,char *buf, u16 wLength);
	int (*bus_suspend)(struct usb_hcd *);	//总线挂起
	int (*bus_resume)(struct usb_hcd *);
	int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
	void (*relinquish_port)(struct usb_hcd *, int);
	int (*port_handed_over)(struct usb_hcd *, int);
	void (*clear_tt_buffer_complete)(struct usb_hcd *,struct usb_host_endpoint *);
	void (*recover_hcd)(struct work_struct *data);
	int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
	void (*free_dev)(struct usb_hcd *, struct usb_device *);
	int (*alloc_streams)(struct usb_hcd *hcd, struct usb_device *udev,struct usb_host_endpoint **eps, 
						unsigned int num_eps,unsigned int num_streams, gfp_t mem_flags);
	int (*free_streams)(struct usb_hcd *hcd, struct usb_device *udev,struct usb_host_endpoint **eps, 
						unsigned int num_eps,gfp_t mem_flags);
	int (*add_endpoint)(struct usb_hcd *, struct usb_device *,struct usb_host_endpoint *);
	int (*drop_endpoint)(struct usb_hcd *, struct usb_device *,struct usb_host_endpoint *);
	int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);
	void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
	int (*address_device)(struct usb_hcd *, struct usb_device *udev);
	int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev,struct usb_tt *tt, gfp_t mem_flags);
	int (*reset_device)(struct usb_hcd *, struct usb_device *);
	int (*update_device)(struct usb_hcd *, struct usb_device *);
};

4. usb主控器设备

struct usb_hcd {
	struct usb_bus self;
	struct kref kref;
	const char *product_desc;	//厂商字串
	char irq_descr[24];
	struct timer_list rh_timer;	//轮询定时器
	struct urb *status_urb;	//urb状态
#ifdef CONFIG_USB_SUSPEND
	struct work_struct	wakeup_work;
#endif
	struct work_struct ehci_omap_work;
	const struct hc_driver *driver;
	unsigned long flags;
	unsigned rh_registered:1;
	unsigned rh_pollable:1;
	unsigned uses_new_polling:1;
	unsigned wireless:1;
	unsigned authorized_default:1;
	unsigned has_tt:1;
	int irq;	//中断号
	void __iomem *regs;	//设备内存
	u64 rsrc_start;	//设备内存资源起始地址
	u64 rsrc_len;	//设备内存资源长度
	unsigned power_budget;
	struct mutex bandwidth_mutex;
	struct dma_pool *pool[HCD_BUFFER_POOLS];
	int state;
	unsigned long hcd_priv[0] __attribute__ ((aligned(sizeof(unsigned long))));
};

5. usb设备驱动

struct usb_driver {
	const char *name;	//usb驱动名
	int (*probe) (struct usb_interface *intf,const struct usb_device_id *id);	//插入
	void (*disconnect) (struct usb_interface *intf);	//拔出
	int (*unlocked_ioctl) (struct usb_interface *intf, unsigned int code,void *buf);	//控制
	int (*suspend) (struct usb_interface *intf, pm_message_t message);	//挂起
	int (*resume) (struct usb_interface *intf);	//唤醒
	int (*reset_resume)(struct usb_interface *intf);	//复位唤醒
	int (*pre_reset)(struct usb_interface *intf);	//预复位
	int (*post_reset)(struct usb_interface *intf);	
	const struct usb_device_id *id_table;	//支持设备id表
	struct usb_dynids dynids;
	struct usbdrv_wrap drvwrap;	//设备驱动的一个封装
	unsigned int no_dynamic_id:1;
	unsigned int supports_autosuspend:1;
	unsigned int soft_unbind:1;
};

6. usb设备

struct usb_device {
	int	devnum;	//usb设备地址
	char	devpath[16];	//usb树中的路径
	u32	route;
	enum usb_device_state	state;	//usb设备状态
	enum usb_device_speed	speed;	//usb速度
	struct usb_tt	*tt;
	int	ttport;
	unsigned int toggle[2];
	struct usb_device *parent;	//父设备hub
	struct usb_bus *bus;	//总线
	struct usb_host_endpoint ep0;	//端点0
	struct device dev;	//设备文件
	struct usb_device_descriptor descriptor;	//设备描述符
	struct usb_host_config *config;	
	struct usb_host_config *actconfig;
	struct usb_host_endpoint *ep_in[16];	//输入端点
	struct usb_host_endpoint *ep_out[16];	//输出端点
	char **rawdescriptors;
	unsigned short bus_mA;	//总线电流限值
	u8 portnum;	//端口数
	u8 level;	//所处hub层数
	unsigned can_submit:1;
	unsigned persist_enabled:1;
	unsigned have_langid:1;
	unsigned authorized:1;
	unsigned authenticated:1;
	unsigned wusb:1;
	int string_langid;
	char *product;	//产品id
	char *manufacturer;	//厂商id
	char *serial;
	struct list_head filelist;
#ifdef CONFIG_USB_DEVICE_CLASS
	struct device *usb_classdev;
#endif
#ifdef CONFIG_USB_DEVICEFS
	struct dentry *usbfs_dentry;	//usbfs入口
#endif
	int maxchild;	//最大子设备个数
	struct usb_device *children[USB_MAXCHILDREN];	//子设备数组
	u32 quirks;
	atomic_t urbnum;
	unsigned long active_duration;
#ifdef CONFIG_PM
	unsigned long last_busy;
	int autosuspend_delay;
	unsigned long connect_time;
	unsigned do_remote_wakeup:1;
	unsigned reset_resume:1;
#endif
	struct wusb_dev *wusb_dev;
	int slot_id;
};

7. usb接口

struct usb_interface {
	struct usb_host_interface *altsetting;
	struct usb_host_interface *cur_altsetting;	
	unsigned num_altsetting;
	struct usb_interface_assoc_descriptor *intf_assoc;
	int minor;
	enum usb_interface_condition condition;
	unsigned sysfs_files_created:1;
	unsigned ep_devs_created:1;
	unsigned unregistering:1;
	unsigned needs_remote_wakeup:1;
	unsigned needs_altsetting0:1;
	unsigned needs_binding:1;
	unsigned reset_running:1;
	unsigned resetting_device:1;
	struct device dev;
	struct device *usb_dev;
	atomic_t pm_usage_cnt;
	struct work_struct reset_ws;
};

8. usb请求块urb

struct urb {
	struct kref kref;	//参考计数
	void *hcpriv;
	atomic_t use_count;
	atomic_t reject;
	int unlinked;
	struct list_head urb_list;	//urb链表头
	struct list_head anchor_list;
	struct list_head giveback_list;
	struct usb_anchor *anchor;
	struct usb_device *dev;	//usb设备
	struct usb_host_endpoint *ep;
	unsigned int pipe;	//pipe
	unsigned int stream_id;
	int status;
	unsigned int transfer_flags;
	void *transfer_buffer;	//传输缓冲区
	dma_addr_t transfer_dma;
	struct scatterlist *sg;
	int num_sgs;
	u32 transfer_buffer_length;	//缓冲区长度
	u32 actual_length;
	unsigned char *setup_packet;	//setup包
	dma_addr_t setup_dma;
	int start_frame;
	int number_of_packets;	//包数
	int interval;
	int error_count;
	void *context;
	usb_complete_t complete;	//回调函数
	struct usb_iso_packet_descriptor iso_frame_desc[0];
};

9. usb设备id

struct usb_device_id {
	__u16		match_flags;	//匹配标志
	__u16		idVendor;	//厂商id
	__u16		idProduct;	//产品id
	__u16		bcdDevice_lo;	//usb版本信息低位
	__u16		bcdDevice_hi;	//usb版本信息高位
	__u8		bDeviceClass;	//设备类
	__u8		bDeviceSubClass;	//子设备类
	__u8		bDeviceProtocol;	//设备协议
	__u8		bInterfaceClass;	//接口类
	__u8		bInterfaceSubClass; //接口之类
	__u8		bInterfaceProtocol;	//接口协议
	kernel_ulong_t	driver_info;	//驱动信息
};


1.usb设备描述符

struct usb_device_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__le16 bcdUSB;
	__u8  bDeviceClass;
	__u8  bDeviceSubClass;
	__u8  bDeviceProtocol;
	__u8  bMaxPacketSize0;
	__le16 idVendor;
	__le16 idProduct;
	__le16 bcdDevice;
	__u8  iManufacturer;
	__u8  iProduct;
	__u8  iSerialNumber;
	__u8  bNumConfigurations;
} __attribute__ ((packed));

2.usb配置描述符

struct usb_config_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__le16 wTotalLength;
	__u8  bNumInterfaces;
	__u8  bConfigurationValue;
	__u8  iConfiguration;
	__u8  bmAttributes;
	__u8  bMaxPower;
} __attribute__ ((packed));

3.usb端点描述符

struct usb_endpoint_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__u8  bEndpointAddress;
	__u8  bmAttributes;
	__le16 wMaxPacketSize;
	__u8  bInterval;
	__u8  bRefresh;
	__u8  bSynchAddress;
} __attribute__ ((packed));

4.usb接口描述符

struct usb_interface_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__u8  bInterfaceNumber;
	__u8  bAlternateSetting;
	__u8  bNumEndpoints;
	__u8  bInterfaceClass;
	__u8  bInterfaceSubClass;
	__u8  bInterfaceProtocol;
	__u8  iInterface;
} __attribute__ ((packed));


二、usb子系统初始化

在/drivers/usb/core/Usb.c中,subsys_initcall(usb_init)声明了usb子系统入口函数usb_init

static int __init usb_init(void)
{
	int retval;
	if (nousb) {
		pr_info("%s: USB support disabled\n", usbcore_name);
		return 0;
	}
	retval = usb_debugfs_init();	//1.usb debugfs初始化
	if (retval)
		goto out;
	retval = bus_register(&usb_bus_type);	//2.usb总线注册
	if (retval)
		goto bus_register_failed;
	retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb);	//3.usb总线通知链注册
	if (retval)
		goto bus_notifier_failed;
	retval = usb_major_init();	//4.注册usb主控器字符设备
	if (retval)
		goto major_init_failed;
	retval = usb_register(&usbfs_driver);	//5.注册usbfs驱动
	if (retval)
		goto driver_register_failed;
	retval = usb_devio_init();	//6.usb设备字符设备初始化
	if (retval)
		goto usb_devio_init_failed;
	retval = usbfs_init();	//7.usbfs初始化
	if (retval)
		goto fs_init_failed;
	retval = usb_hub_init();	//8.usb hub初始化
	if (retval)
		goto hub_init_failed;
	retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);	//9.usb注册同样设备驱动
	if (!retval)
		goto out;
	usb_hub_cleanup();
hub_init_failed:
	usbfs_cleanup();
fs_init_failed:
	usb_devio_cleanup();
usb_devio_init_failed:
	usb_deregister(&usbfs_driver);
driver_register_failed:
	usb_major_cleanup();
major_init_failed:
	bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
bus_notifier_failed:
	bus_unregister(&usb_bus_type);
bus_register_failed:
	usb_debugfs_cleanup();
out:
	return retval;
}

1.usb_debugfs_init --usb debugfs初始化

static int usb_debugfs_init(void)
{
	usb_debug_root = debugfs_create_dir("usb", NULL);	//创建"$(debugfs)/usb"
	if (!usb_debug_root)
		return -ENOENT;		
	usb_debug_devices = debugfs_create_file("devices", 0444,usb_debug_root, NULL,&usbfs_devices_fops);
	//创建"$(debugfs)/usb/device",捆绑usbfs_devices_fops结构体
	if (!usb_debug_devices) {	//若创建失败
		debugfs_remove(usb_debug_root);	//则必须把“$(debugfs)/usb”也删除掉
		usb_debug_root = NULL;
		return -ENOENT;
	}
	return 0;
}

要使用debugfs下面的usb功能,需要先挂着debugfs(mount -t debugfs none $(debugfs) ),具体初始化了啥调试接口,看下usbfs_devices_fops操作函数集
2.usb总线的注册

struct bus_type usb_bus_type = {
	.name =	"usb",	//总线名
	.match =	usb_device_match,	//匹配方法
	.uevent =	usb_uevent,	//事件处理
#ifdef CONFIG_USB_SUSPEND
	.pm =	&usb_bus_pm_ops,	//电源管理
#endif
};

这里总线的match方法是usb设备与usb驱动匹配的函数.

3.注册usb总线通知链

int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
{
	return blocking_notifier_chain_register(&bus->p->bus_notifier, nb);
}

当总线添加删除设备的时候会调用usb_bus_nb指定的notifier_cal方法,既usb_bus_notify

static int usb_bus_notify(struct notifier_block *nb, unsigned long action,void *data)
{
	struct device *dev = data;
	switch (action) {
	case BUS_NOTIFY_ADD_DEVICE:	//添加设备
		if (dev->type == &usb_device_type)	//usb设备
			(void) usb_create_sysfs_dev_files(to_usb_device(dev));
		else if (dev->type == &usb_if_device_type)	//usb接口
			(void) usb_create_sysfs_intf_files(to_usb_interface(dev));
		break;
	case BUS_NOTIFY_DEL_DEVICE:	//删除设备
		if (dev->type == &usb_device_type)	//usb设备
			usb_remove_sysfs_dev_files(to_usb_device(dev));
		else if (dev->type == &usb_if_device_type)	//usb接口
			usb_remove_sysfs_intf_files(to_usb_interface(dev));
		break;
	}
	return 0;
}

4.初始化usb主控器字符设备,USB_MAJOR=180

int usb_major_init(void)
{
	int error;
	error = register_chrdev(USB_MAJOR, "usb", &usb_fops);	//注册usb控制器字符设备,捆绑usb_fops
	if (error)
		printk(KERN_ERR "Unable to get major %d for usb devices\n",USB_MAJOR);
	return error;
}

捆绑usb_fops

static const struct file_operations usb_fops = {
	.owner =	THIS_MODULE,
	.open =	usb_open,
	.llseek =	noop_llseek,
};

5.注册usbfs_driver

struct usb_driver usbfs_driver = {
	.name =	"usbfs",
	.probe =	driver_probe,
	.disconnect = driver_disconnect,
	.suspend = driver_suspend,
	.resume =	driver_resume,
};

6.usb_devio_init     USB_DEVICE_DEV=189

int __init usb_devio_init(void)
{
	int retval;
	retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,"usb_device");	//分配设备号
	if (retval) {
		printk(KERN_ERR "Unable to register minors for usb_device\n");
		goto out;
	}
	cdev_init(&usb_device_cdev, &usbdev_file_operations);	//字符设备初始化
	retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);	//添加字符设备
	if (retval) {
		printk(KERN_ERR "Unable to get usb_device major %d\n",USB_DEVICE_MAJOR);
		goto error_cdev;
	}
#ifdef CONFIG_USB_DEVICE_CLASS
	usb_classdev_class = class_create(THIS_MODULE, "usb_device");	//创建"/sys/class/usb_device"
	if (IS_ERR(usb_classdev_class)) {
		printk(KERN_ERR "Unable to register usb_device class\n");
		retval = PTR_ERR(usb_classdev_class);
		cdev_del(&usb_device_cdev);	
		usb_classdev_class = NULL;
		goto out;
	}
	usb_classdev_class->dev_kobj = NULL;
#endif
	usb_register_notify(&usbdev_nb);	//注册设备通知链
out:
	return retval;
error_cdev:
	unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
	goto out;
}

usb注册的通知链

void usb_register_notify(struct notifier_block *nb)
{
	blocking_notifier_chain_register(&usb_notifier_list, nb);
}

usb通知链表头为usb_notifier_list

在/drivers/usb/core/Notify.c文件中,有四个函数()对usb_notifier_list中发送通知,这四个函数如下:

usb_notify_add_device    //有设备添加
usb_notify_remove_device    //有设备移除
usb_notify_add_bus    //总线添加
usb_notify_remove_bus    //总线移除

当这些事件发生后会调用usbdev_nb指定的notifier_cal方法,既usbdev_notify

static int usbdev_notify(struct notifier_block *self,unsigned long action, void *dev)
{
	switch (action) {
	case USB_DEVICE_ADD:	//设备添加
		if (usb_classdev_add(dev))
			return NOTIFY_BAD;
		break;
	case USB_DEVICE_REMOVE:	//设备删除
		usb_classdev_remove(dev);
		usbdev_remove(dev);
		break;
	}
	return NOTIFY_OK;
}

7.usbfs初始化

int __init usbfs_init(void)
{
	int retval;
	retval = register_filesystem(&usb_fs_type);	//注册文件系统
	if (retval)
		return retval;
	usb_register_notify(&usbfs_nb);	//注册通知链
	usbdir = proc_mkdir("bus/usb", NULL);	//创建"/proc/bus/usb"
	return 0;
}

通知链回调函数

static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
{
	switch (action) {
	case USB_DEVICE_ADD:	//设备添加
		usbfs_add_device(dev);
		break;
	case USB_DEVICE_REMOVE:	//设备移除
		usbfs_remove_device(dev);
		break;
	case USB_BUS_ADD:	//总线添加
		usbfs_add_bus(dev);
		break;
	case USB_BUS_REMOVE:	//总线移除
		usbfs_remove_bus(dev);
	}
	usbfs_update_special();
	usbfs_conn_disc_event();
	return NOTIFY_OK;
}

8.usb hub初始化

int usb_hub_init(void)
{
	if (usb_register(&hub_driver) < 0) {	//注册usb hub设备驱动
		printk(KERN_ERR "%s: can't register hub driver\n",usbcore_name);
		return -1;
	}
	khubd_task = kthread_run(hub_thread, NULL, "khubd");	//创建守护进程
	if (!IS_ERR(khubd_task))
		return 0;
	usb_deregister(&hub_driver);
	printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);
	return -1;
}

hub也是usb设备,所以需要注册器设备驱动,创建hub_thread守护进程
捆绑的hub usb设备驱动

static struct usb_driver hub_driver = {
	.name = "hub",
	.probe =	hub_probe,	//hub连接上
	.disconnect = hub_disconnect,	//hub断开
	.suspend = hub_suspend,	//hub挂起
	.resume =	hub_resume,	//hub唤醒
	.reset_resume = hub_reset_resume,	//hub复位唤醒
	.pre_reset = hub_pre_reset,	
	.post_reset = hub_post_reset,
	.unlocked_ioctl = hub_ioctl,
	.id_table = hub_id_table,	//hub设备驱动 id表
	.supports_autosuspend = 1,
};

hub_thread守护进程

static int hub_thread(void *__unused)
{
	set_freezable();	//设置可冻结
	do {
		hub_events();	//hub事件处理函数
		wait_event_freezable(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop());	//进入睡眠
	} while (!kthread_should_stop() || !list_empty(&hub_event_list));
	pr_debug("%s: khubd exiting\n", usbcore_name);
	return 0;
}

这里while循环是在hub_event_list不为空时候循环执行

当hub_events执行完,会执行wait_event_freezable进入睡眠,其他函数调用wake_up(&khubd_wait)唤醒队列
hub_events函数

static void hub_events(void)
{
	struct list_head *tmp;
	struct usb_device *hdev;
	struct usb_interface *intf;
	struct usb_hub *hub;
	struct device *hub_dev;
	u16 hubstatus;
	u16 hubchange;
	u16 portstatus;
	u16 portchange;
	int i, ret;
	int connect_change;

	while (1) {
		spin_lock_irq(&hub_event_lock);
		//第一次执行假设usb主控器还没注册
		if (list_empty(&hub_event_list)) {	//usb事件链表为空
			spin_unlock_irq(&hub_event_lock);
			break;	//跳出循环
		}
		tmp = hub_event_list.next;	
		list_del_init(tmp);
		hub = list_entry(tmp, struct usb_hub, event_list);	
		kref_get(&hub->kref);
		spin_unlock_irq(&hub_event_lock);
		hdev = hub->hdev;	
		hub_dev = hub->intfdev;	
		intf = to_usb_interface(hub_dev);
		usb_lock_device(hdev);
		if (unlikely(hub->disconnected))
			goto loop_disconnected;
		if (hdev->state == USB_STATE_NOTATTACHED) {
			hub->error = -ENODEV;
			hub_quiesce(hub, HUB_DISCONNECT);
			goto loop;
		}
		ret = usb_autopm_get_interface(intf);
		if (ret) {
			dev_dbg(hub_dev, "Can't autoresume: %d\n", ret);
			goto loop;
		}
		if (hub->quiescing)
			goto loop_autopm;
		if (hub->error) {
			dev_dbg (hub_dev, "resetting for error %d\n",hub->error);
			ret = usb_reset_device(hdev);	
			if (ret) {
				dev_dbg (hub_dev,"error resetting hub: %d\n", ret);
				goto loop_autopm;
			}
			hub->nerrors = 0;
			hub->error = 0;
		}
		for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {
			if (test_bit(i, hub->busy_bits))
				continue;
			connect_change = test_bit(i, hub->change_bits);
			if (!test_and_clear_bit(i, hub->event_bits) &&!connect_change)
				continue;
			ret = hub_port_status(hub, i,&portstatus, &portchange);
			if (ret < 0)
				continue;
			if (portchange & USB_PORT_STAT_C_CONNECTION) {
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_CONNECTION);
				connect_change = 1;
			}
			if (portchange & USB_PORT_STAT_C_ENABLE) {
				if (!connect_change)
					dev_dbg (hub_dev,"port %d enable change,status %08x\n",i, portstatus);
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_ENABLE);
				if (!(portstatus & USB_PORT_STAT_ENABLE)&& !connect_change&& hdev->children[i-1]) {
					dev_err (hub_dev,"port %i disabled by hub (EMI?),re-enabling...\n",i);
					connect_change = 1;
				}
			}
			if (portchange & USB_PORT_STAT_C_SUSPEND) {
				struct usb_device *udev;
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_SUSPEND);
				udev = hdev->children[i-1];
				if (udev) {
					msleep(10);
					usb_lock_device(udev);
					ret = usb_remote_wakeup(hdev->children[i-1]);
					usb_unlock_device(udev);
					if (ret < 0)
						connect_change = 1;
				} else {
					ret = -ENODEV;
					hub_port_disable(hub, i, 1);
				}
				dev_dbg (hub_dev,"resume on port %d, status %d\n",i, ret);
			}
			
			if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
				dev_err (hub_dev,"over-current change on port %d\n",i);
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_OVER_CURRENT);
				hub_power_on(hub, true);
			}
			if (portchange & USB_PORT_STAT_C_RESET) {
				dev_dbg (hub_dev,"reset change on port %d\n",i);
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_RESET);
			}

			if (connect_change)
				hub_port_connect_change(hub, i,portstatus, portchange);
		}
		if (test_and_clear_bit(0, hub->event_bits) == 0)
			;			
		else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
			dev_err (hub_dev, "get_hub_status failed\n");
		else {
			if (hubchange & HUB_CHANGE_LOCAL_POWER) {
				dev_dbg (hub_dev, "power change\n");
				clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
				if (hubstatus & HUB_STATUS_LOCAL_POWER)
					hub->limited_power = 1;
				else
					hub->limited_power = 0;
			}
			if (hubchange & HUB_CHANGE_OVERCURRENT) {
				dev_dbg (hub_dev, "overcurrent change\n");
				msleep(500);
				clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
                        	hub_power_on(hub, true);
			}
		}
 loop_autopm:
		usb_autopm_put_interface_no_suspend(intf);
 loop:
		usb_autopm_put_interface(intf);
 loop_disconnected:
		usb_unlock_device(hdev);
		kref_put(&hub->kref, hub_release);
        }
}

9.usb注册通用设备驱动

int usb_register_device_driver(struct usb_device_driver *new_udriver,struct module *owner)
{
	int retval = 0;
	if (usb_disabled())
		return -ENODEV;
	new_udriver->drvwrap.for_devices = 1;	//usb设备
	new_udriver->drvwrap.driver.name = (char *) new_udriver->name;	//设备名
	new_udriver->drvwrap.driver.bus = &usb_bus_type;	//总线类型
	new_udriver->drvwrap.driver.probe = usb_probe_device;	//probe方法
	new_udriver->drvwrap.driver.remove = usb_unbind_device;	//remove方法
	new_udriver->drvwrap.driver.owner = owner;	//模块所有者
	retval = driver_register(&new_udriver->drvwrap.driver);	//注册设备驱动
	if (!retval) {
		pr_info("%s: registered new device driver %s\n",usbcore_name, new_udriver->name);
		usbfs_update_special();
	} else {
		printk(KERN_ERR "%s: error %d registering device driver %s\n",usbcore_name, retval, new_udriver->name);
	}
	return retval;
}

usb_device_driver结构体是usb_driver的简化版本,这里注册的是usb设备(非接口)驱动

usb总线的match方法对usb设备和usb接口做了区分处理,针对usb设备,直接match的,(分析match时候再细化)

然后调用usb设备驱动的probe方法

static int usb_probe_device(struct device *dev)
{
	struct usb_device_driver *udriver = to_usb_device_driver(dev->driver);
	struct usb_device *udev = to_usb_device(dev);
	int error = 0;
	dev_dbg(dev, "%s\n", __func__);
	if (!udriver->supports_autosuspend)	//条件成立
		error = usb_autoresume_device(udev);
	if (!error)
		error = udriver->probe(udev);	//调用usb_device_driver的probe方法
	return error;
}

接着调用usb_generic_driver的probe方法

struct usb_device_driver usb_generic_driver = {
	.name =	"usb",
	.probe = generic_probe,
	.disconnect = generic_disconnect,
#ifdef	CONFIG_PM
	.suspend = generic_suspend,
	.resume = generic_resume,
#endif
	.supports_autosuspend = 1,
};

所以generic_probe函数会接着被调用

static int generic_probe(struct usb_device *udev)
{
	int err, c;
	if (usb_device_is_owned(udev))
		;
	else if (udev->authorized == 0)	//明显不执行
		dev_err(&udev->dev, "Device is not authorized for usage\n");
	else {	//
		c = usb_choose_configuration(udev);	//选择一个配置
		if (c >= 0) {
			err = usb_set_configuration(udev, c);	//设置一个配置
			if (err) {
				dev_err(&udev->dev, "can't set config #%d, error %d\n",c, err);
			}
		}
	}
	/* USB device state == configured ... usable */
	usb_notify_add_device(udev);	//发送设备添加通知
	return 0;
}


<---usb子系统相关结构体
--->usb主控器注册

三、usb主控器注册

第一步usb主控器设备的分配

usb_create_hcd

struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,struct device *dev, const char *bus_name)
{
	struct usb_hcd *hcd;
	hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);	//分配usb_hcd和私有数据内存
	if (!hcd) {
		dev_dbg (dev, "hcd alloc failed\n");
		return NULL;
	}
	dev_set_drvdata(dev, hcd);	//dev->p->driver_data=hcd
	kref_init(&hcd->kref);	//参考计数+1
	usb_bus_init(&hcd->self);	//初始化usb总线
	hcd->self.controller = dev;	//设置总线控制器设备
	hcd->self.bus_name = bus_name;	//设置总线名
	hcd->self.uses_dma = (dev->dma_mask != NULL);	//设置DMA标志
	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);	//唤醒执行hcd_resume_work函数
#endif
	mutex_init(&hcd->bandwidth_mutex);
	hcd->driver = driver;	//设置主控器驱动
	hcd->product_desc = (driver->product_desc) ? driver->product_desc :"USB Host Controller";	//设置厂商字串
	if (hcd->driver->recover_hcd)	//若主控器驱动存在recover_hcd方法
		INIT_WORK(&hcd->ehci_omap_work, hcd->driver->recover_hcd);	//则调用其方法
	return hcd;
}

这里定时器的回调函数

static void rh_timer_func (unsigned long _hcd)
{
	usb_hcd_poll_rh_status((struct usb_hcd *) _hcd);	//调用hcd轮询检测状态的函数
}

第二步usb主控器设备添加

usb_add_hcd

int usb_add_hcd(struct usb_hcd *hcd,unsigned int irqnum, unsigned long irqflags)
{
	int retval;
	struct usb_device *rhdev;	//usb设备(root hub)
	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);	//设置usb主控器设备设备文件名称
	hcd->authorized_default = hcd->wireless? 0 : 1;	//检测无线受权信息
	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);	//置位usb主控器标志	(全功耗)
	if ((retval = hcd_buffer_create(hcd)) != 0) {	//分配usb主控器设备DMA缓冲池
		dev_dbg(hcd->self.controller, "pool alloc failed\n");
		return retval;
	}
	if ((retval = usb_register_bus(&hcd->self)) < 0)	//usb注册总线
		goto err_register_bus;
	if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {	//分配usb设备(根hub)
		dev_err(hcd->self.controller, "unable to allocate root hub\n");
		retval = -ENOMEM;
		goto err_allocate_root_hub;
	}
	hcd->self.root_hub = rhdev;
	switch (hcd->driver->flags & HCD_MASK) {	//设置usb设备速度类型
	case HCD_USB11:
		rhdev->speed = USB_SPEED_FULL;	//全速
		break;
	case HCD_USB2:
		rhdev->speed = USB_SPEED_HIGH;	//高速
		break;
	case HCD_USB3:
		rhdev->speed = USB_SPEED_SUPER;	//超速
		break;
	default:
		goto err_set_rh_speed;
	}
	device_init_wakeup(&rhdev->dev, 1);
	if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {	//若usb主控器驱动存在重置方法则调用
		dev_err(hcd->self.controller, "can't setup\n");
		goto err_hcd_driver_setup;
	}
	hcd->rh_pollable = 1;//设置为可轮循
	if (device_can_wakeup(hcd->self.controller)&& device_can_wakeup(&hcd->self.root_hub->dev))	//检测唤醒功能
		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
	if (hcd->driver->irq) {	//可中断
		if (irqflags & IRQF_SHARED)	//不能支持共享中断
			irqflags &= ~IRQF_DISABLED;
		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",hcd->driver->description, hcd->self.busnum);
		if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags,hcd->irq_descr, hcd)) != 0) {	//申请中断
			dev_err(hcd->self.controller,"request interrupt %d failed\n", irqnum);
			goto err_request_irq;
		}
		hcd->irq = irqnum;	//设置中断号
		dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum,(hcd->driver->flags & HCD_MEMORY) ?
					"io mem" : "io base",(unsigned long long)hcd->rsrc_start);
	} else {			//不可中断
		hcd->irq = -1;
		if (hcd->rsrc_start)	//存在内存资源起始地址
			dev_info(hcd->self.controller, "%s 0x%08llx\n",(hcd->driver->flags & HCD_MEMORY) ?
				"io mem" : "io base",(unsigned long long)hcd->rsrc_start);
	}
	if ((retval = hcd->driver->start(hcd)) < 0) {	//调用主机驱动的start方法
		dev_err(hcd->self.controller, "startup error %d\n", retval);
		goto err_hcd_driver_start;
	}
	rhdev->bus_mA = min(500u, hcd->power_budget);	//设置总线电流限值
	if ((retval = register_root_hub(hcd)) != 0)	//注册根hub
		goto err_register_root_hub;
	retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);	//创建root hub属性文件
	if (retval < 0) {
		printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",retval);
		goto error_create_attr_group;
	}
	if (hcd->uses_new_polling && HCD_POLL_RH(hcd))	//若使用新的轮询方式且flags为HCD_FLAG_POLL_RH
		usb_hcd_poll_rh_status(hcd);	//则轮询监控root hub状态
	return retval;
error_create_attr_group:
	if (HC_IS_RUNNING(hcd->state))
		hcd->state = HC_STATE_QUIESCING;
	spin_lock_irq(&hcd_root_hub_lock);
	hcd->rh_registered = 0;
	spin_unlock_irq(&hcd_root_hub_lock);
#ifdef CONFIG_USB_SUSPEND
	cancel_work_sync(&hcd->wakeup_work);
#endif
	mutex_lock(&usb_bus_list_lock);
	usb_disconnect(&rhdev);
	mutex_unlock(&usb_bus_list_lock);
err_register_root_hub:
	hcd->rh_pollable = 0;
	clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
	del_timer_sync(&hcd->rh_timer);
	hcd->driver->stop(hcd);
	hcd->state = HC_STATE_HALT;
	clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
	del_timer_sync(&hcd->rh_timer);
err_hcd_driver_start:
	if (hcd->irq >= 0)
		free_irq(irqnum, hcd);
err_request_irq:
err_hcd_driver_setup:
err_set_rh_speed:
	usb_put_dev(hcd->self.root_hub);
err_allocate_root_hub:
	usb_deregister_bus(&hcd->self);
err_register_bus:
	hcd_buffer_destroy(hcd);
	return retval;
} 

root hub中断例程

irqreturn_t usb_hcd_irq (int irq, void *__hcd)
{
	struct usb_hcd	*hcd = __hcd;
	unsigned long	flags;
	irqreturn_t	rc;
	local_irq_save(flags);
	if (unlikely(hcd->state == HC_STATE_HALT || !HCD_HW_ACCESSIBLE(hcd))) {
		rc = IRQ_NONE;
	} else if (hcd->driver->irq(hcd) == IRQ_NONE) {	//调用主控器驱动的中断处理例程
		rc = IRQ_NONE;
	} else {
		set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);	//设置usb主控器标志HCD_FLAG_SAW_IRQ

		if (unlikely(hcd->state == HC_STATE_HALT))	//root hub处于停止状态
			usb_hc_died(hcd);
		rc = IRQ_HANDLED;
	}
	local_irq_restore(flags);
	return rc;
}

注册根hub register_root_hub

static int register_root_hub(struct usb_hcd *hcd)
{
	struct device *parent_dev = hcd->self.controller;
	struct usb_device *usb_dev = hcd->self.root_hub;
	const int devnum = 1;
	int retval;
	usb_dev->devnum = devnum;	//地址
	usb_dev->bus->devnum_next = devnum + 1;
	memset (&usb_dev->bus->devmap.devicemap, 0,sizeof usb_dev->bus->devmap.devicemap);	//初始化总线usb设备号表
	set_bit (devnum, usb_dev->bus->devmap.devicemap);	//设置usb设备地址表第1位
	usb_set_device_state(usb_dev, USB_STATE_ADDRESS);	//设置设备为寻址态
	mutex_lock(&usb_bus_list_lock);
	usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
	retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);	//获取设备描述符
	if (retval != sizeof usb_dev->descriptor) {
		mutex_unlock(&usb_bus_list_lock);
		dev_dbg (parent_dev, "can't read %s device descriptor %d\n",dev_name(&usb_dev->dev), retval);
		return (retval < 0) ? retval : -EMSGSIZE;
	}
	retval = usb_new_device (usb_dev);	//添加新的usb设备(root hub)-->枚举
	if (retval) {
		dev_err (parent_dev, "can't register root hub for %s, %d\n",dev_name(&usb_dev->dev), retval);
	}
	mutex_unlock(&usb_bus_list_lock);
	if (retval == 0) {
		spin_lock_irq (&hcd_root_hub_lock);
		hcd->rh_registered = 1;	//设置hub已注册标志
		spin_unlock_irq (&hcd_root_hub_lock);
		if (hcd->state == HC_STATE_HALT)	//若root hub处于停止状态
			usb_hc_died (hcd);
	}
	return retval;
}

调用usb_new_device添加新设备

int usb_new_device(struct usb_device *udev)
{
	int err;
	if (udev->parent) {
		device_init_wakeup(&udev->dev, 0);
	}
	pm_runtime_set_active(&udev->dev);
	pm_runtime_enable(&udev->dev);
	err = usb_enumerate_device(udev);	//读取usb设备描述符	
        if (err < 0)
		goto fail;
	dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",udev->devnum, udev->bus->busnum,(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
	udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));	//分配设备号
	announce_device(udev);	//打印设备miOAHUDU
	device_enable_async_suspend(&udev->dev);
	err = device_add(&udev->dev);	//设备添加
	if (err) {
		dev_err(&udev->dev, "can't device_add, error %d\n", err);
		goto fail;
	}
	(void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);	//创建端点设备
	return err;
fail:
	usb_set_device_state(udev, USB_STATE_NOTATTACHED);
	pm_runtime_disable(&udev->dev);
	pm_runtime_set_suspended(&udev->dev);
	return err;
} 

有些主控器支持uses_new_polling方法则会调用usb_hcd_poll_rh_status函数

void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
{
	struct urb	*urb;
	int		length;
	unsigned long	flags;
	char	buffer[6];
	if (unlikely(!hcd->rh_pollable))	//若不支持轮询
		return;
	if (!hcd->uses_new_polling && !hcd->status_urb)	//若没有urb要处理
		return;
	length = hcd->driver->hub_status_data(hcd, buffer);	//调用usb主控器驱动的hub_status_data方法
	if (length > 0) {
		spin_lock_irqsave(&hcd_root_hub_lock, flags);
		urb = hcd->status_urb;	//获取待处理的urb
		if (urb) {
			clear_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);	//清除标志位
			hcd->status_urb = NULL;	//清除待处理urb
			urb->actual_length = length;	//指定处理的urb长度
			memcpy(urb->transfer_buffer, buffer, length);

			usb_hcd_unlink_urb_from_ep(hcd, urb);//urb与设备端点解绑
			spin_unlock(&hcd_root_hub_lock);
			usb_hcd_giveback_urb(hcd, urb, 0);	//处理urb,并返回给usb设备
			spin_lock(&hcd_root_hub_lock);
		} else {
			length = 0;
			set_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);
		}
		spin_unlock_irqrestore(&hcd_root_hub_lock, flags);
	}
	if (hcd->uses_new_polling ? HCD_POLL_RH(hcd) :(length == 0 && hcd->status_urb != NULL))
		mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4));	//修改定时值,激活定时器
}

usb_hcd_giveback_urb  //处理urb

void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
{
	urb->hcpriv = NULL;
	if (unlikely(urb->unlinked))
		status = urb->unlinked;
	else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
		urb->actual_length < urb->transfer_buffer_length &&!status))
		status = -EREMOTEIO;
	unmap_urb_for_dma(hcd, urb);
	usbmon_urb_complete(&hcd->self, urb, status);
	usb_unanchor_urb(urb);
	urb->status = status;
	urb->complete (urb);		//urb 回调函数
	atomic_dec (&urb->use_count);
	if (unlikely(atomic_read(&urb->reject)))
		wake_up (&usb_kill_urb_queue);
	usb_put_urb (urb);
}


<--- usb子系统初始化

---> usb设备注册

四、usb设备注册

一.usb设备驱动注册

static inline int usb_register(struct usb_driver *driver)
{
	return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
}

usb_register_driver

int usb_register_driver(struct usb_driver *new_driver, struct module *owner,const char *mod_name)
{
	int retval = 0;
	if (usb_disabled())
		return -ENODEV;
	new_driver->drvwrap.for_devices = 0;	//usb接口设备
	new_driver->drvwrap.driver.name = (char *) new_driver->name;	//设置设备名
	new_driver->drvwrap.driver.bus = &usb_bus_type;	//设置总线类型
	new_driver->drvwrap.driver.probe = usb_probe_interface;	//设置probe方法
	new_driver->drvwrap.driver.remove = usb_unbind_interface;	//设置remove方法
	new_driver->drvwrap.driver.owner = owner;	//设置模块所有者
	new_driver->drvwrap.driver.mod_name = mod_name;
	spin_lock_init(&new_driver->dynids.lock);
	INIT_LIST_HEAD(&new_driver->dynids.list);
	retval = driver_register(&new_driver->drvwrap.driver);	//注册设备驱动
	if (retval)
		goto out;
	usbfs_update_special();
	retval = usb_create_newid_file(new_driver);
	if (retval)
		goto out_newid;
	retval = usb_create_removeid_file(new_driver);
	if (retval)
		goto out_removeid;
	pr_info("%s: registered new interface driver %s\n",usbcore_name, new_driver->name);
out:
	return retval;
out_removeid:
	usb_remove_newid_file(new_driver);
out_newid:
	driver_unregister(&new_driver->drvwrap.driver);
	printk(KERN_ERR "%s: error %d registering interface driver %s\n",usbcore_name, retval, new_driver->name);
	goto out;
}

注册设备驱动后会调用总线的match方法

static int usb_device_match(struct device *dev, struct device_driver *drv)
{
	if (is_usb_device(dev)) {	//usb设备
		if (!is_usb_device_driver(drv))
			return 0;
		return 1;
	} else if (is_usb_interface(dev)) {	//usb接口
		struct usb_interface *intf;
		struct usb_driver *usb_drv;
		const struct usb_device_id *id;
		if (is_usb_device_driver(drv))
			return 0;
		intf = to_usb_interface(dev);	//获取usb接口结构体
		usb_drv = to_usb_driver(drv);	//获取usb_driver
		id = usb_match_id(intf, usb_drv->id_table);	//id匹配
		if (id)
			return 1;
		id = usb_match_dynamic_id(intf, usb_drv);
		if (id)
			return 1;
	}
	return 0;
}

usb_match_id

const struct usb_device_id *usb_match_id(struct usb_interface *interface,const struct usb_device_id *id)
{
	if (id == NULL)
		return NULL;
	for (; id->idVendor || id->idProduct || id->bDeviceClass ||id->bInterfaceClass || id->driver_info; id++) {
		if (usb_match_one_id(interface, id))
			return id;
	}
	return NULL;
}

usb_match_one_id

int usb_match_one_id(struct usb_interface *interface,const struct usb_device_id *id)
{
	struct usb_host_interface *intf;
	struct usb_device *dev;
	if (id == NULL)
		return 0;
	intf = interface->cur_altsetting;
	dev = interface_to_usbdev(interface);
	if (!usb_match_device(dev, id))
		return 0;
	if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
	(id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |USB_DEVICE_ID_MATCH_INT_SUBCLASS |USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&(id->bInterfaceClass != intf->desc.bInterfaceClass))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&(id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&(id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
		return 0;
	return 1;
}

usb_match_device

int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
{
	if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&(id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&(id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&(id->bDeviceClass != dev->descriptor.bDeviceClass))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&(id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
		return 0;
	return 1;
}

匹配成功则调用usb_probe_interface

static int usb_probe_interface(struct device *dev)
{
	struct usb_driver *driver = to_usb_driver(dev->driver);
	struct usb_interface *intf = to_usb_interface(dev);
	struct usb_device *udev = interface_to_usbdev(intf);
	const struct usb_device_id *id;
	int error = -ENODEV;
	dev_dbg(dev, "%s\n", __func__);
	intf->needs_binding = 0;
	if (usb_device_is_owned(udev))
		return error;
	if (udev->authorized == 0) {
		dev_err(&intf->dev, "Device is not authorized for usage\n");
		return error;
	}
	id = usb_match_id(intf, driver->id_table);
	if (!id)
		id = usb_match_dynamic_id(intf, driver);
	if (!id)
		return error;
	dev_dbg(dev, "%s - got id\n", __func__);
	error = usb_autoresume_device(udev);
	if (error)
		return error;
	intf->condition = USB_INTERFACE_BINDING;
	pm_runtime_set_active(dev);
	pm_suspend_ignore_children(dev, false);
	if (driver->supports_autosuspend)
		pm_runtime_enable(dev);
	if (intf->needs_altsetting0) {
		error = usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
		if (error < 0)
			goto err;
		intf->needs_altsetting0 = 0;
	}
	error = driver->probe(intf, id);
	if (error)
		goto err;
	intf->condition = USB_INTERFACE_BOUND;
	usb_autosuspend_device(udev);
	return error;
 err:
	intf->needs_remote_wakeup = 0;
	intf->condition = USB_INTERFACE_UNBOUND;
	usb_cancel_queued_reset(intf);
	if (driver->supports_autosuspend)
		pm_runtime_disable(dev);
	pm_runtime_set_suspended(dev);
	usb_autosuspend_device(udev);
	return error;
}

usb_set_interface

int usb_set_interface(struct usb_device *dev, int interface, int alternate)
{
	struct usb_interface *iface;
	struct usb_host_interface *alt;
	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
	int ret;
	int manual = 0;
	unsigned int epaddr;
	unsigned int pipe;
	if (dev->state == USB_STATE_SUSPENDED)
		return -EHOSTUNREACH;
	iface = usb_ifnum_to_if(dev, interface);
	if (!iface) {
		dev_dbg(&dev->dev, "selecting invalid interface %d\n",interface);
		return -EINVAL;
	}
	alt = usb_altnum_to_altsetting(iface, alternate);
	if (!alt) {
		dev_warn(&dev->dev, "selecting invalid altsetting %d\n",alternate);
		return -EINVAL;
	}
	mutex_lock(&hcd->bandwidth_mutex);
	ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt);
	if (ret < 0) {
		dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",alternate);
		mutex_unlock(&hcd->bandwidth_mutex);
		return ret;
	}
	if (dev->quirks & USB_QUIRK_NO_SET_INTF)
		ret = -EPIPE;
	else
		ret = usb_control_msg(dev, usb_sndctrlpipe(dev,0),USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,alternate, interface, NULL, 0, 5000);
	if (ret == -EPIPE && iface->num_altsetting == 1) {
		dev_dbg(&dev->dev,"manual set_interface for iface %d, alt %d\n",interface, alternate);
		manual = 1;
	} else if (ret < 0) {
		usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting);
		mutex_unlock(&hcd->bandwidth_mutex);
		return ret;
	}
	mutex_unlock(&hcd->bandwidth_mutex);
	if (iface->cur_altsetting != alt) {
		remove_intf_ep_devs(iface);
		usb_remove_sysfs_intf_files(iface);
	}
	usb_disable_interface(dev, iface, true);
	iface->cur_altsetting = alt;
	if (manual) {
		int i;
		for (i = 0; i < alt->desc.bNumEndpoints; i++) {
			epaddr = alt->endpoint[i].desc.bEndpointAddress;
			pipe = __create_pipe(dev,USB_ENDPOINT_NUMBER_MASK & epaddr) |(usb_endpoint_out(epaddr) ?USB_DIR_OUT : USB_DIR_IN);
			usb_clear_halt(dev, pipe);
		}
	}
	usb_enable_interface(dev, iface, true);
	if (device_is_registered(&iface->dev)) {
		usb_create_sysfs_intf_files(iface);
		create_intf_ep_devs(iface);
	}
	return 0;
}


二.usb设备注册

int usb_register_dev(struct usb_interface *intf,struct usb_class_driver *class_driver)
{
	int retval;
	int minor_base = class_driver->minor_base;
	int minor;
	char name[20];
	char *temp;
#ifdef CONFIG_USB_DYNAMIC_MINORS
	minor_base = 0;
#endif
	if (class_driver->fops == NULL)
		return -EINVAL;
	if (intf->minor >= 0)
		return -EADDRINUSE;
	retval = init_usb_class();
	if (retval)
		return retval;
	dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base);
	down_write(&minor_rwsem);
	for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
		if (usb_minors[minor])	//若数组不为空
			continue;
		usb_minors[minor] = class_driver->fops;	//将操作函数集放入全局usb_minors数组中
		intf->minor = minor;	//设置接口的次设备号
		break;
	}
	up_write(&minor_rwsem);
	if (intf->minor < 0)
		return -EXFULL;
	snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
	temp = strrchr(name, '/');
	if (temp && (temp[1] != '\0'))
		++temp;
	else
		temp = name;
	//创建设备
	intf->usb_dev = device_create(usb_class->class, &intf->dev,MKDEV(USB_MAJOR, minor), class_driver,"%s", temp);
	if (IS_ERR(intf->usb_dev)) {
		down_write(&minor_rwsem);
		usb_minors[minor] = NULL;
		intf->minor = -1;
		up_write(&minor_rwsem);
		retval = PTR_ERR(intf->usb_dev);
	}
	return retval;
}


<---usb主控器注册
--->从usb的插入开始

五、从usb的插入开始

当usb设备插入接口,电压变化会通知到usb主控器,

触发主控器中断,如果主控器不支持中断,那么会使用rh_timer方法,轮询接口

其结果都是调用usb_hcd_poll_rh_status

void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
{
	struct urb	*urb;
	int		length;
	unsigned long	flags;
	char		buffer[6];	/* Any root hubs with > 31 ports? */

	if (unlikely(!hcd->rh_pollable))
		return;
	if (!hcd->uses_new_polling && !hcd->status_urb)
		return;

	length = hcd->driver->hub_status_data(hcd, buffer);	//获取urb数据长度
	if (length > 0) {

		/* try to complete the status urb */
		spin_lock_irqsave(&hcd_root_hub_lock, flags);
		urb = hcd->status_urb;	//获取要处理的urb
		if (urb) {
			clear_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);	//清除urb主控器poll标志
			hcd->status_urb = NULL;	//清空待处理urb
			urb->actual_length = length;	//获取urb数据长度
			memcpy(urb->transfer_buffer, buffer, length);	//复制urb缓冲区

			usb_hcd_unlink_urb_from_ep(hcd, urb);	//从主控器的端点上解绑urb
			spin_unlock(&hcd_root_hub_lock);
			usb_hcd_giveback_urb(hcd, urb, 0);	//处理urb并回传urb给设备
			spin_lock(&hcd_root_hub_lock);
		} else {
			length = 0;
			set_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);
		}
		spin_unlock_irqrestore(&hcd_root_hub_lock, flags);
	}
	if (hcd->uses_new_polling ? HCD_POLL_RH(hcd) :
			(length == 0 && hcd->status_urb != NULL))
		mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4));
}

usb_hcd_giveback_urb函数

void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
{
	urb->hcpriv = NULL;
	if (unlikely(urb->unlinked))
		status = urb->unlinked;
	else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
			urb->actual_length < urb->transfer_buffer_length &&
			!status))
		status = -EREMOTEIO;

	unmap_urb_for_dma(hcd, urb);
	usbmon_urb_complete(&hcd->self, urb, status);
	usb_unanchor_urb(urb);

	/* pass ownership to the completion handler */
	urb->status = status;
	urb->complete (urb);		//执行urb回调函数,就是hub_irq
	atomic_dec (&urb->use_count);
	if (unlikely(atomic_read(&urb->reject)))
		wake_up (&usb_kill_urb_queue);
	usb_put_urb (urb);
}

hub_irq函数

static void hub_irq(struct urb *urb)
{
	struct usb_hub *hub = urb->context;
	int status = urb->status;
	unsigned i;
	unsigned long bits;

	switch (status) {
	case -ENOENT:
	case -ECONNRESET:
	case -ESHUTDOWN:
		return;
	default:	//错误
		dev_dbg (hub->intfdev, "transfer --> %d\n", status);
		if ((++hub->nerrors < 10) || hub->error)
			goto resubmit;
		hub->error = status;
	case 0:	//端口状态有变化
		bits = 0;
		for (i = 0; i < urb->actual_length; ++i)
			bits |= ((unsigned long) ((*hub->buffer)[i]))<< (i*8);
		hub->event_bits[0] = bits;	//填充hub->event_bit数组
		break;
	}

	hub->nerrors = 0;
	kick_khubd(hub);	//调用kick_khubd函数
resubmit:
	if (hub->quiescing)
		return;
	if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0&& status != -ENODEV && status != -EPERM)
		dev_err (hub->intfdev, "resubmit --> %d\n", status);
}

kick_khubd函数

static void kick_khubd(struct usb_hub *hub)
{
	unsigned long	flags;
	spin_lock_irqsave(&hub_event_lock, flags);
	if (!hub->disconnected && list_empty(&hub->event_list)) {
		list_add_tail(&hub->event_list, &hub_event_list);
		usb_autopm_get_interface_no_resume(to_usb_interface(hub->intfdev));
		wake_up(&khubd_wait);	//唤醒khubd_wait相关的等待队列
	}
	spin_unlock_irqrestore(&hub_event_lock, flags);
}

这里会触发hub_events函数,原因如下

	do {
		hub_events();
		wait_event_freezable(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop());
	} while (!kthread_should_stop() || !list_empty(&hub_event_list));

hub_events函数

static void hub_events(void)
{
	struct list_head *tmp;
	struct usb_device *hdev;
	struct usb_interface *intf;
	struct usb_hub *hub;
	struct device *hub_dev;
	u16 hubstatus;
	u16 hubchange;
	u16 portstatus;
	u16 portchange;
	int i, ret;
	int connect_change;
	//hcd usb主控器的状态由usb主控器的中断例程根据具体硬件状态去设置
	while (1) {
		spin_lock_irq(&hub_event_lock);
		//这次执行假设usb主控器已经注册
		if (list_empty(&hub_event_list)) {	//usb事件链表不为为空
			spin_unlock_irq(&hub_event_lock);
			break;	
		}
		tmp = hub_event_list.next;	//拿出hub_event链表项	
		list_del_init(tmp);	//从hub_event_list删除其
		hub = list_entry(tmp, struct usb_hub, event_list);	//根据链表项获取usb_hub	
		kref_get(&hub->kref);	//引用计数
		spin_unlock_irq(&hub_event_lock);
		hdev = hub->hdev;		//获取hub usb设备
		hub_dev = hub->intfdev;	//获取hub 设备文件
		intf = to_usb_interface(hub_dev);	//获取hub usb接口
		usb_lock_device(hdev);
		if (unlikely(hub->disconnected))
			goto loop_disconnected;
		if (hdev->state == USB_STATE_NOTATTACHED) {	//判断是否为USB_STATE_NOTATTACHED状态
			hub->error = -ENODEV;
			hub_quiesce(hub, HUB_DISCONNECT);
			goto loop;
		}
		ret = usb_autopm_get_interface(intf);
		if (ret) {
			dev_dbg(hub_dev, "Can't autoresume: %d\n", ret);
			goto loop;
		}
		if (hub->quiescing)
			goto loop_autopm;
		if (hub->error) {
			dev_dbg (hub_dev, "resetting for error %d\n",hub->error);
			ret = usb_reset_device(hdev);	
			if (ret) {
				dev_dbg (hub_dev,"error resetting hub: %d\n", ret);
				goto loop_autopm;
			}
			hub->nerrors = 0;
			hub->error = 0;
		}
		for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {
			if (test_bit(i, hub->busy_bits))
				continue;
			connect_change = test_bit(i, hub->change_bits);	//判断是否hub口状态变化
			if (!test_and_clear_bit(i, hub->event_bits) &&!connect_change)
				continue;
			ret = hub_port_status(hub, i,&portstatus, &portchange);
			if (ret < 0)
				continue;
			if (portchange & USB_PORT_STAT_C_CONNECTION) {	//hub口连接上设备
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_CONNECTION);
				connect_change = 1;
			}
			if (portchange & USB_PORT_STAT_C_ENABLE) {	//hub口的设备使能
				if (!connect_change)
					dev_dbg (hub_dev,"port %d enable change,status %08x\n",i, portstatus);
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_ENABLE);
				if (!(portstatus & USB_PORT_STAT_ENABLE)&& !connect_change&& hdev->children[i-1]) {
					dev_err (hub_dev,"port %i disabled by hub (EMI?),re-enabling...\n",i);
					connect_change = 1;
				}
			}
			if (portchange & USB_PORT_STAT_C_SUSPEND) {	//hub口的设备挂起
				struct usb_device *udev;
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_SUSPEND);
				udev = hdev->children[i-1];
				if (udev) {
					msleep(10);
					usb_lock_device(udev);
					ret = usb_remote_wakeup(hdev->children[i-1]);
					usb_unlock_device(udev);
					if (ret < 0)
						connect_change = 1;
				} else {
					ret = -ENODEV;
					hub_port_disable(hub, i, 1);
				}
				dev_dbg (hub_dev,"resume on port %d, status %d\n",i, ret);
			}
			
			if (portchange & USB_PORT_STAT_C_OVERCURRENT) {	//hub口设备过流
				dev_err (hub_dev,"over-current change on port %d\n",i);
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_OVER_CURRENT);
				hub_power_on(hub, true);
			}
			if (portchange & USB_PORT_STAT_C_RESET) {	//hub口设备重置
				dev_dbg (hub_dev,"reset change on port %d\n",i);
				clear_port_feature(hdev, i,USB_PORT_FEAT_C_RESET);
			}

			if (connect_change)	//hub口有变化(设备插入肯定有变化)
				hub_port_connect_change(hub, i,portstatus, portchange);	//hub口变化处理
		}
		if (test_and_clear_bit(0, hub->event_bits) == 0)
			;			
		else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
			dev_err (hub_dev, "get_hub_status failed\n");
		else {
			if (hubchange & HUB_CHANGE_LOCAL_POWER) {
				dev_dbg (hub_dev, "power change\n");
				clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
				if (hubstatus & HUB_STATUS_LOCAL_POWER)
					hub->limited_power = 1;
				else
					hub->limited_power = 0;
			}
			if (hubchange & HUB_CHANGE_OVERCURRENT) {
				dev_dbg (hub_dev, "overcurrent change\n");
				msleep(500);
				clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
                        	hub_power_on(hub, true);
			}
		}
 loop_autopm:
		usb_autopm_put_interface_no_suspend(intf);
 loop:
		usb_autopm_put_interface(intf);
 loop_disconnected:
		usb_unlock_device(hdev);
		kref_put(&hub->kref, hub_release);
        }
}

hub口状态变化处理函数

static void hub_port_connect_change(struct usb_hub *hub, int port1,u16 portstatus, u16 portchange)
{
	struct usb_device *hdev = hub->hdev;
	struct device *hub_dev = hub->intfdev;
	struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
	unsigned wHubCharacteristics =le16_to_cpu(hub->descriptor->wHubCharacteristics);
	struct usb_device *udev;
	int status, i;
	dev_dbg (hub_dev,"port %d, status %04x, change %04x, %s\n",port1, portstatus, portchange, portspeed (portstatus));
	if (hub->has_indicators) {
		set_port_led(hub, port1, HUB_LED_AUTO);
		hub->indicator[port1-1] = INDICATOR_AUTO;
	}
#ifdef	CONFIG_USB_OTG
	if (hdev->bus->is_b_host)
		portchange &= ~(USB_PORT_STAT_C_CONNECTION |USB_PORT_STAT_C_ENABLE);
#endif
	udev = hdev->children[port1-1];	//获取usb_device
	if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&udev->state != USB_STATE_NOTATTACHED) {
		usb_lock_device(udev);
		if (portstatus & USB_PORT_STAT_ENABLE) {
			status = 0;
#ifdef CONFIG_USB_SUSPEND
		} else if (udev->state == USB_STATE_SUSPENDED &&udev->persist_enabled) {
			status = usb_remote_wakeup(udev);
#endif
		} else {
			status = -ENODEV;
		}
		usb_unlock_device(udev);
		if (status == 0) {
			clear_bit(port1, hub->change_bits);
			return;
		}
	}
	if (udev)
		usb_disconnect(&hdev->children[port1-1]);
	clear_bit(port1, hub->change_bits);	//清除标志位
	if (!(portstatus & USB_PORT_STAT_CONNECTION) ||(portchange & USB_PORT_STAT_C_CONNECTION))
		clear_bit(port1, hub->removed_bits);
	if (portchange & (USB_PORT_STAT_C_CONNECTION |USB_PORT_STAT_C_ENABLE)) {
		status = hub_port_debounce(hub, port1);
		if (status < 0) {
			if (printk_ratelimit())
				dev_err(hub_dev, "connect-debounce failed,port %d disabled\n", port1);
			portstatus &= ~USB_PORT_STAT_CONNECTION;
		} else {
			portstatus = status;
		}
	}
	if (!(portstatus & USB_PORT_STAT_CONNECTION) ||test_bit(port1, hub->removed_bits)) {
		if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2&& !(portstatus & USB_PORT_STAT_POWER))
			set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
		if (portstatus & USB_PORT_STAT_ENABLE)
  			goto done;
		return;
	}
	for (i = 0; i < SET_CONFIG_TRIES; i++) {	//配置usb设备
		udev = usb_alloc_dev(hdev, hdev->bus, port1);		//分配usb_device
		if (!udev) {
			dev_err (hub_dev,"couldn't allocate port %d usb_device\n",port1);
			goto done;
		}
		usb_set_device_state(udev, USB_STATE_POWERED);	//设置usb设备为得电态
 		udev->bus_mA = hub->mA_per_port;	//指定其电流限额
		udev->level = hdev->level + 1;	//层数为所属的hub的层数+1
		udev->wusb = hub_is_wusb(hub);
		if (!(hcd->driver->flags & HCD_USB3))	//usb设备速度
			udev->speed = USB_SPEED_UNKNOWN;
		else if ((hdev->parent == NULL) &&(portstatus & USB_PORT_STAT_SUPER_SPEED))
			udev->speed = USB_SPEED_SUPER;
		else
			udev->speed = USB_SPEED_UNKNOWN;
		choose_address(udev);	//选择一个usb设备地址
		if (udev->devnum <= 0) {
			status = -ENOTCONN;	/* Don't retry */
			goto loop;
		}
		status = hub_port_init(hub, udev, port1, i);	//初始化hub端口,枚举
		if (status < 0)
			goto loop;
		usb_detect_quirks(udev);
		if (udev->quirks & USB_QUIRK_DELAY_INIT)
			msleep(1000);
		if (udev->descriptor.bDeviceClass == USB_CLASS_HUB&& udev->bus_mA <= 100) {	//若插进来的也是hub
			u16	devstat;
			status = usb_get_status(udev, USB_RECIP_DEVICE, 0,&devstat);
			if (status < 2) {
				dev_dbg(&udev->dev, "get status %d ?\n", status);
				goto loop_disable;
			}
			le16_to_cpus(&devstat);
			if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
				dev_err(&udev->dev,"can't connect bus-powered hub to this port\n");
				if (hub->has_indicators) {
					hub->indicator[port1-1] =INDICATOR_AMBER_BLINK;
					schedule_delayed_work (&hub->leds, 0);
				}
				status = -ENOTCONN;
				goto loop_disable;
			}
		}
 		if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200&& udev->speed == USB_SPEED_FULL&& highspeed_hubs != 0)
			check_highspeed (hub, udev, port1);
		status = 0;
		spin_lock_irq(&device_state_lock);
		if (hdev->state == USB_STATE_NOTATTACHED)
			status = -ENOTCONN;
		else
			hdev->children[port1-1] = udev;	//设置hub usb设备的子设备
		spin_unlock_irq(&device_state_lock);
		if (!status) {
			status = usb_new_device(udev);	//usb添加新设备
			if (status) {
				spin_lock_irq(&device_state_lock);
				hdev->children[port1-1] = NULL;
				spin_unlock_irq(&device_state_lock);
			}
		}
		if (status)
			goto loop_disable;
		status = hub_power_remaining(hub);
		if (status)
			dev_dbg(hub_dev, "%dmA power budget left\n", status);
		return;
loop_disable:
		hub_port_disable(hub, port1, 1);
loop:
		usb_ep0_reinit(udev);
		release_address(udev);
		hub_free_dev(udev);
		usb_put_dev(udev);
		if ((status == -ENOTCONN) || (status == -ENOTSUPP))
			break;
	}
	if (hub->hdev->parent ||!hcd->driver->port_handed_over ||!(hcd->driver->port_handed_over)(hcd, port1))
		dev_err(hub_dev, "unable to enumerate USB device on port %d\n",port1);
 done:
	hub_port_disable(hub, port1, 1);
	if (hcd->driver->relinquish_port && !hub->hdev->parent)
		hcd->driver->relinquish_port(hcd, port1);
}

hub端口初始化

static int hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,int retry_counter)
{
	static DEFINE_MUTEX(usb_address0_mutex);
	struct usb_device	*hdev = hub->hdev;
	struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
	int i, j, retval;
	unsigned	delay = HUB_SHORT_RESET_TIME;
	enum usb_device_speed oldspeed = udev->speed;
	char *speed, *type;
	int devnum = udev->devnum;
	if (!hdev->parent) {
		delay = HUB_ROOT_RESET_TIME;
		if (port1 == hdev->bus->otg_port)
			hdev->bus->b_hnp_enable = 0;
	}
	if (oldspeed == USB_SPEED_LOW)
		delay = HUB_LONG_RESET_TIME;
	mutex_lock(&usb_address0_mutex);
	if (!udev->config && oldspeed == USB_SPEED_SUPER) {
		usb_set_device_state(udev, USB_STATE_DEFAULT);
	} else {
		retval = hub_port_reset(hub, port1, udev, delay);
		if (retval < 0)
			goto fail;
	}
	retval = -ENODEV;
	if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) {
		dev_dbg(&udev->dev, "device reset changed speed!\n");
		goto fail;
	}
	oldspeed = udev->speed;
	switch (udev->speed) {
	case USB_SPEED_SUPER:
	case USB_SPEED_WIRELESS:
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
		break;
	case USB_SPEED_HIGH:
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
		break;
	case USB_SPEED_FULL:
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
		break;
	case USB_SPEED_LOW:
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
		break;
	default:
		goto fail;
	}
 	type = "";
	switch (udev->speed) {
	case USB_SPEED_LOW:	speed = "low";	break;
	case USB_SPEED_FULL:	speed = "full";	break;
	case USB_SPEED_HIGH:	speed = "high";	break;
	case USB_SPEED_SUPER:	speed = "super";	break;
	case USB_SPEED_WIRELESS:	speed = "variable";	type = "Wireless ";	break;
	default: 	speed = "?";	break;
	}
	if (udev->speed != USB_SPEED_SUPER)
		dev_info(&udev->dev,"%s %s speed %sUSB device using %s and address %d\n",
		(udev->config) ? "reset" : "new", speed, type,udev->bus->controller->driver->name, devnum);
	if (hdev->tt) {
		udev->tt = hdev->tt;
		udev->ttport = hdev->ttport;
	} else if (udev->speed != USB_SPEED_HIGH&& hdev->speed == USB_SPEED_HIGH) {
		udev->tt = &hub->tt;
		udev->ttport = port1;
	}
 	for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
		if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) {
			struct usb_device_descriptor *buf;
			int r = 0;
#define GET_DESCRIPTOR_BUFSIZE	64
			buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);
			if (!buf) {
				retval = -ENOMEM;
				continue;
			}
			for (j = 0; j < 3; ++j) {
				buf->bMaxPacketSize0 = 0;
				r = usb_control_msg(udev, usb_rcvaddr0pipe(),USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
					USB_DT_DEVICE << 8, 0,buf, GET_DESCRIPTOR_BUFSIZE,initial_descriptor_timeout);
				//获取描述符
				switch (buf->bMaxPacketSize0) {
				case 8: case 16: case 32: case 64: case 255:
					if (buf->bDescriptorType == USB_DT_DEVICE) {
						r = 0;
						break;
					}
				default:
					if (r == 0)
						r = -EPROTO;
					break;
				}
				if (r == 0)
					break;
			}
			udev->descriptor.bMaxPacketSize0 = buf->bMaxPacketSize0;
			kfree(buf);
			retval = hub_port_reset(hub, port1, udev, delay);
			if (retval < 0)
				goto fail;
			if (oldspeed != udev->speed) {
				dev_dbg(&udev->dev,"device reset changed speed!\n");
				retval = -ENODEV;
				goto fail;
			}
			if (r) {
				dev_err(&udev->dev,"device descriptor read/64, error %d\n",r);
				retval = -EMSGSIZE;
				continue;
			}
#undef GET_DESCRIPTOR_BUFSIZE
		}
		if (udev->wusb == 0) {
			for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
				retval = hub_set_address(udev, devnum);	//hub设置usb地址并告诉usb设备
				if (retval >= 0)
					break;
				msleep(200);
			}
			if (retval < 0) {
				dev_err(&udev->dev,"device not accepting address %d, error %d\n",devnum, retval);
				goto fail;
			}
			if (udev->speed == USB_SPEED_SUPER) {
				devnum = udev->devnum;
				dev_info(&udev->dev,"%s SuperSpeed USB device using %s and address %d\n",
				(udev->config) ? "reset" : "new",udev->bus->controller->driver->name, devnum);
			}
			msleep(10);
			if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3))
				break;
  		}

		retval = usb_get_device_descriptor(udev, 8);	//获取设备描述符先读8字节
		if (retval < 8) {
			dev_err(&udev->dev,"device descriptor read/8, error %d\n",retval);
			if (retval >= 0)
				retval = -EMSGSIZE;
		} else {
			retval = 0;
			break;
		}
	}
	if (retval)
		goto fail;
	if (udev->descriptor.bMaxPacketSize0 == 0xff ||
			udev->speed == USB_SPEED_SUPER)
		i = 512;
	else
		i = udev->descriptor.bMaxPacketSize0;
	if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
		if (udev->speed == USB_SPEED_LOW ||!(i == 8 || i == 16 || i == 32 || i == 64)) {
			dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i);
			retval = -EMSGSIZE;
			goto fail;
		}
		if (udev->speed == USB_SPEED_FULL)
			dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
		else
			dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i);
		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
		usb_ep0_reinit(udev);
	}
  	retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);	//再次获取设备描述符
	if (retval < (signed)sizeof(udev->descriptor)) {
		dev_err(&udev->dev, "device descriptor read/all, error %d\n",
			retval);
		if (retval >= 0)
			retval = -ENOMSG;
		goto fail;
	}
	retval = 0;
	if (hcd->driver->update_device)
		hcd->driver->update_device(hcd, udev);
fail:
	if (retval) {
		hub_port_disable(hub, port1, 0);
		update_address(udev, devnum);	/* for disconnect processing */
	}
	mutex_unlock(&usb_address0_mutex);
	return retval;
}

usb_new_device

int usb_new_device(struct usb_device *udev)
{
	int err;
	if (udev->parent) {
		device_init_wakeup(&udev->dev, 0);
	}
	pm_runtime_set_active(&udev->dev);
	pm_runtime_enable(&udev->dev);
	err = usb_enumerate_device(udev);	//读取usb设备的描述符信息
	if (err < 0)
		goto fail;
	dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",udev->devnum, udev->bus->busnum,
			(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
	udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));	//分配设备号
	announce_device(udev);	//打印usb设备厂商啊啥的信息
	device_enable_async_suspend(&udev->dev);
	err = device_add(&udev->dev);	//添加设备(至此usb枚举完了)-->usb设备与驱动的匹配
	if (err) {
		dev_err(&udev->dev, "can't device_add, error %d\n", err);
		goto fail;
	}
	(void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);
	return err;

fail:
	usb_set_device_state(udev, USB_STATE_NOTATTACHED);
	pm_runtime_disable(&udev->dev);
	pm_runtime_set_suspended(&udev->dev);
	return err;
}

usb_enumerate_device

static int usb_enumerate_device(struct usb_device *udev)
{
	int err;
	if (udev->config == NULL) {
		err = usb_get_configuration(udev);	//usb获取配置描述符
		if (err < 0) {
			dev_err(&udev->dev, "can't read configurations, error %d\n",err);
			goto fail;
		}
	}
	if (udev->wusb == 1 && udev->authorized == 0) {
		udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
		udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
		udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
	}
	else {
		udev->product = usb_cache_string(udev, udev->descriptor.iProduct);	//设置产品id
		udev->manufacturer = usb_cache_string(udev,udev->descriptor.iManufacturer);	//设置厂商id
		udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);	//设置产品序列号
	}
	err = usb_enumerate_device_otg(udev);
fail:
	return err;
}

device_add函数会出发总线的通知链发送通知,最终会调用总线的match方法

usb设备和驱动一旦match,则会调用驱动的drvwrap.driver.probe方法

若是设备则调用usb_probe_device

若是接口则调用usb_probe_interface
这里我们调用的是usb接口的,也就是usb_probe_interface

static int usb_probe_interface(struct device *dev)
{
	struct usb_driver *driver = to_usb_driver(dev->driver);
	struct usb_interface *intf = to_usb_interface(dev);
	struct usb_device *udev = interface_to_usbdev(intf);
	const struct usb_device_id *id;
	int error = -ENODEV;
	dev_dbg(dev, "%s\n", __func__);
	intf->needs_binding = 0;
	if (usb_device_is_owned(udev))
		return error;
	if (udev->authorized == 0) {
		dev_err(&intf->dev, "Device is not authorized for usage\n");
		return error;
	}
	id = usb_match_id(intf, driver->id_table);	//静态id匹配
	if (!id)
		id = usb_match_dynamic_id(intf, driver);	//动态id匹配
	if (!id)
		return error;
	dev_dbg(dev, "%s - got id\n", __func__);
	error = usb_autoresume_device(udev);
	if (error)
		return error;
	intf->condition = USB_INTERFACE_BINDING;
	pm_runtime_set_active(dev);
	pm_suspend_ignore_children(dev, false);
	if (driver->supports_autosuspend)
		pm_runtime_enable(dev);
	if (intf->needs_altsetting0) {
		error = usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
		if (error < 0)
			goto err;
		intf->needs_altsetting0 = 0;
	}
	error = driver->probe(intf, id);	//最终调用usb驱动的probe方法
	if (error)
		goto err;
	intf->condition = USB_INTERFACE_BOUND;
	usb_autosuspend_device(udev);
	return error;
err:
	intf->needs_remote_wakeup = 0;
	intf->condition = USB_INTERFACE_UNBOUND;
	usb_cancel_queued_reset(intf);
	if (driver->supports_autosuspend)
		pm_runtime_disable(dev);
	pm_runtime_set_suspended(dev);
	usb_autosuspend_device(udev);
	return error;
}

一般在usb设备驱动的probe方法中会调用usb_alloc_urb分配urb

usb_fill_int_urb
usb_fill_bulk_urb
usb_fill_control_urb
填充urb

然后用usb_submit_urb提交urb

int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
{
	int	xfertype, max;
	struct usb_device	*dev;
	struct usb_host_endpoint	*ep;
	int	is_out;
	if (!urb || urb->hcpriv || !urb->complete)
		return -EINVAL;
	dev = urb->dev;
	if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
		return -ENODEV;
	ep = usb_pipe_endpoint(dev, urb->pipe);	//获取端点
	if (!ep)
		return -ENOENT;
	urb->ep = ep;	//设置端点
	urb->status = -EINPROGRESS;
	urb->actual_length = 0;
	xfertype = usb_endpoint_type(&ep->desc);
	if (xfertype == USB_ENDPOINT_XFER_CONTROL) {	//控制传输
		struct usb_ctrlrequest *setup =(struct usb_ctrlrequest *) urb->setup_packet;	//设置setup包
		if (!setup)
			return -ENOEXEC;
		is_out = !(setup->bRequestType & USB_DIR_IN) ||!setup->wLength;
	} else {
		is_out = usb_endpoint_dir_out(&ep->desc);
	}

	urb->transfer_flags &= ~(URB_DIR_MASK | URB_DMA_MAP_SINGLE |URB_DMA_MAP_PAGE | URB_DMA_MAP_SG | URB_MAP_LOCAL |
			URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |URB_DMA_SG_COMBINED);
	urb->transfer_flags |= (is_out ? URB_DIR_OUT : URB_DIR_IN);	//输入还是输出端点
	if (xfertype != USB_ENDPOINT_XFER_CONTROL &&dev->state < USB_STATE_CONFIGURED)
		return -ENODEV;
	max = le16_to_cpu(ep->desc.wMaxPacketSize);
	if (max <= 0) {
		dev_dbg(&dev->dev,"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
			usb_endpoint_num(&ep->desc), is_out ? "out" : "in",__func__, max);
		return -EMSGSIZE;
	}
	if (xfertype == USB_ENDPOINT_XFER_ISOC) {	//同步传输
		int	n, len;
		if (dev->speed == USB_SPEED_HIGH) {
			int	mult = 1 + ((max >> 11) & 0x03);
			max &= 0x07ff;
			max *= mult;
		}
		if (urb->number_of_packets <= 0)
			return -EINVAL;
		for (n = 0; n < urb->number_of_packets; n++) {
			len = urb->iso_frame_desc[n].length;
			if (len < 0 || len > max)
				return -EMSGSIZE;
			urb->iso_frame_desc[n].status = -EXDEV;
			urb->iso_frame_desc[n].actual_length = 0;
		}
	}
	if (urb->transfer_buffer_length > INT_MAX)
		return -EMSGSIZE;
	switch (xfertype) {	//传输类型
	case USB_ENDPOINT_XFER_ISOC:	//同步传输
	case USB_ENDPOINT_XFER_INT:		//中断传输
		switch (dev->speed) {
		case USB_SPEED_WIRELESS:	//无线?
			if (urb->interval < 6)
				return -EINVAL;
			break;
		default:
			if (urb->interval <= 0)
				return -EINVAL;
			break;
		}
		switch (dev->speed) {
		case USB_SPEED_SUPER:	//超速设备
			if (urb->interval > (1 << 15))
				return -EINVAL;
			max = 1 << 15;
			break;
		case USB_SPEED_WIRELESS:	//无线?
			if (urb->interval > 16)
				return -EINVAL;
			break;
		case USB_SPEED_HIGH:	//高速设备
			if (urb->interval > (1024 * 8))
				urb->interval = 1024 * 8;
			max = 1024 * 8;
			break;
		case USB_SPEED_FULL:	//全速
		case USB_SPEED_LOW:		//低速
			if (xfertype == USB_ENDPOINT_XFER_INT) {
				if (urb->interval > 255)
					return -EINVAL;
				max = 128;
			} else {
				if (urb->interval > 1024)
					urb->interval = 1024;

				max = 1024;
			}
			break;
		default:
			return -EINVAL;
		}
		if (dev->speed != USB_SPEED_WIRELESS) {
			urb->interval = min(max, 1 << ilog2(urb->interval));
		}
	}
	return usb_hcd_submit_urb(urb, mem_flags);
}

调用主控器usb_hcd_submit_urb

int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
{
	int	status;
	struct usb_hcd	*hcd = bus_to_hcd(urb->dev->bus);
	usb_get_urb(urb);
	atomic_inc(&urb->use_count);
	atomic_inc(&urb->dev->urbnum);
	usbmon_urb_submit(&hcd->self, urb);
	if (is_root_hub(urb->dev)) {	//这次不是根hub
		status = rh_urb_enqueue(hcd, urb);
	} else {
		status = map_urb_for_dma(hcd, urb, mem_flags);
		if (likely(status == 0)) {
			status = hcd->driver->urb_enqueue(hcd, urb, mem_flags);	//调用主控器的urb_enqueue方法
			if (unlikely(status))
				unmap_urb_for_dma(hcd, urb);
		}
	}
	if (unlikely(status)) {
		usbmon_urb_submit_error(&hcd->self, urb, status);
		urb->hcpriv = NULL;
		INIT_LIST_HEAD(&urb->urb_list);
		atomic_dec(&urb->use_count);
		atomic_dec(&urb->dev->urbnum);
		if (atomic_read(&urb->reject))
			wake_up(&usb_kill_urb_queue);
		usb_put_urb(urb);
	}
	return status;
}


<---usb设备注册

 

 

 

 

 


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值