drm/radeon: 9800 SE has only one quadpipe
[safe/jmp/linux-2.6] / drivers / char / n_tty.c
index 973be2f..bdae832 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/audit.h>
 #include <linux/file.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 
 #include <asm/system.h>
 
@@ -272,7 +273,8 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty)
  *
  *     This is a helper function that handles one output character
  *     (including special characters like TAB, CR, LF, etc.),
- *     putting the results in the tty driver's write buffer.
+ *     doing OPOST processing and putting the results in the
+ *     tty driver's write buffer.
  *
  *     Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY
  *     and NLDLY.  They simply aren't relevant in the world today.
@@ -300,8 +302,7 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
                        if (space < 2)
                                return -1;
                        tty->canon_column = tty->column = 0;
-                       tty_put_char(tty, '\r');
-                       tty_put_char(tty, c);
+                       tty->ops->write(tty, "\r\n", 2);
                        return 2;
                }
                tty->canon_column = tty->column;
@@ -351,8 +352,9 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
  *     @c: character (or partial unicode symbol)
  *     @tty: terminal device
  *
- *     Perform OPOST processing.  Returns -1 when the output device is
- *     full and the character must be retried.
+ *     Output one character with OPOST processing.
+ *     Returns -1 when the output device is full and the character
+ *     must be retried.
  *
  *     Locking: output_lock to protect column state and space left
  *              (also, this is called from n_tty_write under the
@@ -378,8 +380,11 @@ static int process_output(unsigned char c, struct tty_struct *tty)
 /**
  *     process_output_block            -       block post processor
  *     @tty: terminal device
- *     @inbuf: user buffer
- *     @nr: number of bytes
+ *     @buf: character buffer
+ *     @nr: number of bytes to output
+ *
+ *     Output a block of characters with OPOST processing.
+ *     Returns the number of characters output.
  *
  *     This path is used to speed up block console writes, among other
  *     things when processing blocks of output data. It handles only
@@ -572,33 +577,23 @@ static void process_echoes(struct tty_struct *tty)
                                break;
 
                        default:
-                               if (iscntrl(op)) {
-                                       if (L_ECHOCTL(tty)) {
-                                               /*
-                                                * Ensure there is enough space
-                                                * for the whole ctrl pair.
-                                                */
-                                               if (space < 2) {
-                                                       no_space_left = 1;
-                                                       break;
-                                               }
-                                               tty_put_char(tty, '^');
-                                               tty_put_char(tty, op ^ 0100);
-                                               tty->column += 2;
-                                               space -= 2;
-                                       } else {
-                                               if (!space) {
-                                                       no_space_left = 1;
-                                                       break;
-                                               }
-                                               tty_put_char(tty, op);
-                                               space--;
-                                       }
-                               }
                                /*
-                                * If above falls through, this was an
-                                * undefined op.
+                                * If the op is not a special byte code,
+                                * it is a ctrl char tagged to be echoed
+                                * as "^X" (where X is the letter
+                                * representing the control char).
+                                * Note that we must ensure there is
+                                * enough space for the whole ctrl pair.
+                                *
                                 */
+                               if (space < 2) {
+                                       no_space_left = 1;
+                                       break;
+                               }
+                               tty_put_char(tty, '^');
+                               tty_put_char(tty, op ^ 0100);
+                               tty->column += 2;
+                               space -= 2;
                                cp += 2;
                                nr -= 2;
                        }
@@ -606,12 +601,18 @@ static void process_echoes(struct tty_struct *tty)
                        if (no_space_left)
                                break;
                } else {
-                       int retval;
-
-                       retval = do_output_char(c, tty, space);
-                       if (retval < 0)
-                               break;
-                       space -= retval;
+                       if (O_OPOST(tty) &&
+                           !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
+                               int retval = do_output_char(c, tty, space);
+                               if (retval < 0)
+                                       break;
+                               space -= retval;
+                       } else {
+                               if (!space)
+                                       break;
+                               tty_put_char(tty, c);
+                               space -= 1;
+                       }
                        cp += 1;
                        nr -= 1;
                }
@@ -799,8 +800,8 @@ static void echo_char_raw(unsigned char c, struct tty_struct *tty)
  *     Echo user input back onto the screen. This must be called only when
  *     L_ECHO(tty) is true. Called from the driver receive_buf path.
  *
- *     This variant tags control characters to be possibly echoed as
- *     as "^X" (where X is the letter representing the control char).
+ *     This variant tags control characters to be echoed as "^X"
+ *     (where X is the letter representing the control char).
  *
  *     Locking: echo_lock to protect the echo buffer
  */
@@ -813,7 +814,7 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
                add_echo_byte(ECHO_OP_START, tty);
                add_echo_byte(ECHO_OP_START, tty);
        } else {
-               if (iscntrl(c) && c != '\t')
+               if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
                        add_echo_byte(ECHO_OP_START, tty);
                add_echo_byte(c, tty);
        }
@@ -2091,3 +2092,19 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = {
        .receive_buf     = n_tty_receive_buf,
        .write_wakeup    = n_tty_write_wakeup
 };
+
+/**
+ *     n_tty_inherit_ops       -       inherit N_TTY methods
+ *     @ops: struct tty_ldisc_ops where to save N_TTY methods
+ *
+ *     Used by a generic struct tty_ldisc_ops to easily inherit N_TTY
+ *     methods.
+ */
+
+void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
+{
+       *ops = tty_ldisc_N_TTY;
+       ops->owner = NULL;
+       ops->refcount = ops->flags = 0;
+}
+EXPORT_SYMBOL_GPL(n_tty_inherit_ops);