Dmitriy Geels wrote: > 2009/5/8 Anssi Hannula <anssi.hannula@xxxxxxxxx>: >> Anssi Hannula wrote: >>> Dmitriy Geels wrote: >>>> 2009/3/8 Anssi Hannula <anssi.hannula@xxxxxxxxx>: >>>>> Dmitriy Geels wrote: >>>>>> 2009/3/7 Anssi Hannula <anssi.hannula@xxxxxxxxx>: >>>>>>> Provide the kernel log again, this time with debug=2 set for hid module >>>>>>> and having run "fftest" with only one effect and then "ffmvforce". >>>>>> here is it: http://paste.org.ru/index.pl?4bwah8 >>>>> Apply attached patch that adds more debug output and try this again. >>>> Here is log: http://paste.org.ru/index.pl?0mtjuz >>>> >>> Sorry for the long delay. >>> >>> Try the attached (untested) patch. It adds a simple timeout to the hid >>> ctrl and out urbs, discarding the faulty urb instead of getting stuck. >> And of course there was an error, attached is a fixed patch :) > Just tried to build module with your patch. It doesn't build. > Fixed patch attached. -- Anssi Hannula
--- drivers/hid/usbhid/hid-core.c | 21 +++++++++++++++++++++ drivers/hid/usbhid/usbhid.h | 2 ++ 2 files changed, 23 insertions(+) Index: linux-2629-pidff/drivers/hid/usbhid/hid-core.c =================================================================== --- linux-2629-pidff.orig/drivers/hid/usbhid/hid-core.c 2009-02-13 03:47:15.000000000 +0200 +++ linux-2629-pidff/drivers/hid/usbhid/hid-core.c 2009-06-06 15:08:09.000000000 +0300 @@ -27,6 +27,7 @@ #include <asm/byteorder.h> #include <linux/input.h> #include <linux/wait.h> +#include <linux/timer.h> #include <linux/usb.h> @@ -251,6 +252,9 @@ static int hid_submit_out(struct hid_dev return -1; } + usbhid->urb_out_timeout.expires = jiffies + msecs_to_jiffies(8000); + add_timer(&usbhid->urb_out_timeout); + return 0; } @@ -303,6 +307,9 @@ static int hid_submit_ctrl(struct hid_de return -1; } + usbhid->urb_ctrl_timeout.expires = jiffies + msecs_to_jiffies(8000); + add_timer(&usbhid->urb_ctrl_timeout); + return 0; } @@ -317,6 +324,8 @@ static void hid_irq_out(struct urb *urb) unsigned long flags; int unplug = 0; + del_timer(&usbhid->urb_out_timeout); + switch (urb->status) { case 0: /* success */ break; @@ -364,6 +373,7 @@ static void hid_ctrl(struct urb *urb) unsigned long flags; int unplug = 0; + del_timer(&usbhid->urb_ctrl_timeout); spin_lock_irqsave(&usbhid->ctrllock, flags); switch (urb->status) { @@ -405,6 +415,13 @@ static void hid_ctrl(struct urb *urb) wake_up(&usbhid->wait); } +static void hid_urb_timeout(unsigned long timer_data) +{ + struct urb *hid_urb = (struct urb *)timer_data; + dev_warn(&hid_urb->dev->dev, "hid urb timeout\n"); + usb_unlink_urb(hid_urb); +} + void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) { int head; @@ -851,6 +868,8 @@ static int usbhid_start(struct hid_devic init_waitqueue_head(&usbhid->wait); INIT_WORK(&usbhid->reset_work, hid_reset); setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); + setup_timer(&usbhid->urb_out_timeout, hid_urb_timeout, (unsigned long) usbhid->urbout); + setup_timer(&usbhid->urb_ctrl_timeout, hid_urb_timeout, (unsigned long) usbhid->urbctrl); spin_lock_init(&usbhid->inlock); spin_lock_init(&usbhid->outlock); @@ -915,6 +934,8 @@ static void usbhid_stop(struct hid_devic del_timer_sync(&usbhid->io_retry); cancel_work_sync(&usbhid->reset_work); + del_timer_sync(&usbhid->urb_out_timeout); + del_timer_sync(&usbhid->urb_ctrl_timeout); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_disconnect(hid); Index: linux-2629-pidff/drivers/hid/usbhid/usbhid.h =================================================================== --- linux-2629-pidff.orig/drivers/hid/usbhid/usbhid.h 2009-05-08 01:53:33.000000000 +0300 +++ linux-2629-pidff/drivers/hid/usbhid/usbhid.h 2009-05-08 01:54:02.000000000 +0300 @@ -85,6 +85,8 @@ struct usbhid_device { spinlock_t outlock; /* Output fifo spinlock */ unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ + struct timer_list urb_out_timeout; /* Timeout for out urb */ + struct timer_list urb_ctrl_timeout; /* Timeout for ctrl urb */ struct timer_list io_retry; /* Retry timer */ unsigned long stop_retry; /* Time to give up, in jiffies */ unsigned int retry_delay; /* Delay length in ms */