usb host 驱动 - device 拔插

这篇具有很好参考价值的文章主要介绍了usb host 驱动 - device 拔插。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. usbhid 设备拔插

1.1 usb device disconnect

1.1.1 上层卸载usb 设备驱动

生成应用通过ioctl 卸载usb 设备。

[ 709.471619] [T29796] Kernel panic - not syncing: Object already free
[ 709.478060] [T29796] CPU: 4 PID: 29796 Comm: GConnection0 Tainted: G S B O 5.4.134-qgki-debug-g8c50b8eb5d9c #1
[ 709.489217] [T29796] Hardware name: xxxx. 
[ 709.497527] [T29796] Call trace:
[ 709.500761] [T29796] dump_backtrace.cfi_jt+0x0/0x4
[ 709.505687] [T29796] show_stack+0x18/0x24
[ 709.509815] [T29796] dump_stack+0xd8/0x158
[ 709.514027] [T29796] panic+0x18c/0x400
[ 709.517880] [T29796] kmem_cache_flags+0x0/0xc4
[ 709.522451] [T29796] slab_bug+0x0/0xe0
[ 709.526304] [T29796] free_debug_processing+0x3fc/0x448
[ 709.531588] [T29796] __slab_free+0x64/0x368
[ 709.535895] [T29796] kfree+0x2c4/0x370
[ 709.539748] [T29796] usbhid_stop+0x178/0x1fc
[ 709.544138] [T29796] hid_hw_stop+0x9c/0xf8
[ 709.548350] [T29796] hid_device_remove+0x70/0xd0			// struct bus_type hid_bus_type             .remove = hid_device_remove,
[ 709.553098] [T29796] device_release_driver_internal+0x190/0x2ec		// dev->bus->remove(dev);
[ 709.559180] [T29796] device_release_driver+0x18/0x24		// *dev = &hdev->dev
[ 709.564284] [T29796] bus_remove_device+0x134/0x160
[ 709.569210] [T29796] device_del+0x2e8/0x55c				// device_del(&hdev->dev);    删除 hid_dev
[ 709.573517] [T29796] hid_destroy_device+0x2c/0x6c
[ 709.578360] [T29796] usbhid_disconnect+0x68/0xa4			// driver->disconnect(intf);           intf 驱动
[ 709.583108] [T29796] usb_unbind_interface+0xd0/0x270		// new_driver->drvwrap.driver.remove = usb_unbind_interface;
[ 709.588213] [T29796] device_release_driver_internal+0x1cc/0x2ec	// drv->remove(dev);
[ 709.594295] [T29796] device_release_driver+0x18/0x24		// *dev = &iface->dev;
[ 709.599400] [T29796] usb_driver_release_interface+0x78/0x8c
[ 709.605123] [T29796] proc_ioctl+0x224/0x258
[ 709.609430] [T29796] usbdev_do_ioctl+0xc7c/0x132c
[ 709.614273] [T29796] usbdev_ioctl+0x10/0x20
[ 709.618580] [T29796] do_vfs_ioctl+0x39c/0x700
[ 709.623064] [T29796] __arm64_sys_ioctl+0x78/0xa4
[ 709.627812] [T29796] el0_svc_common+0xbc/0x1c8
[ 709.632383] [T29796] el0_svc_handler+0x74/0x98
[ 709.636952] [T29796] el0_svc+0x8/0xc

(1)用户空间:

ioctl(fd, IOCTL_USBFS_IOCTL, &command); 	//系统调用,操作设备节点/dev

(2)内核空间:

