aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-11-30 08:18:02 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 18:18:07 -0500
commita808ac0c4a2c5d81ba38a2a76d4ddc1de40d1539 (patch)
tree9f00e6494e1ee25d29f979d8723ac361003e03d4 /drivers/char
parentf5c5a36d27ae6d9e03c2f1b7890942bf84e92c5b (diff)
tty: moxa: Locking clean up
- The open lock is needed to fix up the case of a board reset occuring during tty open but too early for a sane hangup response. - The lock can however got for other cases - Use the port mutex for get/setserial - Fix up the confused lack of locking on the THROTTLE and other bits in the private flags. Just use set/test/clear bit and it covers the cases we need Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/moxa.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 474d936d3b31..7ab720f1f30c 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -151,10 +151,10 @@ struct mon_str {
151}; 151};
152 152
153/* statusflags */ 153/* statusflags */
154#define TXSTOPPED 0x1 154#define TXSTOPPED 1
155#define LOWWAIT 0x2 155#define LOWWAIT 2
156#define EMPTYWAIT 0x4 156#define EMPTYWAIT 3
157#define THROTTLE 0x8 157#define THROTTLE 4
158 158
159#define SERIAL_DO_RESTART 159#define SERIAL_DO_RESTART
160 160
@@ -235,6 +235,8 @@ static void MoxaSetFifo(struct moxa_port *port, int enable);
235 * I/O functions 235 * I/O functions
236 */ 236 */
237 237
238static DEFINE_SPINLOCK(moxafunc_lock);
239
238static void moxa_wait_finish(void __iomem *ofsAddr) 240static void moxa_wait_finish(void __iomem *ofsAddr)
239{ 241{
240 unsigned long end = jiffies + moxaFuncTout; 242 unsigned long end = jiffies + moxaFuncTout;
@@ -381,14 +383,14 @@ copy:
381 break; 383 break;
382 } 384 }
383 case TIOCGSERIAL: 385 case TIOCGSERIAL:
384 mutex_lock(&moxa_openlock); 386 mutex_lock(&ch->port.mutex);
385 ret = moxa_get_serial_info(ch, argp); 387 ret = moxa_get_serial_info(ch, argp);
386 mutex_unlock(&moxa_openlock); 388 mutex_unlock(&ch->port.mutex);
387 break; 389 break;
388 case TIOCSSERIAL: 390 case TIOCSSERIAL:
389 mutex_lock(&moxa_openlock); 391 mutex_lock(&ch->port.mutex);
390 ret = moxa_set_serial_info(ch, argp); 392 ret = moxa_set_serial_info(ch, argp);
391 mutex_unlock(&moxa_openlock); 393 mutex_unlock(&ch->port.mutex);
392 break; 394 break;
393 default: 395 default:
394 ret = -ENOIOCTLCMD; 396 ret = -ENOIOCTLCMD;
@@ -433,7 +435,6 @@ static const struct tty_port_operations moxa_port_ops = {
433static struct tty_driver *moxaDriver; 435static struct tty_driver *moxaDriver;
434static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); 436static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
435static DEFINE_SPINLOCK(moxa_lock); 437static DEFINE_SPINLOCK(moxa_lock);
436static DEFINE_SPINLOCK(moxafunc_lock);
437 438
438/* 439/*
439 * HW init 440 * HW init
@@ -1208,9 +1209,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
1208{ 1209{
1209 struct moxa_port *ch = tty->driver_data; 1210 struct moxa_port *ch = tty->driver_data;
1210 ch->cflag = tty->termios->c_cflag; 1211 ch->cflag = tty->termios->c_cflag;
1211 mutex_lock(&moxa_openlock);
1212 tty_port_close(&ch->port, tty, filp); 1212 tty_port_close(&ch->port, tty, filp);
1213 mutex_unlock(&moxa_openlock);
1214} 1213}
1215 1214
1216static int moxa_write(struct tty_struct *tty, 1215static int moxa_write(struct tty_struct *tty,
@@ -1226,7 +1225,7 @@ static int moxa_write(struct tty_struct *tty,
1226 len = MoxaPortWriteData(tty, buf, count); 1225 len = MoxaPortWriteData(tty, buf, count);
1227 spin_unlock_bh(&moxa_lock); 1226 spin_unlock_bh(&moxa_lock);
1228 1227
1229 ch->statusflags |= LOWWAIT; 1228 set_bit(LOWWAIT, &ch->statusflags);
1230 return len; 1229 return len;
1231} 1230}
1232 1231
@@ -1264,7 +1263,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
1264 * Make it possible to wakeup anything waiting for output 1263 * Make it possible to wakeup anything waiting for output
1265 * in tty_ioctl.c, etc. 1264 * in tty_ioctl.c, etc.
1266 */ 1265 */
1267 if (!(ch->statusflags & EMPTYWAIT)) 1266 if (!test_bit(EMPTYWAIT, &ch->statusflags))
1268 moxa_setup_empty_event(tty); 1267 moxa_setup_empty_event(tty);
1269 } 1268 }
1270 unlock_kernel(); 1269 unlock_kernel();
@@ -1332,14 +1331,14 @@ static void moxa_throttle(struct tty_struct *tty)
1332{ 1331{
1333 struct moxa_port *ch = tty->driver_data; 1332 struct moxa_port *ch = tty->driver_data;
1334 1333
1335 ch->statusflags |= THROTTLE; 1334 set_bit(THROTTLE, &ch->statusflags);
1336} 1335}
1337 1336
1338static void moxa_unthrottle(struct tty_struct *tty) 1337static void moxa_unthrottle(struct tty_struct *tty)
1339{ 1338{
1340 struct moxa_port *ch = tty->driver_data; 1339 struct moxa_port *ch = tty->driver_data;
1341 1340
1342 ch->statusflags &= ~THROTTLE; 1341 clear_bit(THROTTLE, &ch->statusflags);
1343} 1342}
1344 1343
1345static void moxa_set_termios(struct tty_struct *tty, 1344static void moxa_set_termios(struct tty_struct *tty,
@@ -1361,7 +1360,7 @@ static void moxa_stop(struct tty_struct *tty)
1361 if (ch == NULL) 1360 if (ch == NULL)
1362 return; 1361 return;
1363 MoxaPortTxDisable(ch); 1362 MoxaPortTxDisable(ch);
1364 ch->statusflags |= TXSTOPPED; 1363 set_bit(TXSTOPPED, &ch->statusflags);
1365} 1364}
1366 1365
1367 1366
@@ -1376,17 +1375,13 @@ static void moxa_start(struct tty_struct *tty)
1376 return; 1375 return;
1377 1376
1378 MoxaPortTxEnable(ch); 1377 MoxaPortTxEnable(ch);
1379 ch->statusflags &= ~TXSTOPPED; 1378 clear_bit(TXSTOPPED, &ch->statusflags);
1380} 1379}
1381 1380
1382static void moxa_hangup(struct tty_struct *tty) 1381static void moxa_hangup(struct tty_struct *tty)
1383{ 1382{
1384 struct moxa_port *ch; 1383 struct moxa_port *ch = tty->driver_data;
1385
1386 mutex_lock(&moxa_openlock);
1387 ch = tty->driver_data;
1388 tty_port_hangup(&ch->port); 1384 tty_port_hangup(&ch->port);
1389 mutex_unlock(&moxa_openlock);
1390} 1385}
1391 1386
1392static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) 1387static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
@@ -1412,24 +1407,24 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
1412 u16 intr; 1407 u16 intr;
1413 1408
1414 if (tty) { 1409 if (tty) {
1415 if ((p->statusflags & EMPTYWAIT) && 1410 if (test_bit(EMPTYWAIT, &p->statusflags) &&
1416 MoxaPortTxQueue(p) == 0) { 1411 MoxaPortTxQueue(p) == 0) {
1417 p->statusflags &= ~EMPTYWAIT; 1412 clear_bit(EMPTYWAIT, &p->statusflags);
1418 tty_wakeup(tty); 1413 tty_wakeup(tty);
1419 } 1414 }
1420 if ((p->statusflags & LOWWAIT) && !tty->stopped && 1415 if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped &&
1421 MoxaPortTxQueue(p) <= WAKEUP_CHARS) { 1416 MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
1422 p->statusflags &= ~LOWWAIT; 1417 clear_bit(LOWWAIT, &p->statusflags);
1423 tty_wakeup(tty); 1418 tty_wakeup(tty);
1424 } 1419 }
1425 1420
1426 if (inited && !(p->statusflags & THROTTLE) && 1421 if (inited && !test_bit(THROTTLE, &p->statusflags) &&
1427 MoxaPortRxQueue(p) > 0) { /* RX */ 1422 MoxaPortRxQueue(p) > 0) { /* RX */
1428 MoxaPortReadData(p); 1423 MoxaPortReadData(p);
1429 tty_schedule_flip(tty); 1424 tty_schedule_flip(tty);
1430 } 1425 }
1431 } else { 1426 } else {
1432 p->statusflags &= ~EMPTYWAIT; 1427 clear_bit(EMPTYWAIT, &p->statusflags);
1433 MoxaPortFlushData(p, 0); /* flush RX */ 1428 MoxaPortFlushData(p, 0); /* flush RX */
1434 } 1429 }
1435 1430
@@ -1533,10 +1528,7 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
1533static void moxa_setup_empty_event(struct tty_struct *tty) 1528static void moxa_setup_empty_event(struct tty_struct *tty)
1534{ 1529{
1535 struct moxa_port *ch = tty->driver_data; 1530 struct moxa_port *ch = tty->driver_data;
1536 1531 set_bit(EMPTYWAIT, &ch->statusflags);
1537 spin_lock_bh(&moxa_lock);
1538 ch->statusflags |= EMPTYWAIT;
1539 spin_unlock_bh(&moxa_lock);
1540} 1532}
1541 1533
1542/***************************************************************************** 1534/*****************************************************************************
@@ -1845,7 +1837,7 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
1845 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); 1837 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
1846 writeb(FC_SetXonXoff, ofsAddr + FuncCode); 1838 writeb(FC_SetXonXoff, ofsAddr + FuncCode);
1847 moxa_wait_finish(ofsAddr); 1839 moxa_wait_finish(ofsAddr);
1848 spin_unlock_irqrestore(&moxafunc_lock); 1840 spin_unlock_irq(&moxafunc_lock);
1849 1841
1850 } 1842 }
1851 return baud; 1843 return baud;