Commit fc83815c authored by Jiri Slaby's avatar Jiri Slaby Committed by Linus Torvalds

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: default avatarJiri Slaby <jirislaby@gmail.com>
Cc: Jan Yenya Kasprzak <kas@fi.muni.cz>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b446a4a5
...@@ -1338,43 +1338,23 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int 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) * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
* Caller should use TIOCGICOUNT to see which one it was * Caller should use TIOCGICOUNT to see which one it was
*/ */
case TIOCMIWAIT: { case TIOCMIWAIT:
DECLARE_WAITQUEUE(wait, current); spin_lock_irqsave(&info->slock, flags);
int ret; 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); 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); spin_unlock_irqrestore(&info->slock, flags);
add_wait_queue(&info->delta_msr_wait, &wait); ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
while (1) { ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
spin_lock_irqsave(&info->slock, flags); ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
cnow = info->icount; /* atomic copy */ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
spin_unlock_irqrestore(&info->slock, flags); }));
break;
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 */
/* /*
* Get counter of input serial line interrupts (DCD,RI,DSR,CTS) * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
* Return: write counters to the user passed counter struct * Return: write counters to the user passed counter struct
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment