diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2007-04-23 23:41:03 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-24 17:23:07 +0200 |
commit | b446a4a5757fe1287bf3472efcdde6b59dfd63ad (patch) | |
tree | ca74e82f6e4b88265342ff9ba22e16cf8e2bc727 /drivers/char | |
parent | Char: mxser_new, fix recursive locking (diff) | |
download | linux-b446a4a5757fe1287bf3472efcdde6b59dfd63ad.tar.xz linux-b446a4a5757fe1287bf3472efcdde6b59dfd63ad.zip |
Char: mxser_new, fix TIOCMIWAIT
There was schedule() missing in the TIOCMIWAIT ioctl. Solve it by moving
the code to the wait_event_interruptible.
Cc: Jan "Yenya" Kasprzak <kas@fi.muni.cz>
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
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>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/mxser_new.c | 38 |
1 files changed, 9 insertions, 29 deletions
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index 59e0aac19c2f..f7603b6aeb87 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c @@ -1758,43 +1758,23 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, * (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); - cprev = info->icount; /* note the counters on entry */ + cnow = info->icount; /* note the counters on entry */ spin_unlock_irqrestore(&info->slock, flags); - add_wait_queue(&info->delta_msr_wait, &wait); - while (1) { + wait_event_interruptible(info->delta_msr_wait, ({ + cprev = cnow; 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); + ((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; - } - /* NOTREACHED */ /* * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) * Return: write counters to the user passed counter struct |