const struct file_operations usbdev_file_operations = {
	.read =		  usbdev_read,
	.poll =		  usbdev_poll,
	.unlocked_ioctl = usbdev_ioctl,
	.open =		  usbdev_open,
	.release =	  usbdev_release,
};
// 卸载usb 接口设备intf
== usbdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
	== usbdev_do_ioctl(file, cmd, (void __user *)arg);
		== proc_ioctl(struct usb_dev_state *ps, struct usbdevfs_ioctl *ctl);
			//== device_attach(&intf->dev);					// USBDEVFS_CONNECT
			== usb_driver_release_interface(driver, intf);	// USBDEVFS_DISCONNECT
				== device_release_driver(struct device *dev);
					== device_release_driver_internal(dev, NULL, NULL);
						== __device_release_driver(dev, parent);
							== dev->bus->remove(dev);	// usb_bus_type的remove 没有定义
							== drv->remove(dev);		// 故走驱动的remove
								== usb_unbind_interface(struct device *dev);	//如果为接口设备
									== driver->disconnect(intf);
									== usbhid_disconnect(struct usb_interface *intf);
										== hid_destroy_device(struct hid_device *hdev);
											== device_del(&hdev->dev);	
								== usb_unbind_device(struct device *dev);	//如果为device设备	//new_udriver->drvwrap.driver.remove = usb_unbind_device;
									== udriver->disconnect(udev);		//if (udriver->disconnect)
									== usb_generic_driver_disconnect(udev);	//if (udriver->generic_subclass)			
// 	卸载 hid_device (即device_add 相关的device 都需要卸载)
== device_del(&hdev->dev);
	== bus_remove_device(struct device *dev);
		== device_release_driver(struct device *dev);
		== device_release_driver_internal(dev, NULL, NULL);
			== __device_release_driver(dev, parent);
				== dev->bus->remove(dev);		// 在hid_allocate_device()中 hdev->dev.bus = &hid_bus_type;
				== hid_device_remove(struct device *dev);
					== hid_hw_stop(struct hid_device *hdev);
						== hid_disconnect(struct hid_device *hdev);	

1.1.2 热拔插usb 设备

通过手动拔掉 usb 设备。

[ 232.893206] Kernel panic - not syncing: Object already free
[ 232.900455] CPU: 0 PID: 7 Comm: kworker/0:1 Tainted: G S B W 4.19.81+ #13
[ 232.908417] Hardware name: xxx. 
[ 232.914960] Workqueue: usb_hub_wq hub_event
[ 232.919271] Call trace:
[ 232.921804] dump_backtrace+0x0/0x260
[ 232.925578] show_stack+0x20/0x30
[ 232.929002] dump_stack+0xd8/0x12c
[ 232.932515] panic+0x158/0x2e0
[ 232.935669] slab_panic+0x24/0x28
[ 232.939092] slab_bug+0x0/0xe8
[ 232.942246] free_debug_processing+0x660/0x698
[ 232.946827] kfree+0x3dc/0x930
[ 232.949980] hid_free_buffers+0x94/0xd8
[ 232.953939] usbhid_stop+0x17c/0x1b0
[ 232.957629] hid_device_remove+0xa0/0xd0
[ 232.961673] device_release_driver_internal+0x1ac/0x260
[ 232.967057] device_release_driver+0x24/0x30
[ 232.971452] bus_remove_device+0xf0/0x140
[ 232.975581] device_del+0x294/0x4a0 			//device_del(&hdev->dev);    删除 hid_dev
[ 232.979174] hid_destroy_device+0x2c/0x68
[ 232.983303] usbhid_disconnect+0x60/0x90     	// driver->disconnect(intf);           intf 驱动
[ 232.987347] usb_unbind_interface+0xc8/0x278 	// new_driver->drvwrap.driver.remove = usb_unbind_interface;
[ 232.991743] device_release_driver_internal+0x1ac/0x260      // drv->remove(dev);
[ 232.997126] device_release_driver+0x24/0x30
[ 233.001521] bus_remove_device+0xf0/0x140
[ 233.005648] device_del+0x294/0x4a0  			//device_del(&udev->dev);     删除设备: usb 1-1: USB disconnect, device number 3
[ 233.009252] usb_disable_device+0x120/0x398   	// unregister 该device 含有的所有interface           for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++)
[ 233.013562] usb_disconnect+0xf8/0x2f0
[ 233.017433] hub_event+0xd84/0x1810
[ 233.021037] process_one_work+0x33c/0x6c8
[ 233.025166] worker_thread+0x330/0x4d0
[ 233.029036] kthread+0x128/0x138
[ 233.032362] ret_from_fork+0x10/0x1c

