summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2007-04-23 14:41:04 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-24 08:23:08 -0700
commitfc83815c3afe1bd8d0f0961a668a96caabb049be (patch)
tree9086ca9ec97e19a07d3f68a6ecec300dbb19ba9b
parentb446a4a5757fe1287bf3472efcdde6b59dfd63ad (diff)
downloadlinux-fc83815c3afe1bd8d0f0961a668a96caabb049be.tar.bz2
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
* (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
* Caller should use TIOCGICOUNT to see which one it was
*/
- case TIOCMIWAIT: {
- DECLARE_WAITQUEUE(wait, current);
- int ret;
+ case TIOCMIWAIT:
+ spin_lock_irqsave(&info->slock, flags);
+ cnow = info->icount; /* note the counters on entry */
+ spin_unlock_irqrestore(&info->slock, flags);
+
+ wait_event_interruptible(info->delta_msr_wait, ({
+ cprev = cnow;
spin_lock_irqsave(&info->slock, flags);
- cprev = info->icount; /* note the counters on entry */
+ cnow = info->icount; /* atomic copy */
spin_unlock_irqrestore(&info->slock, flags);
- add_wait_queue(&info->delta_msr_wait, &wait);
- while (1) {
- spin_lock_irqsave(&info->slock, flags);
- cnow = info->icount; /* atomic copy */
- spin_unlock_irqrestore(&info->slock, flags);
-
- set_current_state(TASK_INTERRUPTIBLE);
- if (((arg & TIOCM_RNG) &&
- (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) &&
- (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) &&
- (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) &&
- (cnow.cts != cprev.cts))) {
- ret = 0;
- break;
- }
- /* see if a signal did it */
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- cprev = cnow;
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&info->delta_msr_wait, &wait);
- break;
- }
- /* NOTREACHED */
+ ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
+ }));
+ break;
/*
* Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
* Return: write counters to the user passed counter struct