hi Alan: > > I originally tried using usb_reset_device, and it caused a deadlock: > > Unplug the HID device. > > I/O error occurs. hid_io_error schedules reset_work. > > The reset_work callback routine is hid_reset. It calls > usb_reset_device. > > The reset fails because the device is gone. At the end of the > reset, hid_post_reset is called. > > hid_post_reset returns 1 because hid_get_class_descriptor > fails. > > Because the post_reset routine failed, usb_reset_device calls > usb_unbind_and_rebind_marked_interfaces. "usb_unbind_and_rebind_marked_interfaces" is called if config parameter is not null, it seems no matter post_reset routine fail or not. > > That routine indirectly calls usbhid_disconnect. Why that routine, usb_reset_device, will call usbhid_disconnect? No matter port reset success or fail, usbhid_disconnect should not be called except that did happen disconnection. > > usbhid_disconnect calls usbhid_close by way of > hid_destroy_device. below is the content of hid_destroy and hid_remove_device, but I cannot find where usbhid_close be called by way of hid_destroy_device. static void hid_remove_device(struct hid_device *hdev) { if (hdev->status & HID_STAT_ADDED) { device_del(&hdev->dev); hid_debug_unregister(hdev); hdev->status &= ~HID_STAT_ADDED; } kfree(hdev->dev_rdesc); hdev->dev_rdesc = NULL; hdev->dev_rsize = 0; } void hid_destroy_device(struct hid_device *hdev) { hid_remove_device(hdev); put_device(&hdev->dev); } > > usbhid_close calls hid_cancel_delayed_stuff. > > hid_cancel_delayed_stuff calls cancel_work_sync for reset_work. > > So the reset_work routine tries to cancel itself synchronously while it > is running. usb_queue_reset_device was carefully written to avoid such > deadlocks. > thanks for your help, -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html