hub 检测到usb 设备拔插event 后,就会卸载操作。

== usb_disconnect(struct usb_device **pdev);
	== usb_disable_device(udev, 0);		//卸载device 的接口设备
		== device_del(&interface->dev);
			== bus_remove_device(struct device *dev);
				== device_release_driver(struct device *dev);
					== __device_release_driver(dev, parent);
						== dev->bus->remove(dev);	//if (dev->bus && dev->bus->remove)
						== drv->remove(dev);		//else if (drv->remove)
	== device_del(&udev->dev);

1.2 usb device connect

插入动作同样是 hub 检测,然后加载操作。

== device_add(struct device *dev);
	== kobject_add(&dev->kobj, dev->kobj.parent, NULL);
	== device_create_file(dev, &dev_attr_uevent);
	== device_create_file(dev, &dev_attr_dev);
	== bus_probe_device(dev);
		== device_initial_probe(struct device *dev);
			== __device_attach(dev, true);
				== __device_attach_driver(struct device_driver *drv, void *_data);
					== driver_match_device(struct device_driver *drv, struct device *dev)
						== return drv->bus->match ? drv->bus->match(dev, drv) : 1;	//new_udriver->drvwrap.driver.bus = &usb_bus_type;
							== usb_device_match(struct device *dev, struct device_driver *drv);
					== driver_probe_device(drv, dev);
						== really_probe(dev, drv);
							== if (dev->bus->probe) { ret = dev->bus->probe(dev);} 	//dev->dev.bus = &usb_bus_type;
								== usb_bus_type 没有定义probe
							== else if (drv->probe) {ret = drv->probe(dev);}	//new_udriver->drvwrap.driver.probe = usb_probe_device;
								== usb_probe_device(struct device *dev);
									== usb_generic_driver_probe(struct usb_device *udev);	//if (udriver->generic_subclass) 通用usb_device_driver 的probe
									== udriver->probe(udev);	//私有udriver 的probe

2. U -disk 设备拔插

2.1 plug in

hub 状态变化:

3-0:1.0: state 7 ports 1 chg 0002 evt 0000		//hub_event打印log

2.1.1 hub_resume

== usb_resume(struct device *dev, pm_message_t msg);
	== usb_resume_both(struct usb_device *udev, pm_message_t msg);
		== usb_resume_device(struct usb_device *udev, pm_message_t msg);
			== usb_generic_driver_resume(udev, msg);	//if (udriver->generic_subclass)
				== hcd_bus_resume(udev, msg);	//root hub: if (!udev->parent)
				== usb_port_resume(udev, msg);	//非root hub
		== usb_resume_interface(struct usb_device *udev, struct usb_interface *intf, pm_message_t msg, int reset_resume);
			== driver->resume(intf);
			== hub_resume(struct usb_interface *intf);
				== hub_activate(hub, HUB_RESUME);
					== set_bit(port1, hub->change_bits);
					== kick_hub_wq(hub);
						== queue_work(hub_wq, &hub->events);
						== hub_event(struct work_struct *work);
							== port_event(struct usb_hub *hub, int port1);

2.2 pull out

2.2.1 usb2.0 设备和otg

先断开U 盘设备:

== hub_event(struct work_struct *work);
	== port_event(struct usb_hub *hub, int port1);
		== hub_port_connect_change(hub, port1, portstatus, portchange);
			== hub_port_connect(hub, port1, portstatus, portchange);
				== usb_disconnect(struct usb_device **pdev);		

后响应otg 断开:

