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

Bug#314954: [Linux-usb-users] Re: logitech usb mouse "dies"



I now recreated the patch in a more usable way.

BTW:

Dec 17 20:50:30 wmiwilli kernel: mtrr: 0xe8000000,0x8000000 overlaps existing 0xe8000000,0x1000000 Dec 17 21:01:25 wmiwilli kernel: drivers/usb/input/hid-core.c: input irq status -84 received Dec 17 21:25:43 wmiwilli kernel: drivers/usb/input/hid-core.c: input irq status -84 received Dec 17 21:29:56 wmiwilli kernel: drivers/usb/input/hid-core.c: input irq status -84 received Dec 17 21:56:45 wmiwilli kernel: drivers/usb/input/hid-core.c: input irq status -84 received Dec 17 21:58:49 wmiwilli kernel: drivers/usb/input/hid-core.c: input irq status -84 received Dec 17 22:07:52 wmiwilli kernel: drivers/usb/input/hid-core.c: input irq status -84 received Dec 17 22:08:26 wmiwilli kernel: drivers/usb/input/hid-core.c: input irq status -84 received Dec 17 22:10:29 wmiwilli kernel: drivers/usb/input/hid-core.c: input irq status -84 received

There seems to be relation between mouse usage and the -84 signal: The more I use the mouse the less it occurs.

Willi

diff -ru rr/linux-source-2.6.14/drivers/usb/input/hid-core.c linux-source-2.6.14/drivers/usb/input/hid-core.c
--- rr/linux-source-2.6.14/drivers/usb/input/hid-core.c	2005-10-28 02:02:08.000000000 +0200
+++ linux-source-2.6.14/drivers/usb/input/hid-core.c	2005-12-17 20:31:41.000000000 +0100
@@ -909,6 +909,29 @@
 }
 
 /*
+ * Request a device reset.
+ */
+static void hid_reset(void *_hid)
+{
+	struct hid_device	*hid = _hid;
+	int			rc, result;
+
+	hid->in_error_cnt = 0;
+	rc = result = usb_lock_device_for_reset(hid->dev, hid->intf);
+	if (rc >= 0) {
+		result = usb_reset_device(hid->dev);
+		if (result == 0 && hid->open)
+			result = usb_submit_urb(hid->urbin, GFP_NOIO);
+		if (rc)
+			usb_unlock_device(hid->dev);
+	}
+	if (result < 0)
+		warn("can't reset device, %s-%s/input%d, result %d",
+				hid->dev->bus->bus_name, hid->dev->devpath,
+				hid->ifnum, result);
+}
+
+/*
  * Input interrupt completion handler.
  */
 
@@ -919,18 +942,20 @@
 
 	switch (urb->status) {
 		case 0:			/* success */
+			hid->in_error_cnt = 0;
 			hid_input_report(HID_INPUT_REPORT, urb, 1, regs);
 			break;
 		case -ECONNRESET:	/* unlink */
 		case -ENOENT:
 		case -EPERM:
 		case -ESHUTDOWN:	/* unplug */
-		case -EILSEQ:		/* unplug timeout on uhci */
 			return;
-		case -ETIMEDOUT:	/* NAK */
-			break;
 		default:		/* error */
 			warn("input irq status %d received", urb->status);
+			if (++hid->in_error_cnt >= 10) {
+				schedule_work(&hid->work);
+				return;
+			}	
 	}
 
 	status = usb_submit_urb(urb, SLAB_ATOMIC);
@@ -1099,7 +1124,6 @@
 		case 0:			/* success */
 			break;
 		case -ESHUTDOWN:	/* unplug */
-		case -EILSEQ:		/* unplug timeout on uhci */
 			unplug = 1;
 		case -ECONNRESET:	/* unlink */
 		case -ENOENT:
@@ -1147,7 +1171,6 @@
 				hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs);
 			break;
 		case -ESHUTDOWN:	/* unplug */
-		case -EILSEQ:		/* unplug timectrl on uhci */
 			unplug = 1;
 		case -ECONNRESET:	/* unlink */
 		case -ENOENT:
@@ -1781,6 +1804,7 @@
 	hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
 	hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
+	INIT_WORK(&hid->work, hid_reset, hid);
 	return hid;
 
 fail:
@@ -1808,6 +1832,7 @@
 	usb_kill_urb(hid->urbin);
 	usb_kill_urb(hid->urbout);
 	usb_kill_urb(hid->urbctrl);
+	flush_scheduled_work();
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_disconnect(hid);
diff -ru rr/linux-source-2.6.14/drivers/usb/input/hid.h linux-source-2.6.14/drivers/usb/input/hid.h
--- rr/linux-source-2.6.14/drivers/usb/input/hid.h	2005-10-28 02:02:08.000000000 +0200
+++ linux-source-2.6.14/drivers/usb/input/hid.h	2005-12-17 21:12:07.000000000 +0100
@@ -396,6 +396,8 @@
 	struct urb *urbin;						/* Input URB */
 	char *inbuf;							/* Input buffer */
 	dma_addr_t inbuf_dma;						/* Input buffer dma */
+	int in_error_cnt;						/* Input error counter */
+	struct work_struct work;					/* Perform asynchronous reset */
 
 	struct urb *urbctrl;						/* Control URB */
 	struct usb_ctrlrequest *cr;					/* Control request struct */


Reply to: