Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b446a4a5 authored by Jiri Slaby's avatar Jiri Slaby Committed by Linus Torvalds
Browse files

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: default avatarJiri Slaby <jirislaby@gmail.com>
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 67d2bc58
Loading
Loading
Loading
Loading
+9 −29
Original line number Diff line number Diff line
@@ -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;
			((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;
			}
			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)
	 * Return: write counters to the user passed counter struct