//mdwc 接收到事件,执行 dwc3_otg_sm_work,并调用dwc3 
== __dwc3_set_mode(struct work_struct *work);
	== dwc3_host_exit(struct dwc3 *dwc);
		== platform_device_unregister(dwc->xhci);
			== xhci_plat_remove(struct platform_device *dev);
				== usb_remove_hcd(struct usb_hcd *hcd);
					== usb_disconnect(&rhdev);		/* Sets rhdev to NULL */
						== hub_disconnect_children(struct usb_device *udev);
						== usb_disable_device(udev, 0);
							== device_del(&interface->dev);
								== hub_disconnect(struct usb_interface *intf);
									== hub_quiesce(hub, HUB_DISCONNECT);
										== usb_disconnect(&hub->ports[i]->child);	//不执行,前面已disconnect
						== device_del(&udev->dev);

2.2.2 usb3.0 设备和otg

(1)reset U 盘设备:

== hub_event(struct work_struct *work);
	== usb_lock_device(hdev);		//struct usb_device *hdev; 该设备被hub_event 占用
	== port_event(struct usb_hub *hub, int port1);
		== usb_lock_device(udev);	//struct usb_device *udev = port_dev->child;
		== usb_reset_device(udev);		//3.0 设备需要reset	Warns all drivers bound to registered interfaces (using their pre_reset method), performs the port reset, 
										//and then lets the drivers know that the reset is over (using their post_reset method).
			== usb_reset_and_verify_device(udev);
				== hub_port_init(parent_hub, udev, port1, i);
					== hub_port_reset(hub, port1, udev, delay, false);
				== hub_port_logical_disconnect(parent_hub, port1);
					== set_bit(port1, hub->change_bits);
					== kick_hub_wq(hub);
						== queue_work(hub_wq, &hub->events);
							== hub_event();		//再次进入hub_event
		== usb_unlock_device(udev);
	== usb_unlock_device(hdev);		

(2)由于usb_reset_device 会消耗部分时间,故期间会响应otg 断开:

//mdwc 接收到事件,执行 dwc3_otg_sm_work,并调用dwc3 
== __dwc3_set_mode(struct work_struct *work);
	== dwc3_host_exit(struct dwc3 *dwc);
		== platform_device_unregister(dwc->xhci);
			== xhci_plat_remove(struct platform_device *dev);
				== usb_remove_hcd(struct usb_hcd *hcd);
					== usb_disconnect(&rhdev);		/* Sets rhdev to NULL */
						== usb_set_device_state(udev, USB_STATE_NOTATTACHED);
						== usb_lock_device(udev);	//需要获取hdev 的锁,但是被hub_event 占用,故等待

(3)reset U盘之后再次hub_event:

== hub_event();		
	== 	hub_quiesce(hub, HUB_DISCONNECT);  	//usb_remove_hcd进程中设置了hdev->state == USB_STATE_NOTATTACHED
											/* If the hub has died, clean up after it */
		== usb_disconnect(&hub->ports[i]->child);		//Disconnect all the children
		== usb_kill_urb(hub->urb);	

(4)上面hub_event 完成后,会释放锁,usb_remove_hcd 得以继续执行。文章来源地址https://www.toymoban.com/news/detail-481771.html

