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 得以继续执行。

usb host 驱动 - device 拔插相关推荐

  1. PCIe实践之路:PCIe转USB Host驱动

    PCIe实践之路:PCIe转USB Host驱动 本次调试PCIe RC驱动,通过PCIe转USB芯片扩展出的USB口接入U盘.RC平台为ARM-A7,运行裸机环境,EP为一款PCIe转USB3.0芯 ...

  2. USB 3G驱动和USB HOST驱动加载

    ********************************LoongEmbedded******************************** 作者:LoongEmbedded(kandi ...

  3. STM32之独立版USB(Host)驱动+MSC+Fatfs移植

    源:STM32之独立版USB(Host)驱动+MSC+Fatfs移植 STM32之USB驱动库详解(架构+文件+函数+使用说明+示例程序)

  4. 详解WinCE下USB Host驱动开发(2)

    当用户需要卸载USB Host设备驱动时,将会调用USBUnInstallDriver函数 BOOL USBUnInstallDriver();     它与USBInstallDriver类似,不过 ...

  5. linux驱动编写(usb host驱动入门)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] usb协议是一个复杂的协议,目前涉及到的版本就有usb1.0, usb2.0, usb3.0.大 ...

  6. linux usb驱动教学视频教程,详解linux usb host驱动编写入门

    usb协议是一个复杂的协议,目前涉及到的版本就有usb1.0, usb2.0, usb3.0.大家如果打开kernel usb host目录,就会发现下面包含了ohci,uhci,ehci,xhci, ...

  7. win10开机USB鼠标要重新拔插才能用的解决方法

    原文地址http://tieba.baidu.com/p/5349926341 我装上win10后,第一时间就装了360,然后用360体检电脑,默认检测出了一堆要优化的选项,按照之前的习惯和对360的 ...

  8. usb host 驱动之 urb

    1.URB 处理流程 (1)usb 设备驱动程序创建并初始化一个访问特定usb设备特定端点的 urb,并提交给 usb core: (2)usb core 提交该 urb 到 usb 主控制器驱动程序 ...

  9. usb host 驱动 - UVC 掉包

    1. issue description yavta 是一款测试APP,测试UVC 摄像头的数据采集回传. yavta -f YUYV -s 1280x720 -t 1/60 -c100 /dev/v ...

最新文章

  1. CVPR2021|基于双边扩充和自适应融合方法的点云语义分割网络
  2. html 中ajax 请求没反应,ajax请求数据成功,页面的数据没有加载出来
  3. Swift - 闭包的介绍及用法(以数组排序为例)
  4. apache rewrite 规则转换 nginx rewrite 的网站
  5. c# string 占位符_C# 基础知识系列- 9 字符串的更多用法(一)
  6. SAP Data Intelligence上的Python Operator
  7. mysql数据库版本不同_MySQL不同版本数据同步
  8. coreboot学习3:启动流程跟踪之bootblock阶段
  9. 个人作业-四则运算题目生成程序(基于控制台)
  10. 【matplotlib】对x轴标签进行旋转的方法小结
  11. mysql中如何将一个表中的部分记录合并,mysql - 如何从一个表中获取所有产品并从另一个包含多行的表中合并一行? - SO中文参考 - www.soinside.com...
  12. Android游戏开发入门基础
  13. 18-HTML标签的居中
  14. 手机ncm转mp3工具_一款手机、电脑都能用的文字转语音工具,够高能! - 橘子世界...
  15. 【百度大脑新品体验】行驶证识别
  16. 下拉框 切换一个下拉框 另一个下拉框做相应的改变
  17. python程序只能在安装了python环境的计算机上_Python程序只能在安装了Python环境的计算机上以源代码形式运行。...
  18. 螺杆支撑座如何避雷要害
  19. win10卸载python3
  20. 论颈椎病与架构师的关系

热门文章

  1. 天下3 修改默认服务器,《天下3》默认字体修改指引 简单轻松
  2. 15条搜狗快速排名策略,让您站在搜索引擎的前列!
  3. 盘点|2021年最受欢迎Linux桌面操作系统top10
  4. 图像质量评价常用数据库下载 |LIVE|MICT|CSIQ|TID2013|CID2013|CCID2014|LIVE-Challenge|LIVE-MultiDistortion|IVC_sub
  5. 认识Linux系统以及Linux命令的使用(未完待续)
  6. IBM服务器装系统看不到硬盘,IBM SATA硬盘的笔记本安装系统找不到硬盘解决方案...
  7. 全志A64平台由于没有SD/TF卡座进不了系统
  8. 对于脚本木马的免杀(特别针对安全狗的V3.0)的经验副过狗菜刀
  9. matlab三维可视化,MATLAB中三维数据可视化及应用
  10. 给创维电视装鸿蒙,创维电视怎么安装第三方应用?这个方法轻松教你搞定