aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-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 @@
51#include "gadget_chips.h" 51#include "gadget_chips.h"
52 52
53 53
54/* Wait Cond */
55
56#define __wait_cond_interruptible(wq, condition, lock, flags, ret) \
57do { \
58 wait_queue_t __wait; \
59 init_waitqueue_entry(&__wait, current); \
60 \
61 add_wait_queue(&wq, &__wait); \
62 for (;;) { \
63 set_current_state(TASK_INTERRUPTIBLE); \
64 if (condition) \
65 break; \
66 if (!signal_pending(current)) { \
67 spin_unlock_irqrestore(lock, flags); \
68 schedule(); \
69 spin_lock_irqsave(lock, flags); \
70 continue; \
71 } \
72 ret = -ERESTARTSYS; \
73 break; \
74 } \
75 current->state = TASK_RUNNING; \
76 remove_wait_queue(&wq, &__wait); \
77} while (0)
78
79#define wait_cond_interruptible(wq, condition, lock, flags) \
80({ \
81 int __ret = 0; \
82 if (!(condition)) \
83 __wait_cond_interruptible(wq, condition, lock, flags, \
84 __ret); \
85 __ret; \
86})
87
88#define __wait_cond_interruptible_timeout(wq, condition, lock, flags, \
89 timeout, ret) \
90do { \
91 signed long __timeout = timeout; \
92 wait_queue_t __wait; \
93 init_waitqueue_entry(&__wait, current); \
94 \
95 add_wait_queue(&wq, &__wait); \
96 for (;;) { \
97 set_current_state(TASK_INTERRUPTIBLE); \
98 if (__timeout == 0) \
99 break; \
100 if (condition) \
101 break; \
102 if (!signal_pending(current)) { \
103 spin_unlock_irqrestore(lock, flags); \
104 __timeout = schedule_timeout(__timeout); \
105 spin_lock_irqsave(lock, flags); \
106 continue; \
107 } \
108 ret = -ERESTARTSYS; \
109 break; \
110 } \
111 current->state = TASK_RUNNING; \
112 remove_wait_queue(&wq, &__wait); \
113} while (0)
114
115#define wait_cond_interruptible_timeout(wq, condition, lock, flags, \
116 timeout) \
117({ \
118 int __ret = 0; \
119 if (!(condition)) \
120 __wait_cond_interruptible_timeout(wq, condition, lock, \
121 flags, timeout, __ret); \
122 __ret; \
123})
124
125
126/* Defines */ 54/* Defines */
127 55
128#define GS_VERSION_STR "v2.0" 56#define GS_VERSION_STR "v2.1"
129#define GS_VERSION_NUM 0x0200 57#define GS_VERSION_NUM 0x0201
130 58
131#define GS_LONG_NAME "Gadget Serial" 59#define GS_LONG_NAME "Gadget Serial"
132#define GS_SHORT_NAME "g_serial" 60#define GS_SHORT_NAME "g_serial"
@@ -843,6 +771,18 @@ exit_unlock_dev:
843/* 771/*
844 * gs_close 772 * gs_close
845 */ 773 */
774
775#define GS_WRITE_FINISHED_EVENT_SAFELY(p) \
776({ \
777 unsigned long flags; \
778 int cond; \
779 \
780 spin_lock_irqsave(&(p)->port_lock, flags); \
781 cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \
782 spin_unlock_irqrestore(&(p)->port_lock, flags); \
783 cond; \
784})
785
846static void gs_close(struct tty_struct *tty, struct file *file) 786static void gs_close(struct tty_struct *tty, struct file *file)
847{ 787{
848 unsigned long flags; 788 unsigned long flags;
@@ -888,10 +828,9 @@ static void gs_close(struct tty_struct *tty, struct file *file)
888 /* at most GS_CLOSE_TIMEOUT seconds */ 828 /* at most GS_CLOSE_TIMEOUT seconds */
889 if (gs_buf_data_avail(port->port_write_buf) > 0) { 829 if (gs_buf_data_avail(port->port_write_buf) > 0) {
890 spin_unlock_irqrestore(&port->port_lock, flags); 830 spin_unlock_irqrestore(&port->port_lock, flags);
891 wait_cond_interruptible_timeout(port->port_write_wait, 831 wait_event_interruptible_timeout(port->port_write_wait,
892 port->port_dev == NULL 832 GS_WRITE_FINISHED_EVENT_SAFELY(port),
893 || gs_buf_data_avail(port->port_write_buf) == 0, 833 GS_CLOSE_TIMEOUT * HZ);
894 &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ);
895 spin_lock_irqsave(&port->port_lock, flags); 834 spin_lock_irqsave(&port->port_lock, flags);
896 } 835 }
897 836