到了这里,关于usb host 驱动 - device 拔插的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Android】adb devices找不到设备驱动的解决方法

    初次使用难免会遇到一些问题,或者换了电脑后操作,按照网上的指导执行命令adb devices找不到设备问题,该怎么办呢,接下来给详细讲一讲。 首先,确保USB连接上电脑的手机上弹出通知提示已启用调试模式, 然后,在电脑上打开终端执行命令adb devices,结果可能如下,问题

    2024年02月07日
    浏览(101)
  • usb摄像头驱动-core层usb设备的注册

    在ubuntu中接入罗技c920摄像头打印的信息如下: 在内核中,/driver/usb/core/driver.c 文件扮演了 USB 核心驱动程序管理的重要角色。该文件包含了 USB 核心驱动程序的实现,负责管理和调度 USB 设备的注册、匹配、连接和断开等操作。 具体而言,driver.c 文件的功能和作用包括: USB

    2024年02月06日
    浏览(53)
  • STM32MP157驱动开发——USB设备驱动

    参考文章:【正点原子】I.MX6U嵌入式Linux驱动开发——Linux USB驱动   由于 USB 协议太过庞大和复杂,所以本节只对 STM32MP157 自带的 USB 驱动进行使能和测试。详细的 USB 接口和协议的介绍,可以参考原子哥的资料《USB2.0 协议中文版.pdf》和《USB3.0 协议中文版.pdf》。   USB 全

    2023年04月14日
    浏览(54)
  • Linux:主机USB设备驱动简析

    限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 本文基于 linux-4.14.132 内核代码进行分析。 其中: 一个 USB 主机控制器(HCD) 上最多可连接 127 个设备(HUB或Func),每个设备在枚举完成后会分配1个地址,地址区间为1~127,特殊地址0用于在设

    2023年04月21日
    浏览(49)
  • 嵌入式Linux驱动开发——解决/sys/bus/spi/devices下没有对应的spi设备文件

    最近在学习Linux驱动开发中SPI总线的驱动框架,但在修改完设备树添加完对应的spi设备节点后,理应在/sys/bus/spi下会有对应的spi设备,我的目录下面没有。 无spi设备 然后我查看了/proc/device-tree,发现有对应的spi设备节点,我就先没有过多理会这个问题。 /proc/device-tree下有对应

    2024年02月16日
    浏览(46)
  • 记录 无法识别USB串口设备以及由于 Windows 无法加载这个设备所需的驱动程序,导致这个设备工作异常。 (代码 31)

    今天使用串口的时候突然电脑设备器显示无法识别USB设备,在这之前都是一切没有问题,我百思不得其解,于是我百度并且试了很多方法比如说换根线连接,重启电脑,卸载设备(没有卸载芯片)等之类的但是都不起作用。 后来我想起来有虚拟串口这个东西。我这边用的是

    2024年02月12日
    浏览(70)
  • FPGA-(Win11)USB-Blaster无法在此设备上加载驱动解决

    在电脑上连接FPGA的USB-Blaster下载器的时候,可能会出现 无法在此设备上加载驱动 问题,可以通过以下方式解决: 首先这里如果驱动没有安装好,会有感叹号标志! 可以在桌面底部搜索 windows 安全中心 选择 设备安全性 单击顶部的 核心隔离 详细信息选项。 只需要关闭 内存完

    2024年02月09日
    浏览(41)
  • linux|操作系统|centos7物理机安装网卡驱动8188gu(内核升级,firmware固件,USB设备管理,module管理)

    目前服务器领域centos7基本是主流的操作系统,而linux相对于Windows来说,软硬件方面的支持是差很多的,在硬件方面来说,以一个免驱的网卡为例,window xp可能不会自动识别到,但Windows10基本都会自动识别到,简简单单的即插即用。根本原因在Windows随着版本的升级,内置的各

    2024年01月20日
    浏览(88)
  • linux上USB检测异常,报错usb 7-1: device descriptor read/8, error -71

    芯片:RK356x 问题:部分USB设备检测异常;部分设备检测成功,但在使用过程中不稳定,经常断开disconnect然后重新连接connect USB设备插入检测打印信息,如下

    2024年02月15日
    浏览(50)
  • Android usb host模式通信示例

    当使用Android设备作为USB主机时,可以使用Android提供的USB API来进行USB通信。下面是一个简单的Android USB通信的示例。在这个示例中,我们将发送一条消息到连接的USB设备并从USB设备接收响应。 首先,在AndroidManifest.xml文件中添加以下权限: 接着,创建一个Activity,并在onCreate方

    2024年02月15日
    浏览(73)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包