diff options
Diffstat (limited to 'drivers/usb/gadget/serial.c')
| -rw-r--r-- | drivers/usb/gadget/serial.c | 105 |
1 files changed, 21 insertions, 84 deletions
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index b992546c394d..9d6e1d295528 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
| @@ -45,88 +45,16 @@ | |||
| 45 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
| 46 | 46 | ||
| 47 | #include <linux/usb_ch9.h> | 47 | #include <linux/usb_ch9.h> |
| 48 | #include <linux/usb_cdc.h> | 48 | #include <linux/usb/cdc.h> |
| 49 | #include <linux/usb_gadget.h> | 49 | #include <linux/usb_gadget.h> |
| 50 | 50 | ||
| 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) \ | ||
| 57 | do { \ | ||
| 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) \ | ||
| 90 | do { \ | ||
| 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.2" |
| 129 | #define GS_VERSION_NUM 0x0200 | 57 | #define GS_VERSION_NUM 0x0202 |
| 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,9 +771,19 @@ exit_unlock_dev: | |||
| 843 | /* | 771 | /* |
| 844 | * gs_close | 772 | * gs_close |
| 845 | */ | 773 | */ |
| 774 | |||
| 775 | #define GS_WRITE_FINISHED_EVENT_SAFELY(p) \ | ||
| 776 | ({ \ | ||
| 777 | int cond; \ | ||
| 778 | \ | ||
| 779 | spin_lock_irq(&(p)->port_lock); \ | ||
| 780 | cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \ | ||
| 781 | spin_unlock_irq(&(p)->port_lock); \ | ||
| 782 | cond; \ | ||
| 783 | }) | ||
| 784 | |||
| 846 | static void gs_close(struct tty_struct *tty, struct file *file) | 785 | static void gs_close(struct tty_struct *tty, struct file *file) |
| 847 | { | 786 | { |
| 848 | unsigned long flags; | ||
| 849 | struct gs_port *port = tty->driver_data; | 787 | struct gs_port *port = tty->driver_data; |
| 850 | struct semaphore *sem; | 788 | struct semaphore *sem; |
| 851 | 789 | ||
| @@ -859,7 +797,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
| 859 | sem = &gs_open_close_sem[port->port_num]; | 797 | sem = &gs_open_close_sem[port->port_num]; |
| 860 | down(sem); | 798 | down(sem); |
| 861 | 799 | ||
| 862 | spin_lock_irqsave(&port->port_lock, flags); | 800 | spin_lock_irq(&port->port_lock); |
| 863 | 801 | ||
| 864 | if (port->port_open_count == 0) { | 802 | if (port->port_open_count == 0) { |
| 865 | printk(KERN_ERR | 803 | printk(KERN_ERR |
| @@ -887,12 +825,11 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
| 887 | /* wait for write buffer to drain, or */ | 825 | /* wait for write buffer to drain, or */ |
| 888 | /* at most GS_CLOSE_TIMEOUT seconds */ | 826 | /* at most GS_CLOSE_TIMEOUT seconds */ |
| 889 | if (gs_buf_data_avail(port->port_write_buf) > 0) { | 827 | if (gs_buf_data_avail(port->port_write_buf) > 0) { |
| 890 | spin_unlock_irqrestore(&port->port_lock, flags); | 828 | spin_unlock_irq(&port->port_lock); |
| 891 | wait_cond_interruptible_timeout(port->port_write_wait, | 829 | wait_event_interruptible_timeout(port->port_write_wait, |
| 892 | port->port_dev == NULL | 830 | GS_WRITE_FINISHED_EVENT_SAFELY(port), |
| 893 | || gs_buf_data_avail(port->port_write_buf) == 0, | 831 | GS_CLOSE_TIMEOUT * HZ); |
| 894 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); | 832 | spin_lock_irq(&port->port_lock); |
| 895 | spin_lock_irqsave(&port->port_lock, flags); | ||
| 896 | } | 833 | } |
| 897 | 834 | ||
| 898 | /* free disconnected port on final close */ | 835 | /* free disconnected port on final close */ |
| @@ -912,7 +849,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
| 912 | port->port_num, tty, file); | 849 | port->port_num, tty, file); |
| 913 | 850 | ||
| 914 | exit: | 851 | exit: |
| 915 | spin_unlock_irqrestore(&port->port_lock, flags); | 852 | spin_unlock_irq(&port->port_lock); |
| 916 | up(sem); | 853 | up(sem); |
| 917 | } | 854 | } |
| 918 | 855 | ||
