root/drivers/char/n_tty.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. put_tty_queue
  2. n_tty_flush_buffer
  3. n_tty_chars_in_buffer
  4. opost
  5. put_char
  6. echo_char
  7. finish_erasing
  8. eraser
  9. isig
  10. n_tty_receive_break
  11. n_tty_receive_overrun
  12. n_tty_receive_parity_error
  13. n_tty_receive_char
  14. n_tty_receive_buf
  15. n_tty_receive_room
  16. is_ignored
  17. n_tty_set_termios
  18. n_tty_close
  19. n_tty_open
  20. input_available_p
  21. copy_from_read_buf
  22. read_chan
  23. write_chan
  24. normal_select

   1 /*
   2  * n_tty.c --- implements the N_TTY line discipline.
   3  * 
   4  * This code used to be in tty_io.c, but things are getting hairy
   5  * enough that it made sense to split things off.  (The N_TTY
   6  * processing has changed so much that it's hardly recognizable,
   7  * anyway...)
   8  *
   9  * Note that the open routine for N_TTY is guaranteed never to return
  10  * an error.  This is because Linux will fall back to setting a line
  11  * to N_TTY if it can not switch to any other line discipline.  
  12  *
  13  * Written by Theodore Ts'o, Copyright 1994.
  14  * 
  15  * This file also contains code originally written by Linus Torvalds,
  16  * Copyright 1991, 1992, 1993, and by Julian Cowley, Copyright 1994.
  17  * 
  18  * This file may be redistributed under the terms of the GNU Public
  19  * License.
  20  */
  21 
  22 #include <linux/types.h>
  23 #include <linux/major.h>
  24 #include <linux/errno.h>
  25 #include <linux/signal.h>
  26 #include <linux/fcntl.h>
  27 #include <linux/sched.h>
  28 #include <linux/interrupt.h>
  29 #include <linux/tty.h>
  30 #include <linux/timer.h>
  31 #include <linux/ctype.h>
  32 #include <linux/kd.h>
  33 #include <linux/mm.h>
  34 #include <linux/string.h>
  35 #include <linux/malloc.h>
  36 
  37 #include <asm/segment.h>
  38 #include <asm/system.h>
  39 #include <asm/bitops.h>
  40 
  41 #define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
  42 
  43 #ifndef MIN
  44 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
  45 #endif
  46 
  47 /* number of characters left in xmit buffer before select has we have room */
  48 #define WAKEUP_CHARS 256
  49 
  50 /*
  51  * This defines the low- and high-watermarks for throttling and
  52  * unthrottling the TTY driver.  These watermarks are used for
  53  * controlling the space in the read buffer.
  54  */
  55 #define TTY_THRESHOLD_THROTTLE          (N_TTY_BUF_SIZE - 128)
  56 #define TTY_THRESHOLD_UNTHROTTLE        128
  57 
  58 static inline void put_tty_queue(unsigned char c, struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60         if (tty->read_cnt < N_TTY_BUF_SIZE) {
  61                 tty->read_buf[tty->read_head] = c;
  62                 tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1);
  63                 tty->read_cnt++;
  64         }
  65 }
  66 
  67 /*
  68  * Flush the input buffer
  69  */
  70 void n_tty_flush_buffer(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72         tty->read_head = tty->read_tail = tty->read_cnt = 0;
  73         tty->canon_head = tty->canon_data = tty->erasing = 0;
  74         memset(&tty->read_flags, 0, sizeof tty->read_flags);
  75         
  76         if (!tty->link)
  77                 return;
  78 
  79         if (tty->driver.unthrottle)
  80                 (tty->driver.unthrottle)(tty);
  81         if (tty->link->packet) {
  82                 tty->ctrl_status |= TIOCPKT_FLUSHREAD;
  83                 wake_up_interruptible(&tty->link->read_wait);
  84         }
  85 }
  86 
  87 /*
  88  * Return number of characters buffered to be delivered to user
  89  */
  90 int n_tty_chars_in_buffer(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92         return tty->read_cnt;
  93 }
  94 
  95 /*
  96  * Perform OPOST processing.  Returns -1 when the output device is
  97  * full and the character must be retried.
  98  */
  99 static int opost(unsigned char c, struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 100 {
 101         int     space, spaces;
 102 
 103         space = tty->driver.write_room(tty);
 104         if (!space)
 105                 return -1;
 106 
 107         if (O_OPOST(tty)) {
 108                 switch (c) {
 109                 case '\n':
 110                         if (O_ONLRET(tty))
 111                                 tty->column = 0;
 112                         if (O_ONLCR(tty)) {
 113                                 if (space < 2)
 114                                         return -1;
 115                                 tty->driver.put_char(tty, '\r');
 116                                 tty->column = 0;
 117                         }
 118                         tty->canon_column = tty->column;
 119                         break;
 120                 case '\r':
 121                         if (O_ONOCR(tty) && tty->column == 0)
 122                                 return 0;
 123                         if (O_OCRNL(tty)) {
 124                                 c = '\n';
 125                                 if (O_ONLRET(tty))
 126                                         tty->canon_column = tty->column = 0;
 127                                 break;
 128                         }
 129                         tty->canon_column = tty->column = 0;
 130                         break;
 131                 case '\t':
 132                         spaces = 8 - (tty->column & 7);
 133                         if (O_TABDLY(tty) == XTABS) {
 134                                 if (space < spaces)
 135                                         return -1;
 136                                 tty->column += spaces;
 137                                 tty->driver.write(tty, 0, "        ", spaces);
 138                                 return 0;
 139                         }
 140                         tty->column += spaces;
 141                         break;
 142                 case '\b':
 143                         if (tty->column > 0)
 144                                 tty->column--;
 145                         break;
 146                 default:
 147                         if (O_OLCUC(tty))
 148                                 c = toupper(c);
 149                         if (!iscntrl(c))
 150                                 tty->column++;
 151                         break;
 152                 }
 153         }
 154         tty->driver.put_char(tty, c);
 155         return 0;
 156 }
 157 
 158 static inline void put_char(unsigned char c, struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160         tty->driver.put_char(tty, c);
 161 }
 162 
 163 /* Must be called only when L_ECHO(tty) is true. */
 164 
 165 static void echo_char(unsigned char c, struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167         if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') {
 168                 put_char('^', tty);
 169                 put_char(c ^ 0100, tty);
 170                 tty->column += 2;
 171         } else
 172                 opost(c, tty);
 173 }
 174 
 175 static inline void finish_erasing(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177         if (tty->erasing) {
 178                 put_char('/', tty);
 179                 tty->column += 2;
 180                 tty->erasing = 0;
 181         }
 182 }
 183 
 184 static void eraser(unsigned char c, struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 185 {
 186         enum { ERASE, WERASE, KILL } kill_type;
 187         int head, seen_alnums;
 188 
 189         if (tty->read_head == tty->canon_head) {
 190                 /* opost('\a', tty); */         /* what do you think? */
 191                 return;
 192         }
 193         if (c == ERASE_CHAR(tty))
 194                 kill_type = ERASE;
 195         else if (c == WERASE_CHAR(tty))
 196                 kill_type = WERASE;
 197         else {
 198                 if (!L_ECHO(tty)) {
 199                         tty->read_cnt -= ((tty->read_head - tty->canon_head) &
 200                                           (N_TTY_BUF_SIZE - 1));
 201                         tty->read_head = tty->canon_head;
 202                         return;
 203                 }
 204                 if (!L_ECHOK(tty) || !L_ECHOKE(tty)) {
 205                         tty->read_cnt -= ((tty->read_head - tty->canon_head) &
 206                                           (N_TTY_BUF_SIZE - 1));
 207                         tty->read_head = tty->canon_head;
 208                         finish_erasing(tty);
 209                         echo_char(KILL_CHAR(tty), tty);
 210                         /* Add a newline if ECHOK is on and ECHOKE is off. */
 211                         if (L_ECHOK(tty))
 212                                 opost('\n', tty);
 213                         return;
 214                 }
 215                 kill_type = KILL;
 216         }
 217 
 218         seen_alnums = 0;
 219         while (tty->read_head != tty->canon_head) {
 220                 head = (tty->read_head - 1) & (N_TTY_BUF_SIZE-1);
 221                 c = tty->read_buf[head];
 222                 if (kill_type == WERASE) {
 223                         /* Equivalent to BSD's ALTWERASE. */
 224                         if (isalnum(c) || c == '_')
 225                                 seen_alnums++;
 226                         else if (seen_alnums)
 227                                 break;
 228                 }
 229                 tty->read_head = head;
 230                 tty->read_cnt--;
 231                 if (L_ECHO(tty)) {
 232                         if (L_ECHOPRT(tty)) {
 233                                 if (!tty->erasing) {
 234                                         put_char('\\', tty);
 235                                         tty->column++;
 236                                         tty->erasing = 1;
 237                                 }
 238                                 echo_char(c, tty);
 239                         } else if (!L_ECHOE(tty)) {
 240                                 echo_char(ERASE_CHAR(tty), tty);
 241                         } else if (c == '\t') {
 242                                 unsigned int col = tty->canon_column;
 243                                 unsigned long tail = tty->canon_head;
 244 
 245                                 /* Find the column of the last char. */
 246                                 while (tail != tty->read_head) {
 247                                         c = tty->read_buf[tail];
 248                                         if (c == '\t')
 249                                                 col = (col | 7) + 1;
 250                                         else if (iscntrl(c)) {
 251                                                 if (L_ECHOCTL(tty))
 252                                                         col += 2;
 253                                         } else
 254                                                 col++;
 255                                         tail = (tail+1) & (N_TTY_BUF_SIZE-1);
 256                                 }
 257 
 258                                 /* Now backup to that column. */
 259                                 while (tty->column > col) {
 260                                         /* Can't use opost here. */
 261                                         put_char('\b', tty);
 262                                         tty->column--;
 263                                 }
 264                         } else {
 265                                 if (iscntrl(c) && L_ECHOCTL(tty)) {
 266                                         put_char('\b', tty);
 267                                         put_char(' ', tty);
 268                                         put_char('\b', tty);
 269                                         tty->column--;
 270                                 }
 271                                 if (!iscntrl(c) || L_ECHOCTL(tty)) {
 272                                         put_char('\b', tty);
 273                                         put_char(' ', tty);
 274                                         put_char('\b', tty);
 275                                         tty->column--;
 276                                 }
 277                         }
 278                 }
 279                 if (kill_type == ERASE)
 280                         break;
 281         }
 282         if (tty->read_head == tty->canon_head)
 283                 finish_erasing(tty);
 284 }
 285 
 286 static void isig(int sig, struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 287 {
 288         if (tty->pgrp > 0)
 289                 kill_pg(tty->pgrp, sig, 1);
 290         if (!L_NOFLSH(tty)) {
 291                 n_tty_flush_buffer(tty);
 292                 if (tty->driver.flush_buffer)
 293                         tty->driver.flush_buffer(tty);
 294         }
 295 }
 296 
 297 static inline void n_tty_receive_break(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 298 {
 299         if (I_IGNBRK(tty))
 300                 return;
 301         if (I_BRKINT(tty)) {
 302                 isig(SIGINT, tty);
 303                 return;
 304         }
 305         if (I_PARMRK(tty)) {
 306                 put_tty_queue('\377', tty);
 307                 put_tty_queue('\0', tty);
 308         }
 309         put_tty_queue('\0', tty);
 310         wake_up_interruptible(&tty->read_wait);
 311 }
 312 
 313 static inline void n_tty_receive_overrun(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 314 {
 315         char buf[64];
 316 
 317         tty->num_overrun++;
 318         if (tty->overrun_time < (jiffies - HZ)) {
 319                 printk("%s: %d input overrun(s)\n", _tty_name(tty, buf),
 320                        tty->num_overrun);
 321                 tty->overrun_time = jiffies;
 322                 tty->num_overrun = 0;
 323         }
 324 }
 325 
 326 static inline void n_tty_receive_parity_error(struct tty_struct *tty,
     /* [previous][next][first][last][top][bottom][index][help] */
 327                                               unsigned char c)
 328 {
 329         if (I_IGNPAR(tty)) {
 330                 return;
 331         }
 332         if (I_PARMRK(tty)) {
 333                 put_tty_queue('\377', tty);
 334                 put_tty_queue('\0', tty);
 335                 put_tty_queue(c, tty);
 336         } else
 337                 put_tty_queue('\0', tty);
 338         wake_up_interruptible(&tty->read_wait);
 339 }
 340 
 341 static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 342 {
 343         if (tty->raw) {
 344                 put_tty_queue(c, tty);
 345                 return;
 346         }
 347         
 348         if (tty->stopped && I_IXON(tty) && I_IXANY(tty)) {
 349                 start_tty(tty);
 350                 return;
 351         }
 352         
 353         if (I_ISTRIP(tty))
 354                 c &= 0x7f;
 355         if (I_IUCLC(tty) && L_IEXTEN(tty))
 356                 c=tolower(c);
 357 
 358         if (tty->closing) {
 359                 if (I_IXON(tty)) {
 360                         if (c == START_CHAR(tty))
 361                                 start_tty(tty);
 362                         else if (c == STOP_CHAR(tty))
 363                                 stop_tty(tty);
 364                 }
 365                 return;
 366         }
 367 
 368         /*
 369          * If the previous character was LNEXT, or we know that this
 370          * character is not one of the characters that we'll have to
 371          * handle specially, do shortcut processing to speed things
 372          * up.
 373          */
 374         if (!test_bit(c, &tty->process_char_map) || tty->lnext) {
 375                 finish_erasing(tty);
 376                 tty->lnext = 0;
 377                 if (L_ECHO(tty)) {
 378                         if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
 379                                 put_char('\a', tty); /* beep if no space */
 380                                 return;
 381                         }
 382                         /* Record the column of first canon char. */
 383                         if (tty->canon_head == tty->read_head)
 384                                 tty->canon_column = tty->column;
 385                         echo_char(c, tty);
 386                 }
 387                 if (I_PARMRK(tty) && c == (unsigned char) '\377')
 388                         put_tty_queue(c, tty);
 389                 put_tty_queue(c, tty);
 390                 return;
 391         }
 392                 
 393         if (c == '\r') {
 394                 if (I_IGNCR(tty))
 395                         return;
 396                 if (I_ICRNL(tty))
 397                         c = '\n';
 398         } else if (c == '\n' && I_INLCR(tty))
 399                 c = '\r';
 400         if (I_IXON(tty)) {
 401                 if (c == START_CHAR(tty)) {
 402                         start_tty(tty);
 403                         return;
 404                 }
 405                 if (c == STOP_CHAR(tty)) {
 406                         stop_tty(tty);
 407                         return;
 408                 }
 409         }
 410         if (L_ISIG(tty)) {
 411                 if (c == INTR_CHAR(tty)) {
 412                         isig(SIGINT, tty);
 413                         return;
 414                 }
 415                 if (c == QUIT_CHAR(tty)) {
 416                         isig(SIGQUIT, tty);
 417                         return;
 418                 }
 419                 if (c == SUSP_CHAR(tty)) {
 420                         if (!is_orphaned_pgrp(tty->pgrp))
 421                                 isig(SIGTSTP, tty);
 422                         return;
 423                 }
 424         }
 425         if (L_ICANON(tty)) {
 426                 if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
 427                     (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
 428                         eraser(c, tty);
 429                         return;
 430                 }
 431                 if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
 432                         tty->lnext = 1;
 433                         if (L_ECHO(tty)) {
 434                                 finish_erasing(tty);
 435                                 if (L_ECHOCTL(tty)) {
 436                                         put_char('^', tty);
 437                                         put_char('\b', tty);
 438                                 }
 439                         }
 440                         return;
 441                 }
 442                 if (c == REPRINT_CHAR(tty) && L_ECHO(tty) &&
 443                     L_IEXTEN(tty)) {
 444                         unsigned long tail = tty->canon_head;
 445 
 446                         finish_erasing(tty);
 447                         echo_char(c, tty);
 448                         opost('\n', tty);
 449                         while (tail != tty->read_head) {
 450                                 echo_char(tty->read_buf[tail], tty);
 451                                 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
 452                         }
 453                         return;
 454                 }
 455                 if (c == '\n') {
 456                         if (L_ECHO(tty) || L_ECHONL(tty)) {
 457                                 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
 458                                         put_char('\a', tty);
 459                                         return;
 460                                 }
 461                                 opost('\n', tty);
 462                         }
 463                         goto handle_newline;
 464                 }
 465                 if (c == EOF_CHAR(tty)) {
 466                         if (tty->canon_head != tty->read_head)
 467                                 set_bit(TTY_PUSH, &tty->flags);
 468                         c = __DISABLED_CHAR;
 469                         goto handle_newline;
 470                 }
 471                 if ((c == EOL_CHAR(tty)) ||
 472                     (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
 473                         /*
 474                          * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
 475                          */
 476                         if (L_ECHO(tty)) {
 477                                 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
 478                                         put_char('\a', tty);
 479                                         return;
 480                                 }
 481                                 /* Record the column of first canon char. */
 482                                 if (tty->canon_head == tty->read_head)
 483                                         tty->canon_column = tty->column;
 484                                 echo_char(c, tty);
 485                         }
 486                         /*
 487                          * XXX does PARMRK doubling happen for
 488                          * EOL_CHAR and EOL2_CHAR?
 489                          */
 490                         if (I_PARMRK(tty) && c == (unsigned char) '\377')
 491                                 put_tty_queue(c, tty);
 492 
 493                 handle_newline:
 494                         set_bit(tty->read_head, &tty->read_flags);
 495                         put_tty_queue(c, tty);
 496                         tty->canon_head = tty->read_head;
 497                         tty->canon_data++;
 498                         if (tty->fasync)
 499                                 kill_fasync(tty->fasync, SIGIO);
 500                         if (tty->read_wait)
 501                                 wake_up_interruptible(&tty->read_wait);
 502                         return;
 503                 }
 504         }
 505         
 506         finish_erasing(tty);
 507         if (L_ECHO(tty)) {
 508                 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
 509                         put_char('\a', tty); /* beep if no space */
 510                         return;
 511                 }
 512                 if (c == '\n')
 513                         opost('\n', tty);
 514                 else {
 515                         /* Record the column of first canon char. */
 516                         if (tty->canon_head == tty->read_head)
 517                                 tty->canon_column = tty->column;
 518                         echo_char(c, tty);
 519                 }
 520         }
 521 
 522         if (I_PARMRK(tty) && c == (unsigned char) '\377')
 523                 put_tty_queue(c, tty);
 524 
 525         put_tty_queue(c, tty);
 526 }       
 527 
 528 static void n_tty_receive_buf(struct tty_struct *tty, unsigned char *cp,
     /* [previous][next][first][last][top][bottom][index][help] */
 529                               char *fp, int count)
 530 {
 531         unsigned char *p;
 532         char *f, flags = 0;
 533         int     i;
 534 
 535         if (!tty->read_buf)
 536                 return;
 537 
 538         if (tty->real_raw) {
 539                 i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
 540                                    N_TTY_BUF_SIZE - tty->read_head));
 541                 memcpy(tty->read_buf + tty->read_head, cp, i);
 542                 tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
 543                 tty->read_cnt += i;
 544                 cp += i;
 545                 count -= i;
 546 
 547                 i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
 548                                N_TTY_BUF_SIZE - tty->read_head));
 549                 memcpy(tty->read_buf + tty->read_head, cp, i);
 550                 tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
 551                 tty->read_cnt += i;
 552         } else {
 553                 for (i=count, p = cp, f = fp; i; i--, p++) {
 554                         if (f)
 555                                 flags = *f++;
 556                         switch (flags) {
 557                         case TTY_NORMAL:
 558                                 n_tty_receive_char(tty, *p);
 559                                 break;
 560                         case TTY_BREAK:
 561                                 n_tty_receive_break(tty);
 562                                 break;
 563                         case TTY_PARITY:
 564                         case TTY_FRAME:
 565                                 n_tty_receive_parity_error(tty, *p);
 566                                 break;
 567                         case TTY_OVERRUN:
 568                                 n_tty_receive_overrun(tty);
 569                                 break;
 570                         default:
 571                                 printk("%s: unknown flag %d\n", tty_name(tty),
 572                                        flags);
 573                                 break;
 574                         }
 575                 }
 576                 if (tty->driver.flush_chars)
 577                         tty->driver.flush_chars(tty);
 578         }
 579 
 580         if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
 581                 if (tty->fasync)
 582                         kill_fasync(tty->fasync, SIGIO);
 583                 if (tty->read_wait)
 584                         wake_up_interruptible(&tty->read_wait);
 585         }
 586 
 587         if ((tty->read_cnt >= TTY_THRESHOLD_THROTTLE) &&
 588             tty->driver.throttle &&
 589             !set_bit(TTY_THROTTLED, &tty->flags))
 590                 tty->driver.throttle(tty);
 591 }
 592 
 593 static int n_tty_receive_room(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 594 {
 595         int     left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
 596 
 597         /*
 598          * If we are doing input canonicalization, and there are no
 599          * pending newlines, let characters through without limit, so
 600          * that erase characters will be handled.  Other excess
 601          * characters will be beeped.
 602          */
 603         if (tty->icanon && !tty->canon_data)
 604                 return N_TTY_BUF_SIZE;
 605 
 606         if (left > 0)
 607                 return left;
 608         return 0;
 609 }
 610 
 611 int is_ignored(int sig)
     /* [previous][next][first][last][top][bottom][index][help] */
 612 {
 613         return ((current->blocked & (1<<(sig-1))) ||
 614                 (current->sigaction[sig-1].sa_handler == SIG_IGN));
 615 }
 616 
 617 static void n_tty_set_termios(struct tty_struct *tty, struct termios * old)
     /* [previous][next][first][last][top][bottom][index][help] */
 618 {
 619         if (!tty)
 620                 return;
 621         
 622         tty->icanon = (L_ICANON(tty) != 0);
 623         if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
 624             I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
 625             I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
 626             I_PARMRK(tty)) {
 627                 cli();
 628                 memset(tty->process_char_map, 0, 256/8);
 629 
 630                 if (I_IGNCR(tty) || I_ICRNL(tty))
 631                         set_bit('\r', &tty->process_char_map);
 632                 if (I_INLCR(tty))
 633                         set_bit('\n', &tty->process_char_map);
 634 
 635                 if (L_ICANON(tty)) {
 636                         set_bit(ERASE_CHAR(tty), &tty->process_char_map);
 637                         set_bit(KILL_CHAR(tty), &tty->process_char_map);
 638                         set_bit(EOF_CHAR(tty), &tty->process_char_map);
 639                         set_bit('\n', &tty->process_char_map);
 640                         set_bit(EOL_CHAR(tty), &tty->process_char_map);
 641                         if (L_IEXTEN(tty)) {
 642                                 set_bit(WERASE_CHAR(tty),
 643                                         &tty->process_char_map);
 644                                 set_bit(LNEXT_CHAR(tty),
 645                                         &tty->process_char_map);
 646                                 set_bit(EOL2_CHAR(tty),
 647                                         &tty->process_char_map);
 648                                 if (L_ECHO(tty))
 649                                         set_bit(REPRINT_CHAR(tty),
 650                                                 &tty->process_char_map);
 651                         }
 652                 }
 653                 if (I_IXON(tty)) {
 654                         set_bit(START_CHAR(tty), &tty->process_char_map);
 655                         set_bit(STOP_CHAR(tty), &tty->process_char_map);
 656                 }
 657                 if (L_ISIG(tty)) {
 658                         set_bit(INTR_CHAR(tty), &tty->process_char_map);
 659                         set_bit(QUIT_CHAR(tty), &tty->process_char_map);
 660                         set_bit(SUSP_CHAR(tty), &tty->process_char_map);
 661                 }
 662                 clear_bit(__DISABLED_CHAR, &tty->process_char_map);
 663                 sti();
 664                 tty->raw = 0;
 665                 tty->real_raw = 0;
 666         } else {
 667                 tty->raw = 1;
 668                 if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) &&
 669                     (I_IGNPAR(tty) || !I_INPCK(tty)) &&
 670                     (tty->driver.flags & TTY_DRIVER_REAL_RAW))
 671                         tty->real_raw = 1;
 672                 else
 673                         tty->real_raw = 0;
 674         }
 675 }
 676 
 677 static void n_tty_close(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 678 {
 679         n_tty_flush_buffer(tty);
 680         if (tty->read_buf) {
 681                 free_page((unsigned long) tty->read_buf);
 682                 tty->read_buf = 0;
 683         }
 684 }
 685 
 686 static int n_tty_open(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 687 {
 688         if (!tty)
 689                 return -EINVAL;
 690 
 691         if (!tty->read_buf) {
 692                 tty->read_buf = (unsigned char *)
 693                         get_free_page(intr_count ? GFP_ATOMIC : GFP_KERNEL);
 694                 if (!tty->read_buf)
 695                         return -ENOMEM;
 696         }
 697         memset(tty->read_buf, 0, N_TTY_BUF_SIZE);
 698         tty->read_head = tty->read_tail = tty->read_cnt = 0;
 699         memset(tty->read_flags, 0, sizeof(tty->read_flags));
 700         n_tty_set_termios(tty, 0);
 701         tty->minimum_to_wake = 1;
 702         tty->closing = 0;
 703         return 0;
 704 }
 705 
 706 static inline int input_available_p(struct tty_struct *tty, int amt)
     /* [previous][next][first][last][top][bottom][index][help] */
 707 {
 708         if (L_ICANON(tty)) {
 709                 if (tty->canon_data)
 710                         return 1;
 711         } else if (tty->read_cnt >= (amt ? amt : 1))
 712                 return 1;
 713 
 714         return 0;
 715 }
 716 
 717 /*
 718  * Helper function to speed up read_chan.  It is only called when
 719  * ICANON is off; it copies characters straight from the tty queue to
 720  * user space directly.  It can be profitably called twice; once to
 721  * drain the space from the tail pointer to the (physical) end of the
 722  * buffer, and once to drain the space from the (physical) beginning of
 723  * the buffer to head pointer.
 724  */
 725 static inline void copy_from_read_buf(struct tty_struct *tty,
     /* [previous][next][first][last][top][bottom][index][help] */
 726                                       unsigned char **b,
 727                                       unsigned int *nr)
 728 
 729 {
 730         int     n;
 731 
 732         n = MIN(*nr, MIN(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail));
 733         if (!n)
 734                 return;
 735         memcpy_tofs(*b, &tty->read_buf[tty->read_tail], n);
 736         tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
 737         tty->read_cnt -= n;
 738         *b += n;
 739         *nr -= n;
 740 }
 741 
 742 static int read_chan(struct tty_struct *tty, struct file *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 743                      unsigned char *buf, unsigned int nr)
 744 {
 745         struct wait_queue wait = { current, NULL };
 746         int c;
 747         unsigned char *b = buf;
 748         int minimum, time;
 749         int retval = 0;
 750         int size;
 751 
 752 do_it_again:
 753 
 754         if (!tty->read_buf) {
 755                 printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
 756                 return -EIO;
 757         }
 758 
 759         /* Job control check -- must be done at start and after
 760            every sleep (POSIX.1 7.1.1.4). */
 761         /* NOTE: not yet done after every sleep pending a thorough
 762            check of the logic of this change. -- jlc */
 763         /* don't stop on /dev/console */
 764         if (file->f_inode->i_rdev != CONSOLE_DEV &&
 765             current->tty == tty) {
 766                 if (tty->pgrp <= 0)
 767                         printk("read_chan: tty->pgrp <= 0!\n");
 768                 else if (current->pgrp != tty->pgrp) {
 769                         if (is_ignored(SIGTTIN) ||
 770                             is_orphaned_pgrp(current->pgrp))
 771                                 return -EIO;
 772                         kill_pg(current->pgrp, SIGTTIN, 1);
 773                         return -ERESTARTSYS;
 774                 }
 775         }
 776 
 777         if (L_ICANON(tty)) {
 778                 minimum = time = 0;
 779                 current->timeout = (unsigned long) -1;
 780         } else {
 781                 time = (HZ / 10) * TIME_CHAR(tty);
 782                 minimum = MIN_CHAR(tty);
 783                 if (minimum) {
 784                         current->timeout = (unsigned long) -1;
 785                         if (time)
 786                                 tty->minimum_to_wake = 1;
 787                         else if (!tty->read_wait ||
 788                                  (tty->minimum_to_wake > minimum))
 789                                 tty->minimum_to_wake = minimum;
 790                 } else {
 791                         if (time) {
 792                                 current->timeout = time + jiffies;
 793                                 time = 0;
 794                         } else
 795                                 current->timeout = 0;
 796                         tty->minimum_to_wake = minimum = 1;
 797                 }
 798         }
 799 
 800         add_wait_queue(&tty->read_wait, &wait);
 801         while (1) {
 802                 /* First test for status change. */
 803                 if (tty->packet && tty->link->ctrl_status) {
 804                         if (b != buf)
 805                                 break;
 806                         put_user(tty->link->ctrl_status, b++);
 807                         tty->link->ctrl_status = 0;
 808                         break;
 809                 }
 810                 /* This statement must be first before checking for input
 811                    so that any interrupt will set the state back to
 812                    TASK_RUNNING. */
 813                 current->state = TASK_INTERRUPTIBLE;
 814                 
 815                 if (((minimum - (b - buf)) < tty->minimum_to_wake) &&
 816                     ((minimum - (b - buf)) >= 1))
 817                         tty->minimum_to_wake = (minimum - (b - buf));
 818                 
 819                 if (!input_available_p(tty, 0)) {
 820                         if (tty->flags & (1 << TTY_SLAVE_CLOSED)) {
 821                                 retval = -EIO;
 822                                 break;
 823                         }
 824                         if (tty_hung_up_p(file))
 825                                 break;
 826                         if (!current->timeout)
 827                                 break;
 828                         if (file->f_flags & O_NONBLOCK) {
 829                                 retval = -EAGAIN;
 830                                 break;
 831                         }
 832                         if (current->signal & ~current->blocked) {
 833                                 retval = -ERESTARTSYS;
 834                                 break;
 835                         }
 836                         schedule();
 837                         continue;
 838                 }
 839                 current->state = TASK_RUNNING;
 840 
 841                 /* Deal with packet mode. */
 842                 if (tty->packet && b == buf) {
 843                         put_user(TIOCPKT_DATA, b++);
 844                         nr--;
 845                 }
 846 
 847                 if (L_ICANON(tty)) {
 848                         while (1) {
 849                                 int eol;
 850 
 851                                 disable_bh(TQUEUE_BH);
 852                                 if (!tty->read_cnt) {
 853                                         enable_bh(TQUEUE_BH);
 854                                         break;
 855                                 }
 856                                 eol = clear_bit(tty->read_tail,
 857                                                 &tty->read_flags);
 858                                 c = tty->read_buf[tty->read_tail];
 859                                 tty->read_tail = ((tty->read_tail+1) &
 860                                                   (N_TTY_BUF_SIZE-1));
 861                                 tty->read_cnt--;
 862                                 enable_bh(TQUEUE_BH);
 863                                 if (!eol) {
 864                                         put_user(c, b++);
 865                                         if (--nr)
 866                                                 continue;
 867                                         break;
 868                                 }
 869                                 if (--tty->canon_data < 0) {
 870                                         tty->canon_data = 0;
 871                                 }
 872                                 if (c != __DISABLED_CHAR) {
 873                                         put_user(c, b++);
 874                                         nr--;
 875                                 }
 876                                 break;
 877                         }
 878                 } else {
 879                         disable_bh(TQUEUE_BH);
 880                         copy_from_read_buf(tty, &b, &nr);
 881                         copy_from_read_buf(tty, &b, &nr);
 882                         enable_bh(TQUEUE_BH);
 883                 }
 884 
 885                 /* If there is enough space in the read buffer now, let the
 886                    low-level driver know. */
 887                 if (tty->driver.unthrottle &&
 888                     (tty->read_cnt <= TTY_THRESHOLD_UNTHROTTLE)
 889                     && clear_bit(TTY_THROTTLED, &tty->flags))
 890                         tty->driver.unthrottle(tty);
 891 
 892                 if (b - buf >= minimum || !nr)
 893                         break;
 894                 if (time)
 895                         current->timeout = time + jiffies;
 896         }
 897         remove_wait_queue(&tty->read_wait, &wait);
 898 
 899         if (!tty->read_wait)
 900                 tty->minimum_to_wake = minimum;
 901 
 902         current->state = TASK_RUNNING;
 903         current->timeout = 0;
 904         size = b - buf;
 905         if (size && nr)
 906                 clear_bit(TTY_PUSH, &tty->flags);
 907         if (!size && clear_bit(TTY_PUSH, &tty->flags))
 908                 goto do_it_again;
 909         if (!size && !retval)
 910                 clear_bit(TTY_PUSH, &tty->flags);
 911         return (size ? size : retval);
 912 }
 913 
 914 static int write_chan(struct tty_struct * tty, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
 915                       unsigned char * buf, unsigned int nr)
 916 {
 917         struct wait_queue wait = { current, NULL };
 918         int c;
 919         unsigned char *b = buf;
 920         int retval = 0;
 921 
 922         /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
 923         if (L_TOSTOP(tty) && file->f_inode->i_rdev != CONSOLE_DEV) {
 924                 retval = tty_check_change(tty);
 925                 if (retval)
 926                         return retval;
 927         }
 928 
 929         add_wait_queue(&tty->write_wait, &wait);
 930         while (1) {
 931                 current->state = TASK_INTERRUPTIBLE;
 932                 if (current->signal & ~current->blocked) {
 933                         retval = -ERESTARTSYS;
 934                         break;
 935                 }
 936                 if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
 937                         retval = -EIO;
 938                         break;
 939                 }
 940                 if (O_OPOST(tty)) {
 941                         while (nr > 0) {
 942                                 c = get_user(b);
 943                                 if (opost(c, tty) < 0)
 944                                         break;
 945                                 b++; nr--;
 946                         }
 947                         if (tty->driver.flush_chars)
 948                                 tty->driver.flush_chars(tty);
 949                 } else {
 950                         c = tty->driver.write(tty, 1, b, nr);
 951                         b += c;
 952                         nr -= c;
 953                 }
 954                 if (!nr)
 955                         break;
 956                 if (file->f_flags & O_NONBLOCK) {
 957                         retval = -EAGAIN;
 958                         break;
 959                 }
 960                 schedule();
 961         }
 962         current->state = TASK_RUNNING;
 963         remove_wait_queue(&tty->write_wait, &wait);
 964         return (b - buf) ? b - buf : retval;
 965 }
 966 
 967 static int normal_select(struct tty_struct * tty, struct inode * inode,
     /* [previous][next][first][last][top][bottom][index][help] */
 968                          struct file * file, int sel_type, select_table *wait)
 969 {
 970         switch (sel_type) {
 971                 case SEL_IN:
 972                         if (input_available_p(tty, TIME_CHAR(tty) ? 0 :
 973                                               MIN_CHAR(tty)))
 974                                 return 1;
 975                         /* fall through */
 976                 case SEL_EX:
 977                         if (tty->packet && tty->link->ctrl_status)
 978                                 return 1;
 979                         if (tty->flags & (1 << TTY_SLAVE_CLOSED))
 980                                 return 1;
 981                         if (tty_hung_up_p(file))
 982                                 return 1;
 983                         if (!tty->read_wait) {
 984                                 if (MIN_CHAR(tty) && !TIME_CHAR(tty))
 985                                         tty->minimum_to_wake = MIN_CHAR(tty);
 986                                 else
 987                                         tty->minimum_to_wake = 1;
 988                         }
 989                         select_wait(&tty->read_wait, wait);
 990                         return 0;
 991                 case SEL_OUT:
 992                         if (tty->driver.chars_in_buffer(tty) < WAKEUP_CHARS)
 993                                 return 1;
 994                         select_wait(&tty->write_wait, wait);
 995                         return 0;
 996         }
 997         return 0;
 998 }
 999 
1000 struct tty_ldisc tty_ldisc_N_TTY = {
1001         TTY_LDISC_MAGIC,        /* magic */
1002         0,                      /* num */
1003         0,                      /* flags */
1004         n_tty_open,             /* open */
1005         n_tty_close,            /* close */
1006         n_tty_flush_buffer,     /* flush_buffer */
1007         n_tty_chars_in_buffer,  /* chars_in_buffer */
1008         read_chan,              /* read */
1009         write_chan,             /* write */
1010         n_tty_ioctl,            /* ioctl */
1011         n_tty_set_termios,      /* set_termios */
1012         normal_select,          /* select */
1013         n_tty_receive_buf,      /* receive_buf */
1014         n_tty_receive_room,     /* receive_room */
1015         0                       /* write_wakeup */
1016 };
1017 

/* [previous][next][first][last][top][bottom][index][help] */