root/kernel/chr_drv/tty_ioctl.c

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

DEFINITIONS

This source file includes following definitions.
  1. change_speed
  2. flush
  3. wait_until_sent
  4. send_break
  5. get_termios
  6. set_termios
  7. get_termio
  8. set_termio
  9. tty_ioctl

   1 /*
   2  *  linux/kernel/chr_drv/tty_ioctl.c
   3  *
   4  *  (C) 1991  Linus Torvalds
   5  */
   6 
   7 #include <errno.h>
   8 #include <termios.h>
   9 
  10 #include <linux/sched.h>
  11 #include <linux/kernel.h>
  12 #include <linux/tty.h>
  13 
  14 #include <asm/io.h>
  15 #include <asm/segment.h>
  16 #include <asm/system.h>
  17 
  18 static unsigned short quotient[] = {
  19         0, 2304, 1536, 1047, 857,
  20         768, 576, 384, 192, 96,
  21         64, 48, 24, 12, 6, 3
  22 };
  23 
  24 static void change_speed(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26         unsigned short port,quot;
  27 
  28         if (!(port = tty->read_q.data))
  29                 return;
  30         quot = quotient[tty->termios.c_cflag & CBAUD];
  31         cli();
  32         outb_p(0x80,port+3);            /* set DLAB */
  33         outb_p(quot & 0xff,port);       /* LS of divisor */
  34         outb_p(quot >> 8,port+1);       /* MS of divisor */
  35         outb(0x03,port+3);              /* reset DLAB */
  36         sti();
  37 }
  38 
  39 static void flush(struct tty_queue * queue)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41         cli();
  42         queue->head = queue->tail;
  43         sti();
  44 }
  45 
  46 static void wait_until_sent(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48         /* do nothing - not implemented */
  49 }
  50 
  51 static void send_break(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  52 {
  53         /* do nothing - not implemented */
  54 }
  55 
  56 static int get_termios(struct tty_struct * tty, struct termios * termios)
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58         int i;
  59 
  60         verify_area(termios, sizeof (*termios));
  61         for (i=0 ; i< (sizeof (*termios)) ; i++)
  62                 put_fs_byte( ((char *)&tty->termios)[i] , i+(char *)termios );
  63         return 0;
  64 }
  65 
  66 static int set_termios(struct tty_struct * tty, struct termios * termios)
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68         int i;
  69 
  70         for (i=0 ; i< (sizeof (*termios)) ; i++)
  71                 ((char *)&tty->termios)[i]=get_fs_byte(i+(char *)termios);
  72         change_speed(tty);
  73         return 0;
  74 }
  75 
  76 static int get_termio(struct tty_struct * tty, struct termio * termio)
     /* [previous][next][first][last][top][bottom][index][help] */
  77 {
  78         int i;
  79         struct termio tmp_termio;
  80 
  81         verify_area(termio, sizeof (*termio));
  82         tmp_termio.c_iflag = tty->termios.c_iflag;
  83         tmp_termio.c_oflag = tty->termios.c_oflag;
  84         tmp_termio.c_cflag = tty->termios.c_cflag;
  85         tmp_termio.c_lflag = tty->termios.c_lflag;
  86         tmp_termio.c_line = tty->termios.c_line;
  87         for(i=0 ; i < NCC ; i++)
  88                 tmp_termio.c_cc[i] = tty->termios.c_cc[i];
  89         for (i=0 ; i< (sizeof (*termio)) ; i++)
  90                 put_fs_byte( ((char *)&tmp_termio)[i] , i+(char *)termio );
  91         return 0;
  92 }
  93 
  94 /*
  95  * This only works as the 386 is low-byt-first
  96  */
  97 static int set_termio(struct tty_struct * tty, struct termio * termio)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99         int i;
 100         struct termio tmp_termio;
 101 
 102         for (i=0 ; i< (sizeof (*termio)) ; i++)
 103                 ((char *)&tmp_termio)[i]=get_fs_byte(i+(char *)termio);
 104         *(unsigned short *)&tty->termios.c_iflag = tmp_termio.c_iflag;
 105         *(unsigned short *)&tty->termios.c_oflag = tmp_termio.c_oflag;
 106         *(unsigned short *)&tty->termios.c_cflag = tmp_termio.c_cflag;
 107         *(unsigned short *)&tty->termios.c_lflag = tmp_termio.c_lflag;
 108         tty->termios.c_line = tmp_termio.c_line;
 109         for(i=0 ; i < NCC ; i++)
 110                 tty->termios.c_cc[i] = tmp_termio.c_cc[i];
 111         change_speed(tty);
 112         return 0;
 113 }
 114 
 115 int tty_ioctl(int dev, int cmd, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 116 {
 117         struct tty_struct * tty;
 118         if (MAJOR(dev) == 5) {
 119                 dev=current->tty;
 120                 if (dev<0)
 121                         panic("tty_ioctl: dev<0");
 122         } else
 123                 dev=MINOR(dev);
 124         tty = dev + tty_table;
 125         switch (cmd) {
 126                 case TCGETS:
 127                         return get_termios(tty,(struct termios *) arg);
 128                 case TCSETSF:
 129                         flush(&tty->read_q); /* fallthrough */
 130                 case TCSETSW:
 131                         wait_until_sent(tty); /* fallthrough */
 132                 case TCSETS:
 133                         return set_termios(tty,(struct termios *) arg);
 134                 case TCGETA:
 135                         return get_termio(tty,(struct termio *) arg);
 136                 case TCSETAF:
 137                         flush(&tty->read_q); /* fallthrough */
 138                 case TCSETAW:
 139                         wait_until_sent(tty); /* fallthrough */
 140                 case TCSETA:
 141                         return set_termio(tty,(struct termio *) arg);
 142                 case TCSBRK:
 143                         if (!arg) {
 144                                 wait_until_sent(tty);
 145                                 send_break(tty);
 146                         }
 147                         return 0;
 148                 case TCXONC:
 149                         return -EINVAL; /* not implemented */
 150                 case TCFLSH:
 151                         if (arg==0)
 152                                 flush(&tty->read_q);
 153                         else if (arg==1)
 154                                 flush(&tty->write_q);
 155                         else if (arg==2) {
 156                                 flush(&tty->read_q);
 157                                 flush(&tty->write_q);
 158                         } else
 159                                 return -EINVAL;
 160                         return 0;
 161                 case TIOCEXCL:
 162                         return -EINVAL; /* not implemented */
 163                 case TIOCNXCL:
 164                         return -EINVAL; /* not implemented */
 165                 case TIOCSCTTY:
 166                         return -EINVAL; /* set controlling term NI */
 167                 case TIOCGPGRP:
 168                         verify_area((void *) arg,4);
 169                         put_fs_long(tty->pgrp,(unsigned long *) arg);
 170                         return 0;
 171                 case TIOCSPGRP:
 172                         tty->pgrp=get_fs_long((unsigned long *) arg);
 173                         return 0;
 174                 case TIOCOUTQ:
 175                         verify_area((void *) arg,4);
 176                         put_fs_long(CHARS(tty->write_q),(unsigned long *) arg);
 177                         return 0;
 178                 case TIOCINQ:
 179                         verify_area((void *) arg,4);
 180                         put_fs_long(CHARS(tty->secondary),
 181                                 (unsigned long *) arg);
 182                         return 0;
 183                 case TIOCSTI:
 184                         return -EINVAL; /* not implemented */
 185                 case TIOCGWINSZ:
 186                         return -EINVAL; /* not implemented */
 187                 case TIOCSWINSZ:
 188                         return -EINVAL; /* not implemented */
 189                 case TIOCMGET:
 190                         return -EINVAL; /* not implemented */
 191                 case TIOCMBIS:
 192                         return -EINVAL; /* not implemented */
 193                 case TIOCMBIC:
 194                         return -EINVAL; /* not implemented */
 195                 case TIOCMSET:
 196                         return -EINVAL; /* not implemented */
 197                 case TIOCGSOFTCAR:
 198                         return -EINVAL; /* not implemented */
 199                 case TIOCSSOFTCAR:
 200                         return -EINVAL; /* not implemented */
 201                 default:
 202                         return -EINVAL;
 203         }
 204 }

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