diff options
author | Alan Cox <alan@redhat.com> | 2009-01-02 08:45:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:39 -0500 |
commit | c2ba38cd76df770a253f0cab4b6abe514c265a85 (patch) | |
tree | d5400b7c3c2125cbd461cbfda6091ac352c4055f /drivers/char | |
parent | a129909ca910d086b8536c790338504878489a95 (diff) |
tty: relock riscom8 using port locks
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/riscom8.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 6ad1c2aa2a98..14662d7aa628 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -919,14 +919,12 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
919 | retval = 0; | 919 | retval = 0; |
920 | add_wait_queue(&port->open_wait, &wait); | 920 | add_wait_queue(&port->open_wait, &wait); |
921 | 921 | ||
922 | spin_lock_irqsave(&riscom_lock, flags); | 922 | spin_lock_irqsave(&port->lock, flags); |
923 | |||
924 | if (!tty_hung_up_p(filp)) | 923 | if (!tty_hung_up_p(filp)) |
925 | port->count--; | 924 | port->count--; |
926 | |||
927 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
928 | |||
929 | port->blocked_open++; | 925 | port->blocked_open++; |
926 | spin_unlock_irqrestore(&port->lock, flags); | ||
927 | |||
930 | while (1) { | 928 | while (1) { |
931 | 929 | ||
932 | CD = tty_port_carrier_raised(port); | 930 | CD = tty_port_carrier_raised(port); |
@@ -950,13 +948,13 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
950 | } | 948 | } |
951 | __set_current_state(TASK_RUNNING); | 949 | __set_current_state(TASK_RUNNING); |
952 | remove_wait_queue(&port->open_wait, &wait); | 950 | remove_wait_queue(&port->open_wait, &wait); |
951 | spin_lock_irqsave(&port->lock, flags); | ||
953 | if (!tty_hung_up_p(filp)) | 952 | if (!tty_hung_up_p(filp)) |
954 | port->count++; | 953 | port->count++; |
955 | port->blocked_open--; | 954 | port->blocked_open--; |
956 | if (retval) | 955 | if (retval == 0) |
957 | return retval; | 956 | port->flags |= ASYNC_NORMAL_ACTIVE; |
958 | 957 | spin_unlock_irqrestore(&port->lock, flags); | |
959 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
960 | return 0; | 958 | return 0; |
961 | } | 959 | } |
962 | 960 | ||
@@ -1015,7 +1013,7 @@ static void rc_close(struct tty_struct *tty, struct file *filp) | |||
1015 | if (!port || rc_paranoia_check(port, tty->name, "close")) | 1013 | if (!port || rc_paranoia_check(port, tty->name, "close")) |
1016 | return; | 1014 | return; |
1017 | 1015 | ||
1018 | spin_lock_irqsave(&riscom_lock, flags); | 1016 | spin_lock_irqsave(&port->port.lock, flags); |
1019 | 1017 | ||
1020 | if (tty_hung_up_p(filp)) | 1018 | if (tty_hung_up_p(filp)) |
1021 | goto out; | 1019 | goto out; |
@@ -1041,6 +1039,7 @@ static void rc_close(struct tty_struct *tty, struct file *filp) | |||
1041 | * the line discipline to only process XON/XOFF characters. | 1039 | * the line discipline to only process XON/XOFF characters. |
1042 | */ | 1040 | */ |
1043 | tty->closing = 1; | 1041 | tty->closing = 1; |
1042 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
1044 | if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1043 | if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1045 | tty_wait_until_sent(tty, port->port.closing_wait); | 1044 | tty_wait_until_sent(tty, port->port.closing_wait); |
1046 | /* | 1045 | /* |
@@ -1049,6 +1048,8 @@ static void rc_close(struct tty_struct *tty, struct file *filp) | |||
1049 | * interrupt driver to stop checking the data ready bit in the | 1048 | * interrupt driver to stop checking the data ready bit in the |
1050 | * line status register. | 1049 | * line status register. |
1051 | */ | 1050 | */ |
1051 | |||
1052 | spin_lock_irqsave(&riscom_lock, flags); | ||
1052 | port->IER &= ~IER_RXD; | 1053 | port->IER &= ~IER_RXD; |
1053 | if (port->port.flags & ASYNC_INITIALIZED) { | 1054 | if (port->port.flags & ASYNC_INITIALIZED) { |
1054 | port->IER &= ~IER_TXRDY; | 1055 | port->IER &= ~IER_TXRDY; |
@@ -1062,21 +1063,27 @@ static void rc_close(struct tty_struct *tty, struct file *filp) | |||
1062 | */ | 1063 | */ |
1063 | timeout = jiffies + HZ; | 1064 | timeout = jiffies + HZ; |
1064 | while (port->IER & IER_TXEMPTY) { | 1065 | while (port->IER & IER_TXEMPTY) { |
1066 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1065 | msleep_interruptible(jiffies_to_msecs(port->timeout)); | 1067 | msleep_interruptible(jiffies_to_msecs(port->timeout)); |
1068 | spin_lock_irqsave(&riscom_lock, flags); | ||
1066 | if (time_after(jiffies, timeout)) | 1069 | if (time_after(jiffies, timeout)) |
1067 | break; | 1070 | break; |
1068 | } | 1071 | } |
1069 | } | 1072 | } |
1070 | rc_shutdown_port(tty, bp, port); | 1073 | rc_shutdown_port(tty, bp, port); |
1071 | rc_flush_buffer(tty); | 1074 | rc_flush_buffer(tty); |
1075 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1072 | tty_ldisc_flush(tty); | 1076 | tty_ldisc_flush(tty); |
1073 | 1077 | ||
1078 | spin_lock_irqsave(&port->port.lock, flags); | ||
1074 | tty->closing = 0; | 1079 | tty->closing = 0; |
1075 | port->port.tty = NULL; | 1080 | port->port.tty = NULL; |
1076 | if (port->port.blocked_open) { | 1081 | if (port->port.blocked_open) { |
1082 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
1077 | if (port->port.close_delay) | 1083 | if (port->port.close_delay) |
1078 | msleep_interruptible(jiffies_to_msecs(port->port.close_delay)); | 1084 | msleep_interruptible(jiffies_to_msecs(port->port.close_delay)); |
1079 | wake_up_interruptible(&port->port.open_wait); | 1085 | wake_up_interruptible(&port->port.open_wait); |
1086 | spin_lock_irqsave(&port->port.lock, flags); | ||
1080 | } | 1087 | } |
1081 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1088 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
1082 | wake_up_interruptible(&port->port.close_wait); | 1089 | wake_up_interruptible(&port->port.close_wait); |
@@ -1465,6 +1472,7 @@ static void rc_hangup(struct tty_struct *tty) | |||
1465 | { | 1472 | { |
1466 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1473 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1467 | struct riscom_board *bp; | 1474 | struct riscom_board *bp; |
1475 | unsigned long flags; | ||
1468 | 1476 | ||
1469 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) | 1477 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) |
1470 | return; | 1478 | return; |
@@ -1472,10 +1480,12 @@ static void rc_hangup(struct tty_struct *tty) | |||
1472 | bp = port_Board(port); | 1480 | bp = port_Board(port); |
1473 | 1481 | ||
1474 | rc_shutdown_port(tty, bp, port); | 1482 | rc_shutdown_port(tty, bp, port); |
1483 | spin_lock_irqsave(&port->port.lock, flags); | ||
1475 | port->port.count = 0; | 1484 | port->port.count = 0; |
1476 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1485 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1477 | port->port.tty = NULL; | 1486 | port->port.tty = NULL; |
1478 | wake_up_interruptible(&port->port.open_wait); | 1487 | wake_up_interruptible(&port->port.open_wait); |
1488 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
1479 | } | 1489 | } |
1480 | 1490 | ||
1481 | static void rc_set_termios(struct tty_struct *tty, | 1491 | static void rc_set_termios(struct tty_struct *tty, |