summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/serial.c95
1 files changed, 17 insertions, 78 deletions
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b992546c394d..b58f015554b7 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -51,82 +51,10 @@
#include "gadget_chips.h"
-/* Wait Cond */
-
-#define __wait_cond_interruptible(wq, condition, lock, flags, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- spin_unlock_irqrestore(lock, flags); \
- schedule(); \
- spin_lock_irqsave(lock, flags); \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- current->state = TASK_RUNNING; \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_cond_interruptible(wq, condition, lock, flags) \
-({ \
- int __ret = 0; \
- if (!(condition)) \
- __wait_cond_interruptible(wq, condition, lock, flags, \
- __ret); \
- __ret; \
-})
-
-#define __wait_cond_interruptible_timeout(wq, condition, lock, flags, \
- timeout, ret) \
-do { \
- signed long __timeout = timeout; \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (__timeout == 0) \
- break; \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- spin_unlock_irqrestore(lock, flags); \
- __timeout = schedule_timeout(__timeout); \
- spin_lock_irqsave(lock, flags); \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- current->state = TASK_RUNNING; \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_cond_interruptible_timeout(wq, condition, lock, flags, \
- timeout) \
-({ \
- int __ret = 0; \
- if (!(condition)) \
- __wait_cond_interruptible_timeout(wq, condition, lock, \
- flags, timeout, __ret); \
- __ret; \
-})
-
-
/* Defines */
-#define GS_VERSION_STR "v2.0"
-#define GS_VERSION_NUM 0x0200
+#define GS_VERSION_STR "v2.1"
+#define GS_VERSION_NUM 0x0201
#define GS_LONG_NAME "Gadget Serial"
#define GS_SHORT_NAME "g_serial"
@@ -843,6 +771,18 @@ exit_unlock_dev:
/*
* gs_close
*/
+
+#define GS_WRITE_FINISHED_EVENT_SAFELY(p) \
+({ \
+ unsigned long flags; \
+ int cond; \
+ \
+ spin_lock_irqsave(&(p)->port_lock, flags); \
+ cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \
+ spin_unlock_irqrestore(&(p)->port_lock, flags); \
+ cond; \
+})
+
static void gs_close(struct tty_struct *tty, struct file *file)
{
unsigned long flags;
@@ -888,10 +828,9 @@ static void gs_close(struct tty_struct *tty, struct file *file)
/* at most GS_CLOSE_TIMEOUT seconds */
if (gs_buf_data_avail(port->port_write_buf) > 0) {
spin_unlock_irqrestore(&port->port_lock, flags);
- wait_cond_interruptible_timeout(port->port_write_wait,
- port->port_dev == NULL
- || gs_buf_data_avail(port->port_write_buf) == 0,
- &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ);
+ wait_event_interruptible_timeout(port->port_write_wait,
+ GS_WRITE_FINISHED_EVENT_SAFELY(port),
+ GS_CLOSE_TIMEOUT * HZ);
spin_lock_irqsave(&port->port_lock, flags);
}