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

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