diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 19:12:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 19:12:24 -0400 |
commit | 94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9 (patch) | |
tree | 39197121b6ef8cddaa0f4057fe24b4ced58e8982 /drivers/usb | |
parent | 5d4e2d08e7fdf7339f84a1c670d296a77e02f881 (diff) | |
parent | 59bd234b72fc29887839d792b7d6c7e8d2a577a6 (diff) |
Merge tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY updates from Greg Kroah-Hartman:
"Here's the big TTY/serial driver pull request for the 3.5-rc1 merge
window.
Nothing major in here, just lots of incremental changes from Alan and
Jiri reworking some tty core things to behave better and to get a more
solid grasp on some of the nasty tty locking issues.
There are a few tty and serial driver updates in here as well.
All of this has been in the linux-next releases for a while with no
problems.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
* tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (115 commits)
serial: bfin_uart: Make MMR access compatible with 32 bits bf609 style controller.
serial: bfin_uart: RTS and CTS MMRs can be either 16-bit width or 32-bit width.
serial: bfin_uart: narrow the reboot condition in DMA tx interrupt
serial: bfin_uart: Adapt bf5xx serial driver to bf60x serial4 controller.
Revert "serial_core: Update buffer overrun statistics."
tty: hvc_xen: NULL dereference on allocation failure
tty: Fix LED error return
tty: Allow uart_register/unregister/register
tty: move global ldisc idle waitqueue to the individual ldisc
serial8250-em: Add DT support
serial8250-em: clk_get() IS_ERR() error handling fix
serial_core: Update buffer overrun statistics.
tty: drop the pty lock during hangup
cris: fix missing tty arg in wait_event_interruptible_tty call
tty/amiserial: Add missing argument for tty_unlock()
tty_lock: Localise the lock
pty: Lock the devpts bits privately
tty_lock: undo the old tty_lock use on the ctty
serial8250-em: Emma Mobile UART driver V2
Add missing call to uart_update_timeout()
...
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/u_serial.c | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 380a87f6e56c..15a42c8c1943 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -94,17 +94,14 @@ struct gs_buf { | |||
94 | * (and thus for each /dev/ node). | 94 | * (and thus for each /dev/ node). |
95 | */ | 95 | */ |
96 | struct gs_port { | 96 | struct gs_port { |
97 | struct tty_port port; | ||
97 | spinlock_t port_lock; /* guard port_* access */ | 98 | spinlock_t port_lock; /* guard port_* access */ |
98 | 99 | ||
99 | struct gserial *port_usb; | 100 | struct gserial *port_usb; |
100 | struct tty_struct *port_tty; | ||
101 | 101 | ||
102 | unsigned open_count; | ||
103 | bool openclose; /* open/close in progress */ | 102 | bool openclose; /* open/close in progress */ |
104 | u8 port_num; | 103 | u8 port_num; |
105 | 104 | ||
106 | wait_queue_head_t close_wait; /* wait for last close */ | ||
107 | |||
108 | struct list_head read_pool; | 105 | struct list_head read_pool; |
109 | int read_started; | 106 | int read_started; |
110 | int read_allocated; | 107 | int read_allocated; |
@@ -412,8 +409,8 @@ __acquires(&port->port_lock) | |||
412 | break; | 409 | break; |
413 | } | 410 | } |
414 | 411 | ||
415 | if (do_tty_wake && port->port_tty) | 412 | if (do_tty_wake && port->port.tty) |
416 | tty_wakeup(port->port_tty); | 413 | tty_wakeup(port->port.tty); |
417 | return status; | 414 | return status; |
418 | } | 415 | } |
419 | 416 | ||
@@ -435,7 +432,7 @@ __acquires(&port->port_lock) | |||
435 | struct tty_struct *tty; | 432 | struct tty_struct *tty; |
436 | 433 | ||
437 | /* no more rx if closed */ | 434 | /* no more rx if closed */ |
438 | tty = port->port_tty; | 435 | tty = port->port.tty; |
439 | if (!tty) | 436 | if (!tty) |
440 | break; | 437 | break; |
441 | 438 | ||
@@ -488,7 +485,7 @@ static void gs_rx_push(unsigned long _port) | |||
488 | 485 | ||
489 | /* hand any queued data to the tty */ | 486 | /* hand any queued data to the tty */ |
490 | spin_lock_irq(&port->port_lock); | 487 | spin_lock_irq(&port->port_lock); |
491 | tty = port->port_tty; | 488 | tty = port->port.tty; |
492 | while (!list_empty(queue)) { | 489 | while (!list_empty(queue)) { |
493 | struct usb_request *req; | 490 | struct usb_request *req; |
494 | 491 | ||
@@ -699,7 +696,7 @@ static int gs_start_io(struct gs_port *port) | |||
699 | 696 | ||
700 | /* unblock any pending writes into our circular buffer */ | 697 | /* unblock any pending writes into our circular buffer */ |
701 | if (started) { | 698 | if (started) { |
702 | tty_wakeup(port->port_tty); | 699 | tty_wakeup(port->port.tty); |
703 | } else { | 700 | } else { |
704 | gs_free_requests(ep, head, &port->read_allocated); | 701 | gs_free_requests(ep, head, &port->read_allocated); |
705 | gs_free_requests(port->port_usb->in, &port->write_pool, | 702 | gs_free_requests(port->port_usb->in, &port->write_pool, |
@@ -734,9 +731,9 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
734 | spin_lock_irq(&port->port_lock); | 731 | spin_lock_irq(&port->port_lock); |
735 | 732 | ||
736 | /* already open? Great. */ | 733 | /* already open? Great. */ |
737 | if (port->open_count) { | 734 | if (port->port.count) { |
738 | status = 0; | 735 | status = 0; |
739 | port->open_count++; | 736 | port->port.count++; |
740 | 737 | ||
741 | /* currently opening/closing? wait ... */ | 738 | /* currently opening/closing? wait ... */ |
742 | } else if (port->openclose) { | 739 | } else if (port->openclose) { |
@@ -793,9 +790,9 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
793 | /* REVISIT maybe wait for "carrier detect" */ | 790 | /* REVISIT maybe wait for "carrier detect" */ |
794 | 791 | ||
795 | tty->driver_data = port; | 792 | tty->driver_data = port; |
796 | port->port_tty = tty; | 793 | port->port.tty = tty; |
797 | 794 | ||
798 | port->open_count = 1; | 795 | port->port.count = 1; |
799 | port->openclose = false; | 796 | port->openclose = false; |
800 | 797 | ||
801 | /* if connected, start the I/O stream */ | 798 | /* if connected, start the I/O stream */ |
@@ -837,11 +834,11 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
837 | 834 | ||
838 | spin_lock_irq(&port->port_lock); | 835 | spin_lock_irq(&port->port_lock); |
839 | 836 | ||
840 | if (port->open_count != 1) { | 837 | if (port->port.count != 1) { |
841 | if (port->open_count == 0) | 838 | if (port->port.count == 0) |
842 | WARN_ON(1); | 839 | WARN_ON(1); |
843 | else | 840 | else |
844 | --port->open_count; | 841 | --port->port.count; |
845 | goto exit; | 842 | goto exit; |
846 | } | 843 | } |
847 | 844 | ||
@@ -851,7 +848,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
851 | * and sleep if necessary | 848 | * and sleep if necessary |
852 | */ | 849 | */ |
853 | port->openclose = true; | 850 | port->openclose = true; |
854 | port->open_count = 0; | 851 | port->port.count = 0; |
855 | 852 | ||
856 | gser = port->port_usb; | 853 | gser = port->port_usb; |
857 | if (gser && gser->disconnect) | 854 | if (gser && gser->disconnect) |
@@ -879,14 +876,14 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
879 | gs_buf_clear(&port->port_write_buf); | 876 | gs_buf_clear(&port->port_write_buf); |
880 | 877 | ||
881 | tty->driver_data = NULL; | 878 | tty->driver_data = NULL; |
882 | port->port_tty = NULL; | 879 | port->port.tty = NULL; |
883 | 880 | ||
884 | port->openclose = false; | 881 | port->openclose = false; |
885 | 882 | ||
886 | pr_debug("gs_close: ttyGS%d (%p,%p) done!\n", | 883 | pr_debug("gs_close: ttyGS%d (%p,%p) done!\n", |
887 | port->port_num, tty, file); | 884 | port->port_num, tty, file); |
888 | 885 | ||
889 | wake_up_interruptible(&port->close_wait); | 886 | wake_up_interruptible(&port->port.close_wait); |
890 | exit: | 887 | exit: |
891 | spin_unlock_irq(&port->port_lock); | 888 | spin_unlock_irq(&port->port_lock); |
892 | } | 889 | } |
@@ -1034,8 +1031,8 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) | |||
1034 | if (port == NULL) | 1031 | if (port == NULL) |
1035 | return -ENOMEM; | 1032 | return -ENOMEM; |
1036 | 1033 | ||
1034 | tty_port_init(&port->port); | ||
1037 | spin_lock_init(&port->port_lock); | 1035 | spin_lock_init(&port->port_lock); |
1038 | init_waitqueue_head(&port->close_wait); | ||
1039 | init_waitqueue_head(&port->drain_wait); | 1036 | init_waitqueue_head(&port->drain_wait); |
1040 | 1037 | ||
1041 | tasklet_init(&port->push, gs_rx_push, (unsigned long) port); | 1038 | tasklet_init(&port->push, gs_rx_push, (unsigned long) port); |
@@ -1155,7 +1152,7 @@ static int gs_closed(struct gs_port *port) | |||
1155 | int cond; | 1152 | int cond; |
1156 | 1153 | ||
1157 | spin_lock_irq(&port->port_lock); | 1154 | spin_lock_irq(&port->port_lock); |
1158 | cond = (port->open_count == 0) && !port->openclose; | 1155 | cond = (port->port.count == 0) && !port->openclose; |
1159 | spin_unlock_irq(&port->port_lock); | 1156 | spin_unlock_irq(&port->port_lock); |
1160 | return cond; | 1157 | return cond; |
1161 | } | 1158 | } |
@@ -1194,7 +1191,7 @@ void gserial_cleanup(void) | |||
1194 | tasklet_kill(&port->push); | 1191 | tasklet_kill(&port->push); |
1195 | 1192 | ||
1196 | /* wait for old opens to finish */ | 1193 | /* wait for old opens to finish */ |
1197 | wait_event(port->close_wait, gs_closed(port)); | 1194 | wait_event(port->port.close_wait, gs_closed(port)); |
1198 | 1195 | ||
1199 | WARN_ON(port->port_usb != NULL); | 1196 | WARN_ON(port->port_usb != NULL); |
1200 | 1197 | ||
@@ -1268,7 +1265,7 @@ int gserial_connect(struct gserial *gser, u8 port_num) | |||
1268 | /* if it's already open, start I/O ... and notify the serial | 1265 | /* if it's already open, start I/O ... and notify the serial |
1269 | * protocol about open/close status (connect/disconnect). | 1266 | * protocol about open/close status (connect/disconnect). |
1270 | */ | 1267 | */ |
1271 | if (port->open_count) { | 1268 | if (port->port.count) { |
1272 | pr_debug("gserial_connect: start ttyGS%d\n", port->port_num); | 1269 | pr_debug("gserial_connect: start ttyGS%d\n", port->port_num); |
1273 | gs_start_io(port); | 1270 | gs_start_io(port); |
1274 | if (gser->connect) | 1271 | if (gser->connect) |
@@ -1315,10 +1312,10 @@ void gserial_disconnect(struct gserial *gser) | |||
1315 | 1312 | ||
1316 | port->port_usb = NULL; | 1313 | port->port_usb = NULL; |
1317 | gser->ioport = NULL; | 1314 | gser->ioport = NULL; |
1318 | if (port->open_count > 0 || port->openclose) { | 1315 | if (port->port.count > 0 || port->openclose) { |
1319 | wake_up_interruptible(&port->drain_wait); | 1316 | wake_up_interruptible(&port->drain_wait); |
1320 | if (port->port_tty) | 1317 | if (port->port.tty) |
1321 | tty_hangup(port->port_tty); | 1318 | tty_hangup(port->port.tty); |
1322 | } | 1319 | } |
1323 | spin_unlock_irqrestore(&port->port_lock, flags); | 1320 | spin_unlock_irqrestore(&port->port_lock, flags); |
1324 | 1321 | ||
@@ -1331,7 +1328,7 @@ void gserial_disconnect(struct gserial *gser) | |||
1331 | 1328 | ||
1332 | /* finally, free any unused/unusable I/O buffers */ | 1329 | /* finally, free any unused/unusable I/O buffers */ |
1333 | spin_lock_irqsave(&port->port_lock, flags); | 1330 | spin_lock_irqsave(&port->port_lock, flags); |
1334 | if (port->open_count == 0 && !port->openclose) | 1331 | if (port->port.count == 0 && !port->openclose) |
1335 | gs_buf_free(&port->port_write_buf); | 1332 | gs_buf_free(&port->port_write_buf); |
1336 | gs_free_requests(gser->out, &port->read_pool, NULL); | 1333 | gs_free_requests(gser->out, &port->read_pool, NULL); |
1337 | gs_free_requests(gser->out, &port->read_queue, NULL); | 1334 | gs_free_requests(gser->out, &port->read_queue, NULL); |