Re: hid-pidff bug: fails to find all required reports of saitek gamepad

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

 



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 */

[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