aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2007-04-23 17:41:04 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-24 11:23:08 -0400
commitfc83815c3afe1bd8d0f0961a668a96caabb049be (patch)
tree9086ca9ec97e19a07d3f68a6ecec300dbb19ba9b
parentb446a4a5757fe1287bf3472efcdde6b59dfd63ad (diff)
Char: mxser, fix TIOCMIWAIT
There was schedule() missing in the TIOCMIWAIT ioctl. Solve it by moving the code to the wait_event_interruptible. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Cc: Jan Yenya Kasprzak <kas@fi.muni.cz> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/mxser.c48
1 files changed, 14 insertions, 34 deletions
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index a61fb6da5d03..80a01150b86c 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1338,43 +1338,23 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
1338 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) 1338 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
1339 * Caller should use TIOCGICOUNT to see which one it was 1339 * Caller should use TIOCGICOUNT to see which one it was
1340 */ 1340 */
1341 case TIOCMIWAIT: { 1341 case TIOCMIWAIT:
1342 DECLARE_WAITQUEUE(wait, current); 1342 spin_lock_irqsave(&info->slock, flags);
1343 int ret; 1343 cnow = info->icount; /* note the counters on entry */
1344 spin_unlock_irqrestore(&info->slock, flags);
1345
1346 wait_event_interruptible(info->delta_msr_wait, ({
1347 cprev = cnow;
1344 spin_lock_irqsave(&info->slock, flags); 1348 spin_lock_irqsave(&info->slock, flags);
1345 cprev = info->icount; /* note the counters on entry */ 1349 cnow = info->icount; /* atomic copy */
1346 spin_unlock_irqrestore(&info->slock, flags); 1350 spin_unlock_irqrestore(&info->slock, flags);
1347 1351
1348 add_wait_queue(&info->delta_msr_wait, &wait); 1352 ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
1349 while (1) { 1353 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
1350 spin_lock_irqsave(&info->slock, flags); 1354 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
1351 cnow = info->icount; /* atomic copy */ 1355 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
1352 spin_unlock_irqrestore(&info->slock, flags); 1356 }));
1353 1357 break;
1354 set_current_state(TASK_INTERRUPTIBLE);
1355 if (((arg & TIOCM_RNG) &&
1356 (cnow.rng != cprev.rng)) ||
1357 ((arg & TIOCM_DSR) &&
1358 (cnow.dsr != cprev.dsr)) ||
1359 ((arg & TIOCM_CD) &&
1360 (cnow.dcd != cprev.dcd)) ||
1361 ((arg & TIOCM_CTS) &&
1362 (cnow.cts != cprev.cts))) {
1363 ret = 0;
1364 break;
1365 }
1366 /* see if a signal did it */
1367 if (signal_pending(current)) {
1368 ret = -ERESTARTSYS;
1369 break;
1370 }
1371 cprev = cnow;
1372 }
1373 current->state = TASK_RUNNING;
1374 remove_wait_queue(&info->delta_msr_wait, &wait);
1375 break;
1376 }
1377 /* NOTREACHED */
1378 /* 1358 /*
1379 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) 1359 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
1380 * Return: write counters to the user passed counter struct 1360 * Return: write counters to the user passed counter struct