Re: [PATCH 1/1] HID: usbhid: add usb_clear_halt determination for next hid_start_in

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 24 Aug 2014, vichy wrote:

> 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.

Yes, that's right.  I should have said: "Because the post_reset routine 
failed, usb_unbind_and_rebind_marked_interfaces indirectly calls 
usbhid_disconnect.

> >         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 gets called when the driver is unbound, regardless of
whether the device was unplugged.  The kernel unbinds a driver when a
device is reset but the driver isn't able to handle the reset.

> >         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);
> }

I don't remember the entire call chain.  It was pretty long.  
hid_destroy_device calls hid_remove_device, which calls device_del,
which calls lots of other things.  If you really want to see all the
details, put a dump_stack() call in usbhid_close and examine what it
prints in the kernel log when you unplug an HID device.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux