USB mouse 枚举过程 在 linux 上的代码分析2

USB mouse 枚举过程 在 linux 上的代码分析1 讲述了 usb1.0枚举过程 中的 1-4
本篇文章要讲述 usb1.0枚举过程 中的 5-8

在这里插入图片描述

// 关键看 hub_event 是什么时候发生的 TODO
什么时候 什么条件 kick_hub
什么时候 hub_event
  • 可能的流程1
hub_probe
	INIT_WORK(&hub->events, hub_event);

vic_handle_irq
	... 
		usb_hcd_irq
			... 
				hub_irq
					kick_hub_wq(hub);
						queue_work(hub_wq, &hub->events);
  • 可能的流程1
	ohci_irq
		usb_hcd_poll_rh_status
			hcd->driver->hub_status_data // 即ohci_s3c2410_hub_status_data
				ohci_hub_status_data
					ohci_root_hub_state_changes
						usb_hcd_resume_root_hub
							queue_work(pm_wq, &hcd->wakeup_work); // 对应 hcd_resume_work
	kthread->worker_thread->process_one_work // 工作队列 的运行时机 在 worker_thread 内核线程 被调度时
		hcd_resume_work
			usb_remote_wakeup
				[26] usb_remote_wakeup:3646: usb usb1: usb wakeup-resume
				usb_autoresume_device
					__pm_runtime_resume->rpm_resume->rpm_callback->__rpm_callback->usb_resume_both
						usb_resume_device
							usb_generic_driver_resume
								hcd_bus_resume
									[26] hcd_bus_resume:2182: usb usb1: usb auto-resume
									ohci_bus_resume
										ohci_rh_resume
											[26] ohci_rh_resume:184: s3c2410-ohci s3c2410-ohci: wakeup root hub
										usb_hcd_poll_rh_status
						usb_resume_interface
							driver->resume/ 即 hub_resume
								[26] hub_resume:3807: hub 1-0:1.0: hub_resume
								hub_activate
									kick_hub_wq


  • 流程2
kthread
	worker_thread
		process_one_work
			hub_event
				port_event
					hub_port_connect_change
						hub_port_connect
							udev = usb_alloc_dev
							usb_set_device_state(udev, USB_STATE_POWERED);
							choose_devnum(udev); // 原来是 choose_address
							status = hub_port_init(hub, udev, port1, i);
								hub_port_reset(hub, port1, udev, delay, false);	----------------------- 波形1
									// 之后开启 了 1ms 一次的 keep-alive
								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); ----------------------- 波形2
								hub_port_reset(hub, port1, udev, delay, false); ----------------------- 波形3 , 和 波形1 一样
								hub_set_address(udev, devnum);	----------------------- 波形4
								usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE); ----------------------- 波形5
							usb_new_device
								usb_enumerate_device
									usb_get_configuration 
										usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, desc, USB_DT_CONFIG_SIZE);----------------------- 波形6
										usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length);----------------------- 波形7
										usb_parse_configuration
											usb_parse_interface
												[26] usb_parse_interface:554: usb 1-1: skipped 1 descriptor after interface
						
									udev->product = usb_cache_string(udev, udev->descriptor.iProduct);----------------------- 波形8
									udev->manufacturer = usb_cache_string(udev, udev->descriptor.iManufacturer);----------------------- 波形9
									udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);----------------------- 波形10
										[26] usb_get_langid:939: usb 1-1: default language 0x0409

								[26] usb_new_device:2529: usb 1-1: udev 2, busnum 1, minor = 1
								device_add
								|		[1] usb_probe_device:255: usb usb1: usb_probe_device
								|
								|
								usb_generic_driver_probe        // USB设备driver
									usb_choose_configuration
										[1] usb_choose_configuration:187: usb usb1: configuration #1 chosen from 1 choice
									usb_set_configuration ----------------------- 波形11
										[1] usb_set_configuration:2181: usb usb1: adding 1-0:1.0 (config #1, interface 0)

										device_add(&intf->dev); // 注册 USB接口device   // 为usbhid接口
										|
										|	   [1] usb_probe_interface:327: hub 1-0:1.0: usb_probe_interface
										|	   [1] usb_probe_interface:349: hub 1-0:1.0: usb_probe_interface - got id
										usbhid_probe		    // USB接口driver
											hid->ll_driver = &usb_hid_driver;
											hid_add_device(hid);
												hdev->ll_driver->parse(hdev); // 即 usbhid_parse
													hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); 
														usb_control_msg(dev, usb_sndctrlpipe(dev, 0),HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report,ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
															----------------------- 波形12
															参考hid1_11.pdf 7.2 Class-Specific Requests
													hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize);
														usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,(type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT);
															----------------------- 波形13
															参考hid1_11.pdf 7.1.1 Get_Descriptor Request
															GET_DESCRIPTOR  , Descriptor Type : Report , Length : 64

之后流程的参考

按时间发生的参考波形
  • 周期性波形
    在这里插入图片描述

  • 波形1 : port init 后的 port reset
    在这里插入图片描述

  • 波形2 : 对设备的标准请求:获取 设备描述符 长度为64
    在这里插入图片描述

  • 波形3 : port reset
    在这里插入图片描述

  • 波形4 : 对设备的标准请求:set address ,设置地址为14
    在这里插入图片描述

hub_set_address调用过程中发生了两个中断
	其中 usb_control_msg 有一个
	另外一个  是 什么引起的呢??
下图set_address 为 usb_control_msg  的调用过程

在这里插入图片描述

下图set_address 为 hub_set_address 的调用过程

在这里插入图片描述

  • 波形5 : 对设备的标准请求:获取 设备描述符 长度为18
    在这里插入图片描述

  • 波形6 : 对设备的标准请求:获取 配置描述符 长度为9
    在这里插入图片描述

  • 波形7 : 对设备的标准请求:获取 配置描述符 长度为34
    在这里插入图片描述

  • 波形8 : 对设备的标准请求:获取 字符串描述符 长度为255
    在这里插入图片描述

  • 波形9 : 对设备的标准请求:获取 字符串描述符(index:2,语言ID为0x0409) 长度为255
    在这里插入图片描述

  • 波形10 : 对设备的标准请求:获取 字符串描述符(index:1,语言ID为0x0409) 长度为255
    在这里插入图片描述

  • 波形11 : 对设备的标准请求:设置配置(配置值为1)
    在这里插入图片描述

  • 波形12 : 对接口的类请求 ,bRequest 为 10,为SET_IDLE
    在这里插入图片描述

  • 波形13 : 对接口的HID Class请求:获取Report描述符
    在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值