staging: quatech_usb2: Potential lost wakeup scenario in TIOCMIWAIT
[pandora-kernel.git] / drivers / staging / quatech_usb2 / quatech_usb2.c
index ca098ca..02fafec 100644 (file)
@@ -916,9 +916,10 @@ static int qt2_ioctl(struct tty_struct *tty,
                dbg("%s() port %d, cmd == TIOCMIWAIT enter",
                        __func__, port->number);
                prev_msr_value = port_extra->shadowMSR  & QT2_SERIAL_MSR_MASK;
+               barrier();
+               __set_current_state(TASK_INTERRUPTIBLE);
                while (1) {
                        add_wait_queue(&port_extra->wait, &wait);
-                       set_current_state(TASK_INTERRUPTIBLE);
                        schedule();
                        dbg("%s(): port %d, cmd == TIOCMIWAIT here\n",
                                __func__, port->number);
@@ -926,9 +927,12 @@ static int qt2_ioctl(struct tty_struct *tty,
                        /* see if a signal woke us up */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+                       set_current_state(TASK_INTERRUPTIBLE);
                        msr_value = port_extra->shadowMSR & QT2_SERIAL_MSR_MASK;
-                       if (msr_value == prev_msr_value)
+                       if (msr_value == prev_msr_value) {
+                               __set_current_state(TASK_RUNNING);
                                return -EIO;  /* no change - error */
+                       }
                        if ((arg & TIOCM_RNG &&
                                ((prev_msr_value & QT2_SERIAL_MSR_RI) ==
                                        (msr_value & QT2_SERIAL_MSR_RI))) ||
@@ -941,6 +945,7 @@ static int qt2_ioctl(struct tty_struct *tty,
                                (arg & TIOCM_CTS &&
                                ((prev_msr_value & QT2_SERIAL_MSR_CTS) ==
                                        (msr_value & QT2_SERIAL_MSR_CTS)))) {
+                               __set_current_state(TASK_RUNNING);
                                return 0;
                        }
                } /* end inifinite while */