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
:文章来源:https://www.toymoban.com/news/detail-481771.html
== 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模板网!