aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/rocket.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 0e29a23ec4c5..79c3bc69165a 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -73,7 +73,6 @@
73#include <linux/tty_driver.h> 73#include <linux/tty_driver.h>
74#include <linux/tty_flip.h> 74#include <linux/tty_flip.h>
75#include <linux/serial.h> 75#include <linux/serial.h>
76#include <linux/smp_lock.h>
77#include <linux/string.h> 76#include <linux/string.h>
78#include <linux/fcntl.h> 77#include <linux/fcntl.h>
79#include <linux/ptrace.h> 78#include <linux/ptrace.h>
@@ -1017,6 +1016,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1017 if (tty_port_close_start(port, tty, filp) == 0) 1016 if (tty_port_close_start(port, tty, filp) == 0)
1018 return; 1017 return;
1019 1018
1019 mutex_lock(&port->mutex);
1020 cp = &info->channel; 1020 cp = &info->channel;
1021 /* 1021 /*
1022 * Before we drop DTR, make sure the UART transmitter 1022 * Before we drop DTR, make sure the UART transmitter
@@ -1060,9 +1060,13 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1060 info->xmit_buf = NULL; 1060 info->xmit_buf = NULL;
1061 } 1061 }
1062 } 1062 }
1063 spin_lock_irq(&port->lock);
1063 info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE); 1064 info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE);
1064 tty->closing = 0; 1065 tty->closing = 0;
1066 spin_unlock_irq(&port->lock);
1067 mutex_unlock(&port->mutex);
1065 tty_port_tty_set(port, NULL); 1068 tty_port_tty_set(port, NULL);
1069
1066 wake_up_interruptible(&port->close_wait); 1070 wake_up_interruptible(&port->close_wait);
1067 complete_all(&info->close_wait); 1071 complete_all(&info->close_wait);
1068 atomic_dec(&rp_num_ports_open); 1072 atomic_dec(&rp_num_ports_open);
@@ -1210,11 +1214,13 @@ static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
1210 if (!retinfo) 1214 if (!retinfo)
1211 return -EFAULT; 1215 return -EFAULT;
1212 memset(&tmp, 0, sizeof (tmp)); 1216 memset(&tmp, 0, sizeof (tmp));
1217 mutex_lock(&info->port.mutex);
1213 tmp.line = info->line; 1218 tmp.line = info->line;
1214 tmp.flags = info->flags; 1219 tmp.flags = info->flags;
1215 tmp.close_delay = info->port.close_delay; 1220 tmp.close_delay = info->port.close_delay;
1216 tmp.closing_wait = info->port.closing_wait; 1221 tmp.closing_wait = info->port.closing_wait;
1217 tmp.port = rcktpt_io_addr[(info->line >> 5) & 3]; 1222 tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];
1223 mutex_unlock(&info->port.mutex);
1218 1224
1219 if (copy_to_user(retinfo, &tmp, sizeof (*retinfo))) 1225 if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
1220 return -EFAULT; 1226 return -EFAULT;
@@ -1229,10 +1235,13 @@ static int set_config(struct tty_struct *tty, struct r_port *info,
1229 if (copy_from_user(&new_serial, new_info, sizeof (new_serial))) 1235 if (copy_from_user(&new_serial, new_info, sizeof (new_serial)))
1230 return -EFAULT; 1236 return -EFAULT;
1231 1237
1238 mutex_lock(&info->port.mutex);
1232 if (!capable(CAP_SYS_ADMIN)) 1239 if (!capable(CAP_SYS_ADMIN))
1233 { 1240 {
1234 if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) 1241 if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) {
1242 mutex_unlock(&info->port.mutex);
1235 return -EPERM; 1243 return -EPERM;
1244 }
1236 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); 1245 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
1237 configure_r_port(tty, info, NULL); 1246 configure_r_port(tty, info, NULL);
1238 return 0; 1247 return 0;
@@ -1250,6 +1259,7 @@ static int set_config(struct tty_struct *tty, struct r_port *info,
1250 tty->alt_speed = 230400; 1259 tty->alt_speed = 230400;
1251 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) 1260 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
1252 tty->alt_speed = 460800; 1261 tty->alt_speed = 460800;
1262 mutex_unlock(&info->port.mutex);
1253 1263
1254 configure_r_port(tty, info, NULL); 1264 configure_r_port(tty, info, NULL);
1255 return 0; 1265 return 0;
@@ -1325,8 +1335,6 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file,
1325 if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl")) 1335 if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
1326 return -ENXIO; 1336 return -ENXIO;
1327 1337
1328 lock_kernel();
1329
1330 switch (cmd) { 1338 switch (cmd) {
1331 case RCKP_GET_STRUCT: 1339 case RCKP_GET_STRUCT:
1332 if (copy_to_user(argp, info, sizeof (struct r_port))) 1340 if (copy_to_user(argp, info, sizeof (struct r_port)))
@@ -1350,7 +1358,6 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file,
1350 default: 1358 default:
1351 ret = -ENOIOCTLCMD; 1359 ret = -ENOIOCTLCMD;
1352 } 1360 }
1353 unlock_kernel();
1354 return ret; 1361 return ret;
1355} 1362}
1356 1363
@@ -1471,7 +1478,6 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
1471 jiffies); 1478 jiffies);
1472 printk(KERN_INFO "cps=%d...\n", info->cps); 1479 printk(KERN_INFO "cps=%d...\n", info->cps);
1473#endif 1480#endif
1474 lock_kernel();
1475 while (1) { 1481 while (1) {
1476 txcnt = sGetTxCnt(cp); 1482 txcnt = sGetTxCnt(cp);
1477 if (!txcnt) { 1483 if (!txcnt) {
@@ -1499,7 +1505,6 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
1499 break; 1505 break;
1500 } 1506 }
1501 __set_current_state(TASK_RUNNING); 1507 __set_current_state(TASK_RUNNING);
1502 unlock_kernel();
1503#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT 1508#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1504 printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); 1509 printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
1505#endif 1510#endif
@@ -1512,6 +1517,7 @@ static void rp_hangup(struct tty_struct *tty)
1512{ 1517{
1513 CHANNEL_t *cp; 1518 CHANNEL_t *cp;
1514 struct r_port *info = tty->driver_data; 1519 struct r_port *info = tty->driver_data;
1520 unsigned long flags;
1515 1521
1516 if (rocket_paranoia_check(info, "rp_hangup")) 1522 if (rocket_paranoia_check(info, "rp_hangup"))
1517 return; 1523 return;
@@ -1520,11 +1526,15 @@ static void rp_hangup(struct tty_struct *tty)
1520 printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line); 1526 printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line);
1521#endif 1527#endif
1522 rp_flush_buffer(tty); 1528 rp_flush_buffer(tty);
1523 if (info->port.flags & ASYNC_CLOSING) 1529 spin_lock_irqsave(&info->port.lock, flags);
1530 if (info->port.flags & ASYNC_CLOSING) {
1531 spin_unlock_irqrestore(&info->port.lock, flags);
1524 return; 1532 return;
1533 }
1525 if (info->port.count) 1534 if (info->port.count)
1526 atomic_dec(&rp_num_ports_open); 1535 atomic_dec(&rp_num_ports_open);
1527 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); 1536 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1537 spin_unlock_irqrestore(&info->port.lock, flags);
1528 1538
1529 tty_port_hangup(&info->port); 1539 tty_port_hangup(&info->port);
1530 1540
@@ -1535,7 +1545,7 @@ static void rp_hangup(struct tty_struct *tty)
1535 sDisCTSFlowCtl(cp); 1545 sDisCTSFlowCtl(cp);
1536 sDisTxSoftFlowCtl(cp); 1546 sDisTxSoftFlowCtl(cp);
1537 sClrTxXOFF(cp); 1547 sClrTxXOFF(cp);
1538 info->port.flags &= ~ASYNC_INITIALIZED; 1548 clear_bit(ASYNCB_INITIALIZED, &info->port.flags);
1539 1549
1540 wake_up_interruptible(&info->port.open_wait); 1550 wake_up_interruptible(&info->port.open_wait);
1541} 1551}