diff options
author | Alan Cox <alan@redhat.com> | 2009-01-02 08:45:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:38 -0500 |
commit | 3e61696bdc2103107674b06d0daf30b76193e922 (patch) | |
tree | cc4f2b7b7b0ce2162613bb9d3cf819f6bbfd3628 | |
parent | 5d951fb458f847e5485b5251597fbf326000bb3b (diff) |
isicom: redo locking to use tty port locks
This helps set the basis for moving block_til_ready into common code. We also
introduce a tty_port_hangup helper as this will also be generally needed.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/char/isicom.c | 35 | ||||
-rw-r--r-- | drivers/char/synclinkmp.c | 20 | ||||
-rw-r--r-- | drivers/char/tty_port.c | 24 | ||||
-rw-r--r-- | include/linux/tty.h | 1 |
4 files changed, 54 insertions, 26 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index a449449e301c..db53db91ae4a 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -841,7 +841,6 @@ static int isicom_carrier_raised(struct tty_port *port) | |||
841 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | 841 | static int block_til_ready(struct tty_struct *tty, struct file *filp, |
842 | struct isi_port *ip) | 842 | struct isi_port *ip) |
843 | { | 843 | { |
844 | struct isi_board *card = ip->card; | ||
845 | struct tty_port *port = &ip->port; | 844 | struct tty_port *port = &ip->port; |
846 | int do_clocal = 0, retval; | 845 | int do_clocal = 0, retval; |
847 | unsigned long flags; | 846 | unsigned long flags; |
@@ -876,11 +875,11 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
876 | retval = 0; | 875 | retval = 0; |
877 | add_wait_queue(&port->open_wait, &wait); | 876 | add_wait_queue(&port->open_wait, &wait); |
878 | 877 | ||
879 | spin_lock_irqsave(&card->card_lock, flags); | 878 | spin_lock_irqsave(&port->lock, flags); |
880 | if (!tty_hung_up_p(filp)) | 879 | if (!tty_hung_up_p(filp)) |
881 | port->count--; | 880 | port->count--; |
882 | port->blocked_open++; | 881 | port->blocked_open++; |
883 | spin_unlock_irqrestore(&card->card_lock, flags); | 882 | spin_unlock_irqrestore(&port->lock, flags); |
884 | 883 | ||
885 | while (1) { | 884 | while (1) { |
886 | tty_port_raise_dtr_rts(port); | 885 | tty_port_raise_dtr_rts(port); |
@@ -905,14 +904,13 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
905 | } | 904 | } |
906 | set_current_state(TASK_RUNNING); | 905 | set_current_state(TASK_RUNNING); |
907 | remove_wait_queue(&port->open_wait, &wait); | 906 | remove_wait_queue(&port->open_wait, &wait); |
908 | spin_lock_irqsave(&card->card_lock, flags); | 907 | spin_lock_irqsave(&port->lock, flags); |
909 | if (!tty_hung_up_p(filp)) | 908 | if (!tty_hung_up_p(filp)) |
910 | port->count++; | 909 | port->count++; |
911 | port->blocked_open--; | 910 | port->blocked_open--; |
912 | spin_unlock_irqrestore(&card->card_lock, flags); | 911 | if (retval == 0) |
913 | if (retval) | 912 | port->flags |= ASYNC_NORMAL_ACTIVE; |
914 | return retval; | 913 | spin_unlock_irqrestore(&port->lock, flags); |
915 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
916 | return 0; | 914 | return 0; |
917 | } | 915 | } |
918 | 916 | ||
@@ -1034,9 +1032,9 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
1034 | 1032 | ||
1035 | pr_dbg("Close start!!!.\n"); | 1033 | pr_dbg("Close start!!!.\n"); |
1036 | 1034 | ||
1037 | spin_lock_irqsave(&card->card_lock, flags); | 1035 | spin_lock_irqsave(&port->port.lock, flags); |
1038 | if (tty_hung_up_p(filp)) { | 1036 | if (tty_hung_up_p(filp)) { |
1039 | spin_unlock_irqrestore(&card->card_lock, flags); | 1037 | spin_unlock_irqrestore(&port->port.lock, flags); |
1040 | return; | 1038 | return; |
1041 | } | 1039 | } |
1042 | 1040 | ||
@@ -1054,12 +1052,12 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
1054 | } | 1052 | } |
1055 | 1053 | ||
1056 | if (port->port.count) { | 1054 | if (port->port.count) { |
1057 | spin_unlock_irqrestore(&card->card_lock, flags); | 1055 | spin_unlock_irqrestore(&port->port.lock, flags); |
1058 | return; | 1056 | return; |
1059 | } | 1057 | } |
1060 | port->port.flags |= ASYNC_CLOSING; | 1058 | port->port.flags |= ASYNC_CLOSING; |
1061 | tty->closing = 1; | 1059 | tty->closing = 1; |
1062 | spin_unlock_irqrestore(&card->card_lock, flags); | 1060 | spin_unlock_irqrestore(&port->port.lock, flags); |
1063 | 1061 | ||
1064 | if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1062 | if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1065 | tty_wait_until_sent(tty, port->port.closing_wait); | 1063 | tty_wait_until_sent(tty, port->port.closing_wait); |
@@ -1076,22 +1074,22 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
1076 | isicom_flush_buffer(tty); | 1074 | isicom_flush_buffer(tty); |
1077 | tty_ldisc_flush(tty); | 1075 | tty_ldisc_flush(tty); |
1078 | 1076 | ||
1079 | spin_lock_irqsave(&card->card_lock, flags); | 1077 | spin_lock_irqsave(&port->port.lock, flags); |
1080 | tty->closing = 0; | 1078 | tty->closing = 0; |
1081 | 1079 | ||
1082 | if (port->port.blocked_open) { | 1080 | if (port->port.blocked_open) { |
1083 | spin_unlock_irqrestore(&card->card_lock, flags); | 1081 | spin_unlock_irqrestore(&port->port.lock, flags); |
1084 | if (port->port.close_delay) { | 1082 | if (port->port.close_delay) { |
1085 | pr_dbg("scheduling until time out.\n"); | 1083 | pr_dbg("scheduling until time out.\n"); |
1086 | msleep_interruptible( | 1084 | msleep_interruptible( |
1087 | jiffies_to_msecs(port->port.close_delay)); | 1085 | jiffies_to_msecs(port->port.close_delay)); |
1088 | } | 1086 | } |
1089 | spin_lock_irqsave(&card->card_lock, flags); | 1087 | spin_lock_irqsave(&port->port.lock, flags); |
1090 | wake_up_interruptible(&port->port.open_wait); | 1088 | wake_up_interruptible(&port->port.open_wait); |
1091 | } | 1089 | } |
1092 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 1090 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); |
1093 | wake_up_interruptible(&port->port.close_wait); | 1091 | wake_up_interruptible(&port->port.close_wait); |
1094 | spin_unlock_irqrestore(&card->card_lock, flags); | 1092 | spin_unlock_irqrestore(&port->port.lock, flags); |
1095 | } | 1093 | } |
1096 | 1094 | ||
1097 | /* write et all */ | 1095 | /* write et all */ |
@@ -1430,10 +1428,7 @@ static void isicom_hangup(struct tty_struct *tty) | |||
1430 | isicom_shutdown_port(port); | 1428 | isicom_shutdown_port(port); |
1431 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1429 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1432 | 1430 | ||
1433 | port->port.count = 0; | 1431 | tty_port_hangup(&port->port); |
1434 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; | ||
1435 | tty_port_tty_set(&port->port, NULL); | ||
1436 | wake_up_interruptible(&port->port.open_wait); | ||
1437 | } | 1432 | } |
1438 | 1433 | ||
1439 | 1434 | ||
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index fcf1ec77450d..1f5c21ec4b14 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -3331,6 +3331,17 @@ static int carrier_raised(struct tty_port *port) | |||
3331 | return (info->serial_signals & SerialSignal_DCD) ? 1 : 0; | 3331 | return (info->serial_signals & SerialSignal_DCD) ? 1 : 0; |
3332 | } | 3332 | } |
3333 | 3333 | ||
3334 | static void raise_dtr_rts(struct tty_port *port) | ||
3335 | { | ||
3336 | SLMP_INFO *info = container_of(port, SLMP_INFO, port); | ||
3337 | unsigned long flags; | ||
3338 | |||
3339 | spin_lock_irqsave(&info->lock,flags); | ||
3340 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | ||
3341 | set_signals(info); | ||
3342 | spin_unlock_irqrestore(&info->lock,flags); | ||
3343 | } | ||
3344 | |||
3334 | /* Block the current process until the specified port is ready to open. | 3345 | /* Block the current process until the specified port is ready to open. |
3335 | */ | 3346 | */ |
3336 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | 3347 | static int block_til_ready(struct tty_struct *tty, struct file *filp, |
@@ -3381,12 +3392,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3381 | port->blocked_open++; | 3392 | port->blocked_open++; |
3382 | 3393 | ||
3383 | while (1) { | 3394 | while (1) { |
3384 | if ((tty->termios->c_cflag & CBAUD)) { | 3395 | if (tty->termios->c_cflag & CBAUD) |
3385 | spin_lock_irqsave(&info->lock,flags); | 3396 | tty_port_raise_dtr_rts(port); |
3386 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | ||
3387 | set_signals(info); | ||
3388 | spin_unlock_irqrestore(&info->lock,flags); | ||
3389 | } | ||
3390 | 3397 | ||
3391 | set_current_state(TASK_INTERRUPTIBLE); | 3398 | set_current_state(TASK_INTERRUPTIBLE); |
3392 | 3399 | ||
@@ -3793,6 +3800,7 @@ static void add_device(SLMP_INFO *info) | |||
3793 | 3800 | ||
3794 | static const struct tty_port_operations port_ops = { | 3801 | static const struct tty_port_operations port_ops = { |
3795 | .carrier_raised = carrier_raised, | 3802 | .carrier_raised = carrier_raised, |
3803 | .raise_dtr_rts = raise_dtr_rts, | ||
3796 | }; | 3804 | }; |
3797 | 3805 | ||
3798 | /* Allocate and initialize a device instance structure | 3806 | /* Allocate and initialize a device instance structure |
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index 0557b6384747..9f418bca4a22 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/tty.h> | 7 | #include <linux/tty.h> |
8 | #include <linux/tty_driver.h> | 8 | #include <linux/tty_driver.h> |
9 | #include <linux/tty_flip.h> | 9 | #include <linux/tty_flip.h> |
10 | #include <linux/serial.h> | ||
10 | #include <linux/timer.h> | 11 | #include <linux/timer.h> |
11 | #include <linux/string.h> | 12 | #include <linux/string.h> |
12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
@@ -96,6 +97,29 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty) | |||
96 | EXPORT_SYMBOL(tty_port_tty_set); | 97 | EXPORT_SYMBOL(tty_port_tty_set); |
97 | 98 | ||
98 | /** | 99 | /** |
100 | * tty_port_hangup - hangup helper | ||
101 | * @port: tty port | ||
102 | * | ||
103 | * Perform port level tty hangup flag and count changes. Drop the tty | ||
104 | * reference. | ||
105 | */ | ||
106 | |||
107 | void tty_port_hangup(struct tty_port *port) | ||
108 | { | ||
109 | unsigned long flags; | ||
110 | |||
111 | spin_lock_irqsave(&port->lock, flags); | ||
112 | port->count = 0; | ||
113 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
114 | if (port->tty) | ||
115 | tty_kref_put(port->tty); | ||
116 | port->tty = NULL; | ||
117 | spin_unlock_irqrestore(&port->lock, flags); | ||
118 | wake_up_interruptible(&port->open_wait); | ||
119 | } | ||
120 | EXPORT_SYMBOL(tty_port_hangup); | ||
121 | |||
122 | /** | ||
99 | * tty_port_carrier_raised - carrier raised check | 123 | * tty_port_carrier_raised - carrier raised check |
100 | * @port: tty port | 124 | * @port: tty port |
101 | * | 125 | * |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 5001bbcacff6..a1a93140e6e4 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -438,6 +438,7 @@ extern struct tty_struct *tty_port_tty_get(struct tty_port *port); | |||
438 | extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); | 438 | extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); |
439 | extern int tty_port_carrier_raised(struct tty_port *port); | 439 | extern int tty_port_carrier_raised(struct tty_port *port); |
440 | extern void tty_port_raise_dtr_rts(struct tty_port *port); | 440 | extern void tty_port_raise_dtr_rts(struct tty_port *port); |
441 | extern void tty_port_hangup(struct tty_port *port); | ||
441 | 442 | ||
442 | extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); | 443 | extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); |
443 | extern int tty_unregister_ldisc(int disc); | 444 | extern int tty_unregister_ldisc(int disc); |