diff options
| author | Jiri Slaby <jirislaby@gmail.com> | 2007-04-23 17:41:03 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-24 11:23:07 -0400 |
| commit | b446a4a5757fe1287bf3472efcdde6b59dfd63ad (patch) | |
| tree | ca74e82f6e4b88265342ff9ba22e16cf8e2bc727 | |
| parent | 67d2bc58afdd5168dce54ae06f5f30038c59f498 (diff) | |
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>
| -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, | |||
| 1758 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) | 1758 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) |
| 1759 | * Caller should use TIOCGICOUNT to see which one it was | 1759 | * Caller should use TIOCGICOUNT to see which one it was |
| 1760 | */ | 1760 | */ |
| 1761 | case TIOCMIWAIT: { | 1761 | case TIOCMIWAIT: |
| 1762 | DECLARE_WAITQUEUE(wait, current); | ||
| 1763 | int ret; | ||
| 1764 | spin_lock_irqsave(&info->slock, flags); | 1762 | spin_lock_irqsave(&info->slock, flags); |
| 1765 | cprev = info->icount; /* note the counters on entry */ | 1763 | cnow = info->icount; /* note the counters on entry */ |
| 1766 | spin_unlock_irqrestore(&info->slock, flags); | 1764 | spin_unlock_irqrestore(&info->slock, flags); |
| 1767 | 1765 | ||
| 1768 | add_wait_queue(&info->delta_msr_wait, &wait); | 1766 | wait_event_interruptible(info->delta_msr_wait, ({ |
| 1769 | while (1) { | 1767 | cprev = cnow; |
| 1770 | spin_lock_irqsave(&info->slock, flags); | 1768 | spin_lock_irqsave(&info->slock, flags); |
| 1771 | cnow = info->icount; /* atomic copy */ | 1769 | cnow = info->icount; /* atomic copy */ |
| 1772 | spin_unlock_irqrestore(&info->slock, flags); | 1770 | spin_unlock_irqrestore(&info->slock, flags); |
| 1773 | 1771 | ||
| 1774 | set_current_state(TASK_INTERRUPTIBLE); | 1772 | ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || |
| 1775 | if (((arg & TIOCM_RNG) && | 1773 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || |
| 1776 | (cnow.rng != cprev.rng)) || | 1774 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || |
| 1777 | ((arg & TIOCM_DSR) && | 1775 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)); |
| 1778 | (cnow.dsr != cprev.dsr)) || | 1776 | })); |
| 1779 | ((arg & TIOCM_CD) && | ||
| 1780 | (cnow.dcd != cprev.dcd)) || | ||
| 1781 | ((arg & TIOCM_CTS) && | ||
| 1782 | (cnow.cts != cprev.cts))) { | ||
| 1783 | ret = 0; | ||
| 1784 | break; | ||
| 1785 | } | ||
| 1786 | /* see if a signal did it */ | ||
| 1787 | if (signal_pending(current)) { | ||
| 1788 | ret = -ERESTARTSYS; | ||
| 1789 | break; | ||
| 1790 | } | ||
| 1791 | cprev = cnow; | ||
| 1792 | } | ||
| 1793 | current->state = TASK_RUNNING; | ||
| 1794 | remove_wait_queue(&info->delta_msr_wait, &wait); | ||
| 1795 | break; | 1777 | break; |
| 1796 | } | ||
| 1797 | /* NOTREACHED */ | ||
| 1798 | /* | 1778 | /* |
| 1799 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | 1779 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) |
| 1800 | * Return: write counters to the user passed counter struct | 1780 | * Return: write counters to the user passed counter struct |
