|
@@ -368,6 +368,29 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * tty_buffer_flush - flush full tty buffers
|
|
|
+ * @tty: tty to flush
|
|
|
+ *
|
|
|
+ * flush all the buffers containing receive data
|
|
|
+ *
|
|
|
+ * Locking: none
|
|
|
+ */
|
|
|
+
|
|
|
+static void tty_buffer_flush(struct tty_struct *tty)
|
|
|
+{
|
|
|
+ struct tty_buffer *thead;
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&tty->buf.lock, flags);
|
|
|
+ while((thead = tty->buf.head) != NULL) {
|
|
|
+ tty->buf.head = thead->next;
|
|
|
+ tty_buffer_free(tty, thead);
|
|
|
+ }
|
|
|
+ tty->buf.tail = NULL;
|
|
|
+ spin_unlock_irqrestore(&tty->buf.lock, flags);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* tty_buffer_find - find a free tty buffer
|
|
|
* @tty: tty owning the buffer
|
|
@@ -1248,6 +1271,7 @@ void tty_ldisc_flush(struct tty_struct *tty)
|
|
|
ld->flush_buffer(tty);
|
|
|
tty_ldisc_deref(ld);
|
|
|
}
|
|
|
+ tty_buffer_flush(tty);
|
|
|
}
|
|
|
|
|
|
EXPORT_SYMBOL_GPL(tty_ldisc_flush);
|
|
@@ -3350,6 +3374,15 @@ int tty_ioctl(struct inode * inode, struct file * file,
|
|
|
case TIOCMBIC:
|
|
|
case TIOCMBIS:
|
|
|
return tty_tiocmset(tty, file, cmd, p);
|
|
|
+ case TCFLSH:
|
|
|
+ switch (arg) {
|
|
|
+ case TCIFLUSH:
|
|
|
+ case TCIOFLUSH:
|
|
|
+ /* flush tty buffer and allow ldisc to process ioctl */
|
|
|
+ tty_buffer_flush(tty);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
if (tty->driver->ioctl) {
|
|
|
retval = (tty->driver->ioctl)(tty, file, cmd, arg);
|