diff options
author | Alan Cox <alan@redhat.com> | 2009-01-02 08:48:17 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:41 -0500 |
commit | c1314a49d7907b96d72f2c41f8927fc3c738e956 (patch) | |
tree | e19a5127804c871088d57978f8eba00cf9d3c578 /drivers/char/rocket.c | |
parent | 6ed1dbaeadd62a026a93aa3ac8680d2dfe9f96b3 (diff) |
tty: Redo the rocket driver locking
Bring this driver into the port locking model
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/rocket.c')
-rw-r--r-- | drivers/char/rocket.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 1e68cc2296fa..efc3e5c51f6f 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -920,7 +920,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
920 | #ifdef ROCKET_DEBUG_OPEN | 920 | #ifdef ROCKET_DEBUG_OPEN |
921 | printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, port->count); | 921 | printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, port->count); |
922 | #endif | 922 | #endif |
923 | spin_lock_irqsave(&info->slock, flags); | 923 | spin_lock_irqsave(&port->lock, flags); |
924 | 924 | ||
925 | #ifdef ROCKET_DISABLE_SIMUSAGE | 925 | #ifdef ROCKET_DISABLE_SIMUSAGE |
926 | info->flags |= ASYNC_NORMAL_ACTIVE; | 926 | info->flags |= ASYNC_NORMAL_ACTIVE; |
@@ -932,7 +932,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
932 | #endif | 932 | #endif |
933 | port->blocked_open++; | 933 | port->blocked_open++; |
934 | 934 | ||
935 | spin_unlock_irqrestore(&info->slock, flags); | 935 | spin_unlock_irqrestore(&port->lock, flags); |
936 | 936 | ||
937 | while (1) { | 937 | while (1) { |
938 | if (tty->termios->c_cflag & CBAUD) | 938 | if (tty->termios->c_cflag & CBAUD) |
@@ -961,13 +961,13 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
961 | __set_current_state(TASK_RUNNING); | 961 | __set_current_state(TASK_RUNNING); |
962 | remove_wait_queue(&port->open_wait, &wait); | 962 | remove_wait_queue(&port->open_wait, &wait); |
963 | 963 | ||
964 | spin_lock_irqsave(&info->slock, flags); | 964 | spin_lock_irqsave(&port->lock, flags); |
965 | 965 | ||
966 | if (extra_count) | 966 | if (extra_count) |
967 | port->count++; | 967 | port->count++; |
968 | port->blocked_open--; | 968 | port->blocked_open--; |
969 | 969 | ||
970 | spin_unlock_irqrestore(&info->slock, flags); | 970 | spin_unlock_irqrestore(&port->lock, flags); |
971 | 971 | ||
972 | #ifdef ROCKET_DEBUG_OPEN | 972 | #ifdef ROCKET_DEBUG_OPEN |
973 | printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n", | 973 | printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n", |
@@ -1095,6 +1095,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
1095 | static void rp_close(struct tty_struct *tty, struct file *filp) | 1095 | static void rp_close(struct tty_struct *tty, struct file *filp) |
1096 | { | 1096 | { |
1097 | struct r_port *info = tty->driver_data; | 1097 | struct r_port *info = tty->driver_data; |
1098 | struct tty_port *port = &info->port; | ||
1098 | unsigned long flags; | 1099 | unsigned long flags; |
1099 | int timeout; | 1100 | int timeout; |
1100 | CHANNEL_t *cp; | 1101 | CHANNEL_t *cp; |
@@ -1108,9 +1109,9 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1108 | 1109 | ||
1109 | if (tty_hung_up_p(filp)) | 1110 | if (tty_hung_up_p(filp)) |
1110 | return; | 1111 | return; |
1111 | spin_lock_irqsave(&info->slock, flags); | 1112 | spin_lock_irqsave(&port->lock, flags); |
1112 | 1113 | ||
1113 | if ((tty->count == 1) && (info->port.count != 1)) { | 1114 | if (tty->count == 1 && port->count != 1) { |
1114 | /* | 1115 | /* |
1115 | * Uh, oh. tty->count is 1, which means that the tty | 1116 | * Uh, oh. tty->count is 1, which means that the tty |
1116 | * structure will be freed. Info->count should always | 1117 | * structure will be freed. Info->count should always |
@@ -1120,19 +1121,19 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1120 | */ | 1121 | */ |
1121 | printk(KERN_WARNING "rp_close: bad serial port count; " | 1122 | printk(KERN_WARNING "rp_close: bad serial port count; " |
1122 | "tty->count is 1, info->port.count is %d\n", info->port.count); | 1123 | "tty->count is 1, info->port.count is %d\n", info->port.count); |
1123 | info->port.count = 1; | 1124 | port->count = 1; |
1124 | } | 1125 | } |
1125 | if (--info->port.count < 0) { | 1126 | if (--port->count < 0) { |
1126 | printk(KERN_WARNING "rp_close: bad serial port count for " | 1127 | printk(KERN_WARNING "rp_close: bad serial port count for " |
1127 | "ttyR%d: %d\n", info->line, info->port.count); | 1128 | "ttyR%d: %d\n", info->line, info->port.count); |
1128 | info->port.count = 0; | 1129 | port->count = 0; |
1129 | } | 1130 | } |
1130 | if (info->port.count) { | 1131 | if (port->count) { |
1131 | spin_unlock_irqrestore(&info->slock, flags); | 1132 | spin_unlock_irqrestore(&port->lock, flags); |
1132 | return; | 1133 | return; |
1133 | } | 1134 | } |
1134 | info->flags |= ASYNC_CLOSING; | 1135 | info->flags |= ASYNC_CLOSING; |
1135 | spin_unlock_irqrestore(&info->slock, flags); | 1136 | spin_unlock_irqrestore(&port->lock, flags); |
1136 | 1137 | ||
1137 | cp = &info->channel; | 1138 | cp = &info->channel; |
1138 | 1139 | ||
@@ -1152,7 +1153,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1152 | * Wait for the transmit buffer to clear | 1153 | * Wait for the transmit buffer to clear |
1153 | */ | 1154 | */ |
1154 | if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1155 | if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1155 | tty_wait_until_sent(tty, info->port.closing_wait); | 1156 | tty_wait_until_sent(tty, port->closing_wait); |
1156 | /* | 1157 | /* |
1157 | * Before we drop DTR, make sure the UART transmitter | 1158 | * Before we drop DTR, make sure the UART transmitter |
1158 | * has completely drained; this is especially | 1159 | * has completely drained; this is especially |
@@ -1181,11 +1182,11 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1181 | 1182 | ||
1182 | clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); | 1183 | clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); |
1183 | 1184 | ||
1184 | if (info->port.blocked_open) { | 1185 | if (port->blocked_open) { |
1185 | if (info->port.close_delay) { | 1186 | if (port->close_delay) { |
1186 | msleep_interruptible(jiffies_to_msecs(info->port.close_delay)); | 1187 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); |
1187 | } | 1188 | } |
1188 | wake_up_interruptible(&info->port.open_wait); | 1189 | wake_up_interruptible(&port->open_wait); |
1189 | } else { | 1190 | } else { |
1190 | if (info->xmit_buf) { | 1191 | if (info->xmit_buf) { |
1191 | free_page((unsigned long) info->xmit_buf); | 1192 | free_page((unsigned long) info->xmit_buf); |