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 #include <linux/kd.h>
  14 #include <linux/vt.h>
  15 
  16 #include <asm/io.h>
  17 #include <asm/segment.h>
  18 
  19 #include "vt_kern.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  * We handle the console-specific ioctl's here.  We allow the
  67  * capability to modify any console, not just the fg_console. 
  68  */
  69 int vt_ioctl(struct tty_struct *tty, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
  70              unsigned int cmd, unsigned int arg)
  71 {
  72         int console;
  73         unsigned char ucval;
  74 
  75         console = tty->line - 1;
  76 
  77         if (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                 if (vt_cons[console].vt_mode == (unsigned char) arg)
 125                         return 0;
 126                 vt_cons[console].vt_mode = (unsigned char) arg;
 127                 if (console != fg_console)
 128                         return 0;
 129                 if (arg == KD_TEXT)
 130                         unblank_screen();
 131                 else {
 132                         timer_active &= 1<<BLANK_TIMER;
 133                         blank_screen();
 134                 }
 135                 return 0;
 136         case KDGETMODE:
 137                 verify_area((void *) arg, sizeof(unsigned long));
 138                 put_fs_long(vt_cons[console].vt_mode, (unsigned long *) arg);
 139                 return 0;
 140 
 141         case KDMAPDISP:
 142         case KDUNMAPDISP:
 143                 /*
 144                  * these work like a combination of mmap and KDENABIO.
 145                  * this could be easily finished.
 146                  */
 147                 return -EINVAL;
 148 
 149         case KDSKBMODE:
 150                 if (arg == K_RAW) {
 151                         if (console == fg_console) {
 152                                 kraw = 1;
 153                                 ke0 = 0;
 154                         } else {
 155                                 vt_cons[console].vc_kbdraw = 1;
 156                                 vt_cons[console].vc_kbde0 = 0;
 157                         }
 158                 }
 159                 else if (arg == K_XLATE) {
 160                         if (console == fg_console)
 161                                 kraw = 0;
 162                         else
 163                                 vt_cons[console].vc_kbdraw = 0;
 164                 }
 165                 else
 166                         return -EINVAL;
 167                 flush_input(tty);
 168                 return 0;
 169         case KDGKBMODE:
 170                 verify_area((void *) arg, sizeof(unsigned long));
 171                 ucval = (console == fg_console) ? kraw :
 172                         vt_cons[console].vc_kbdraw;
 173                 put_fs_long(ucval ? K_RAW : K_XLATE, (unsigned long *) arg);
 174                 return 0;
 175 
 176         case KDGETLED:
 177                 verify_area((void *) arg, sizeof(unsigned char));
 178                 ucval = (console == fg_console) ? kleds :
 179                         vt_cons[console].vc_kbdleds;
 180                 put_fs_byte((((ucval & 1) ? LED_SCR : 0) |
 181                              ((ucval & 2) ? LED_NUM : 0) |
 182                              ((ucval & 4) ? LED_CAP : 0)),
 183                             (unsigned char *) arg);
 184                 return 0;
 185         case KDSETLED:
 186                 if (arg & ~7)
 187                         return -EINVAL;
 188                 ucval = (((arg & LED_SCR) ? 1 : 0) |
 189                          ((arg & LED_NUM) ? 2 : 0) |
 190                          ((arg & LED_CAP) ? 4 : 0));
 191                 if (console == fg_console) {
 192                         kleds = ucval;
 193                         set_leds();
 194                 }
 195                 else
 196                         vt_cons[console].vc_kbdleds = ucval;
 197                 return 0;
 198 
 199         default:
 200                 return -EINVAL;
 201         }
 202 }

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