diff --git a/kernel.spec b/kernel.spec index 397bbbd..bad03f1 100644 --- a/kernel.spec +++ b/kernel.spec @@ -31,7 +31,7 @@ Summary: The Linux kernel # # (Uncomment the '#' and both spaces below to set the buildid.) # -# % define buildid .local +%define buildid .caylan1 ################################################################### # The buildid can also be specified on the rpmbuild command line @@ -828,6 +828,8 @@ Patch25064: iwlwifi-dvm-dont-send-BT_CONFIG-on-devices-wo-Bluetooth.patch #rhbz 976837 Patch25065: fix-ext4-overflows.patch +Patch40000: tty-caylan-changes.patch + # END OF PATCH DEFINITIONS %endif @@ -1604,6 +1606,9 @@ ApplyPatch iwlwifi-dvm-dont-send-BT_CONFIG-on-devices-wo-Bluetooth.patch #rhbz 976837 ApplyPatch fix-ext4-overflows.patch + +ApplyPatch tty-caylan-changes.patch + # END OF PATCH APPLICATIONS %endif diff --git a/tty-caylan-changes.patch b/tty-caylan-changes.patch new file mode 100644 index 0000000..a7233b6 --- /dev/null +++ b/tty-caylan-changes.patch @@ -0,0 +1,102 @@ +diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c +index 6c7fe90..6705bf4 100644 +--- a/drivers/tty/n_tty.c ++++ b/drivers/tty/n_tty.c +@@ -1507,9 +1507,18 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) + canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; + if (canon_change) { + bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); +- ldata->canon_head = ldata->read_tail; +- ldata->canon_data = 0; + ldata->erasing = 0; ++ if (!L_ICANON(tty) || !ldata->read_cnt) { ++ ldata->canon_head = ldata->read_tail; ++ ldata->canon_data = 0; ++ } else { ++ /* the data written in raw mode should still ++ * be available for immediate read */ ++ set_bit(ldata->read_head, ldata->read_flags); ++ put_tty_queue(__DISABLED_CHAR, ldata); ++ ldata->canon_head = ldata->read_head; ++ ldata->canon_data = 1; ++ } + } + + if (canon_change && !L_ICANON(tty) && ldata->read_cnt) +@@ -1865,6 +1874,7 @@ do_it_again: + tty->minimum_to_wake = (minimum - (b - buf)); + + if (!input_available_p(tty, 0)) { ++ int old_icanon = ldata->icanon; + if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { + retval = -EIO; + break; +@@ -1884,6 +1894,30 @@ do_it_again: + /* FIXME: does n_tty_set_room need locking ? */ + n_tty_set_room(tty); + timeout = schedule_timeout(timeout); ++ if (old_icanon == ldata->icanon) ++ continue; ++ /* recalc parameters if icanon changed */ ++printk(KERN_ERR "TTY: recalc icanon\n"); ++ minimum = time = 0; ++ timeout = MAX_SCHEDULE_TIMEOUT; ++ if (!ldata->icanon) { ++ time = (HZ / 10) * TIME_CHAR(tty); ++ minimum = MIN_CHAR(tty); ++ if (minimum) { ++ if (time) ++ tty->minimum_to_wake = 1; ++ else if (!waitqueue_active(&tty->read_wait) || ++ (tty->minimum_to_wake > minimum)) ++ tty->minimum_to_wake = minimum; ++ } else { ++ timeout = 0; ++ if (time) { ++ timeout = time; ++ time = 0; ++ } ++ tty->minimum_to_wake = minimum = 1; ++ } ++ } + continue; + } + __set_current_state(TASK_RUNNING); +diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c +index abfd990..6876af4 100644 +--- a/drivers/tty/pty.c ++++ b/drivers/tty/pty.c +@@ -66,6 +66,13 @@ static void pty_close(struct tty_struct *tty, struct file *filp) + tty_unlock(tty); + tty_vhangup(tty->link); + tty_lock(tty); ++ } else { ++ spin_lock_irq(&tty->ctrl_lock); ++ put_pid(tty->session); ++ put_pid(tty->pgrp); ++ tty->session = NULL; ++ tty->pgrp = NULL; ++ spin_unlock_irq(&tty->ctrl_lock); + } + } + +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index 6464029..167219e 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -877,13 +877,12 @@ void disassociate_ctty(int on_exit) + + tty = get_current_tty(); + if (tty) { +- unsigned long flags; +- spin_lock_irqsave(&tty->ctrl_lock, flags); ++ spin_lock_irq(&tty->ctrl_lock); + put_pid(tty->session); + put_pid(tty->pgrp); + tty->session = NULL; + tty->pgrp = NULL; +- spin_unlock_irqrestore(&tty->ctrl_lock, flags); ++ spin_unlock_irq(&tty->ctrl_lock); + tty_kref_put(tty); + } else { + #ifdef TTY_DEBUG_HANGUP