diff mbox

usbmouse: random freeze/hangup; synchronize irq completion

Message ID 201102140951.00866.jordipujolp@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jordi Pujol Feb. 14, 2011, 8:51 a.m. UTC
None
diff mbox

Patch

 usbmouse: synchonize the irq completion

Signed-off-by: Jordi Pujol <jordipujolp AT gmail DOT com>

--- linux-2.6.37-old/include/linux/usb.h	2011-01-05 01:50:19.000000000 +0100
+++ linux-2.6.37/include/linux/usb.h	2011-02-10 09:31:30.098752709 +0100
@@ -1214,6 +1214,7 @@  struct urb {
 	int error_count;		/* (return) number of ISO errors */
 	void *context;			/* (in) context for completion */
 	usb_complete_t complete;	/* (in) completion routine */
+	struct mutex		complete_mutex;		/* synchronize completion */
 	struct usb_iso_packet_descriptor iso_frame_desc[0];
 					/* (in) ISO ONLY */
 };
@@ -1250,6 +1251,7 @@  static inline void usb_fill_control_urb(
 	urb->transfer_buffer_length = buffer_length;
 	urb->complete = complete_fn;
 	urb->context = context;
+	mutex_init(&urb->complete_mutex);
 }

 /**
@@ -1279,6 +1281,7 @@  static inline void usb_fill_bulk_urb(str
 	urb->transfer_buffer_length = buffer_length;
 	urb->complete = complete_fn;
 	urb->context = context;
+	mutex_init(&urb->complete_mutex);
 }

 /**
@@ -1326,6 +1329,7 @@  static inline void usb_fill_int_urb(stru
 	else
 		urb->interval = interval;
 	urb->start_frame = -1;
+	mutex_init(&urb->complete_mutex);
 }

 extern void usb_init_urb(struct urb *urb);
--- linux-2.6.37-old/drivers/hid/usbhid/usbmouse.c
+++ linux-2.6.37/drivers/hid/usbhid/usbmouse.c	2011-02-06 16:15:10.432559673 +0100
@@ -66,13 +71,15 @@  static void usb_mouse_irq(struct urb *ur
 	struct input_dev *dev = mouse->dev;
 	int status;

+	mutex_lock(&urb->complete_mutex);
+
 	switch (urb->status) {
 	case 0:			/* success */
 		break;
 	case -ECONNRESET:	/* unlink */
 	case -ENOENT:
 	case -ESHUTDOWN:
-		return;
+		goto out;
 	/* -EPIPE:  should clear the halt */
 	default:		/* error */
 		goto resubmit;
@@ -95,6 +102,9 @@  resubmit:
 		err ("can't resubmit intr, %s-%s/input0, status %d",
 				mouse->usbdev->bus->bus_name,
 				mouse->usbdev->devpath, status);
+
+out:
+	mutex_unlock(&urb->complete_mutex);
 }

 static int usb_mouse_open(struct input_dev *dev)