root/kernel/chr_drv/vt.c

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

DEFINITIONS

This source file includes following definitions.
  1. kiocsound
  2. vt_ioctl

   1 /*
   2  *  kernel/chr_drv/vt.c
   3  *
   4  *  (C) 1992 obz under the linux copyright
   5  */
   6 
   7 #include <errno.h>
   8 
   9 #include <sys/types.h>
  10 #include <sys/kd.h>
  11 #include <sys/vt.h>
  12 
  13 #include <asm/io.h>
  14 #include <asm/segment.h>
  15 
  16 #include <linux/sched.h>
  17 #include <linux/tty.h>
  18 #include <linux/kernel.h>
  19 
  20 #include "vt_kern.h"
  21 
  22 /*
  23  * console (vt and kd) routines, as defined by usl svr4 manual
  24  */
  25 
  26 struct vt_cons vt_cons[MAX_CONSOLES];
  27 
  28 extern int NR_CONSOLES;
  29 extern unsigned char kleds;
  30 extern unsigned char kraw;
  31 extern unsigned char ke0;
  32 
  33 extern int sys_ioperm(unsigned long from, unsigned long num, int on);
  34 extern void set_leds(void);
  35 
  36 /*
  37  * these are the valid i/o ports we're allowed to change. they map all the
  38  * video ports
  39  */
  40 #define GPFIRST 0x3b4
  41 #define GPLAST 0x3df
  42 #define GPNUM (GPLAST - GPFIRST + 1)
  43 
  44 /*
  45  * turns on sound of some freq. 0 turns it off.
  46  * stolen from console.c, so i'm not sure if its the correct interpretation
  47  */
  48 static int
  49 kiocsound(unsigned int freq)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51         if (freq == 0) {
  52                 /* disable counter 2 */
  53                 outb(inb_p(0x61)&0xFC, 0x61);
  54         }
  55         else {
  56                 /* enable counter 2 */
  57                 outb_p(inb_p(0x61)|3, 0x61);
  58                 /* set command for counter 2, 2 byte write */
  59                 outb_p(0xB6, 0x43);
  60                 /* select desired HZ */
  61                 outb_p(freq & 0xff, 0x42);
  62                 outb((freq >> 8) & 0xff, 0x42);
  63         }
  64         return 0;
  65 }
  66 
  67 /*
  68  * all the vt ioctls affect only consoles, so we reject all other ttys.
  69  * we also have the capability to modify any console, not just the fg_console.
  70  */
  71 int
  72 vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74         int console = dev ? dev - 1 : fg_console;
  75         unsigned char ucval;
  76 
  77         if (!IS_A_CONSOLE(dev) || console < 0 || console >= NR_CONSOLES)
  78                 return -EINVAL;
  79 
  80         switch (cmd) {
  81         case KIOCSOUND:
  82                 return kiocsound((unsigned int)arg);
  83 
  84         case KDGKBTYPE:
  85                 /*
  86                  * this is naive.
  87                  */
  88                 verify_area((void *) arg, sizeof(unsigned char));
  89                 put_fs_byte(KB_101, (unsigned char *) arg);
  90                 return 0;
  91 
  92         case KDADDIO:
  93         case KDDELIO:
  94                 /*
  95                  * KDADDIO and KDDELIO may be able to add ports beyond what
  96                  * we reject here, but to be safe...
  97                  */
  98                 if (arg < GPFIRST || arg > GPLAST)
  99                         return -EINVAL;
 100                 return sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
 101 
 102         case KDENABIO:
 103         case KDDISABIO:
 104                 return sys_ioperm(GPFIRST, GPNUM,
 105                                   (cmd == KDENABIO)) ? -ENXIO : 0;
 106 
 107         case KDSETMODE:
 108                 /*
 109                  * currently, setting the mode from KD_TEXT to KD_GRAPHICS
 110                  * doesn't do a whole lot. i'm not sure if it should do any
 111                  * restoration of modes or what...
 112                  */
 113                 switch (arg) {
 114                 case KD_GRAPHICS:
 115                         break;
 116                 case KD_TEXT0:
 117                 case KD_TEXT1:
 118                         arg = KD_TEXT;
 119                 case KD_TEXT:
 120                         break;
 121                 default:
 122                         return -EINVAL;
 123                 }
 124                 vt_cons[console].vt_mode = arg;
 125                 return 0;
 126         case KDGETMODE:
 127                 verify_area((void *) arg, sizeof(unsigned long));
 128                 put_fs_long(vt_cons[console].vt_mode, (unsigned long *) arg);
 129                 return 0;
 130 
 131         case KDMAPDISP:
 132         case KDUNMAPDISP:
 133                 /*
 134                  * these work like a combination of mmap and KDENABIO.
 135                  * this could be easily finished.
 136                  */
 137                 return -EINVAL;
 138 
 139         case KDSKBMODE:
 140                 if (arg == K_RAW) {
 141                         if (console == fg_console) {
 142                                 kraw = 1;
 143                                 ke0 = 0;
 144                         } else {
 145                                 vt_cons[console].vc_kbdraw = 1;
 146                                 vt_cons[console].vc_kbde0 = 0;
 147                         }
 148                 }
 149                 else if (arg == K_XLATE) {
 150                         if (console == fg_console)
 151                                 kraw = 0;
 152                         else
 153                                 vt_cons[console].vc_kbdraw = 0;
 154                 }
 155                 else
 156                         return -EINVAL;
 157                 flush(tty->read_q);
 158                 flush(tty->secondary);
 159                 return 0;
 160         case KDGKBMODE:
 161                 verify_area((void *) arg, sizeof(unsigned long));
 162                 ucval = (console == fg_console) ? kraw :
 163                         vt_cons[console].vc_kbdraw;
 164                 put_fs_long(ucval ? K_RAW : K_XLATE, (unsigned long *) arg);
 165                 return 0;
 166 
 167         case KDGETLED:
 168                 verify_area((void *) arg, sizeof(unsigned char));
 169                 ucval = (console == fg_console) ? kleds :
 170                         vt_cons[console].vc_kbdleds;
 171                 put_fs_byte((((ucval & 1) ? LED_SCR : 0) |
 172                              ((ucval & 2) ? LED_NUM : 0) |
 173                              ((ucval & 4) ? LED_CAP : 0)),
 174                             (unsigned char *) arg);
 175                 return 0;
 176         case KDSETLED:
 177                 if (arg & ~7)
 178                         return -EINVAL;
 179                 ucval = (((arg & LED_SCR) ? 1 : 0) |
 180                          ((arg & LED_NUM) ? 2 : 0) |
 181                          ((arg & LED_CAP) ? 4 : 0));
 182                 if (console == fg_console) {
 183                         kleds = ucval;
 184                         set_leds();
 185                 }
 186                 else
 187                         vt_cons[console].vc_kbdleds = ucval;
 188                 return 0;
 189 
 190         default:
 191                 return -EINVAL;
 192         }
 193 }

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