|
@@ -919,18 +919,18 @@ void no_tty(void)
|
|
|
* but not always.
|
|
|
*
|
|
|
* Locking:
|
|
|
- * Uses the tty control lock internally
|
|
|
+ * ctrl_lock
|
|
|
+ * flow_lock
|
|
|
*/
|
|
|
|
|
|
-void stop_tty(struct tty_struct *tty)
|
|
|
+void __stop_tty(struct tty_struct *tty)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
- spin_lock_irqsave(&tty->ctrl_lock, flags);
|
|
|
- if (tty->stopped) {
|
|
|
- spin_unlock_irqrestore(&tty->ctrl_lock, flags);
|
|
|
+
|
|
|
+ if (tty->stopped)
|
|
|
return;
|
|
|
- }
|
|
|
tty->stopped = 1;
|
|
|
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
|
|
|
if (tty->link && tty->link->packet) {
|
|
|
tty->ctrl_status &= ~TIOCPKT_START;
|
|
|
tty->ctrl_status |= TIOCPKT_STOP;
|
|
@@ -941,6 +941,14 @@ void stop_tty(struct tty_struct *tty)
|
|
|
(tty->ops->stop)(tty);
|
|
|
}
|
|
|
|
|
|
+void stop_tty(struct tty_struct *tty)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&tty->flow_lock, flags);
|
|
|
+ __stop_tty(tty);
|
|
|
+ spin_unlock_irqrestore(&tty->flow_lock, flags);
|
|
|
+}
|
|
|
EXPORT_SYMBOL(stop_tty);
|
|
|
|
|
|
/**
|
|
@@ -954,17 +962,17 @@ EXPORT_SYMBOL(stop_tty);
|
|
|
*
|
|
|
* Locking:
|
|
|
* ctrl_lock
|
|
|
+ * flow_lock
|
|
|
*/
|
|
|
|
|
|
-void start_tty(struct tty_struct *tty)
|
|
|
+void __start_tty(struct tty_struct *tty)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
- spin_lock_irqsave(&tty->ctrl_lock, flags);
|
|
|
- if (!tty->stopped || tty->flow_stopped) {
|
|
|
- spin_unlock_irqrestore(&tty->ctrl_lock, flags);
|
|
|
+
|
|
|
+ if (!tty->stopped || tty->flow_stopped)
|
|
|
return;
|
|
|
- }
|
|
|
tty->stopped = 0;
|
|
|
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
|
|
|
if (tty->link && tty->link->packet) {
|
|
|
tty->ctrl_status &= ~TIOCPKT_STOP;
|
|
|
tty->ctrl_status |= TIOCPKT_START;
|
|
@@ -977,6 +985,14 @@ void start_tty(struct tty_struct *tty)
|
|
|
tty_wakeup(tty);
|
|
|
}
|
|
|
|
|
|
+void start_tty(struct tty_struct *tty)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&tty->flow_lock, flags);
|
|
|
+ __start_tty(tty);
|
|
|
+ spin_unlock_irqrestore(&tty->flow_lock, flags);
|
|
|
+}
|
|
|
EXPORT_SYMBOL(start_tty);
|
|
|
|
|
|
/* We limit tty time update visibility to every 8 seconds or so. */
|
|
@@ -3019,6 +3035,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
|
|
|
INIT_WORK(&tty->hangup_work, do_tty_hangup);
|
|
|
mutex_init(&tty->atomic_write_lock);
|
|
|
spin_lock_init(&tty->ctrl_lock);
|
|
|
+ spin_lock_init(&tty->flow_lock);
|
|
|
INIT_LIST_HEAD(&tty->tty_files);
|
|
|
INIT_WORK(&tty->SAK_work, do_SAK_work);
|
|
|
|