diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 6715a128e6c8..519bb53993aa 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -62,6 +62,7 @@ struct usb_yurex { struct mutex io_mutex; struct fasync_struct *async_queue; wait_queue_head_t waitq; + struct completion cntl_cpl; spinlock_t lock; __s64 bbu; /* BBU from device */ @@ -80,7 +81,7 @@ static void yurex_control_callback(struct urb *urb) if (status) { dev_err(&urb->dev->dev, "%s - control failed: %d\n", __func__, status); - wake_up_interruptible(&dev->waitq); + complete(&dev->cntl_cpl); return; } /* on success, sender woken up by CMD_ACK int in, or timeout */ @@ -202,6 +203,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ mutex_init(&dev->io_mutex); spin_lock_init(&dev->lock); init_waitqueue_head(&dev->waitq); + init_completion(&dev->cntl_cpl); dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; @@ -322,6 +324,7 @@ static void yurex_disconnect(struct usb_interface *interface) /* wakeup waiters */ kill_fasync(&dev->async_queue, SIGIO, POLL_IN); wake_up_interruptible(&dev->waitq); + complete(&dev->cntl_cpl); /* decrement our usage count */ kref_put(&dev->kref, yurex_delete); @@ -485,13 +488,10 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, } /* send the data as the control msg */ - prepare_to_wait(&dev->waitq, &wait, TASK_INTERRUPTIBLE); dev_dbg(&dev->interface->dev, "%s - submit %c\n", __func__, dev->cntl_buffer[0]); retval = usb_submit_urb(dev->cntl_urb, GFP_KERNEL); - if (retval >= 0) - timeout = schedule_timeout(YUREX_WRITE_TIMEOUT); - finish_wait(&dev->waitq, &wait); + timeout = wait_for_completion_interruptible__timeout(&dev->cntl_cpl, YUREX_WRITE_TIMEOUT); mutex_unlock(&dev->io_mutex);