usbmouse: synchonize the irq completion
Signed-off-by: Jordi Pujol <jordipujolp AT gmail DOT com>
@@ -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);
@@ -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)