|
@@ -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);
|
|
|
}
|
|
|
|