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: