|
|
1.1 root 1: /*
2: * kernel/chr_drv/vt.c
3: *
1.1.1.3 root 4: * Copyright (C) 1992 obz under the linux copyright
1.1 root 5: */
6:
1.1.1.3 root 7: #include <linux/types.h>
8: #include <linux/errno.h>
1.1 root 9: #include <linux/sched.h>
10: #include <linux/tty.h>
1.1.1.2 root 11: #include <linux/timer.h>
1.1 root 12: #include <linux/kernel.h>
1.1.1.4 ! root 13: #include <linux/kd.h>
! 14: #include <linux/vt.h>
1.1 root 15:
1.1.1.3 root 16: #include <asm/io.h>
17: #include <asm/segment.h>
18:
1.1 root 19: #include "vt_kern.h"
20:
21: /*
22: * console (vt and kd) routines, as defined by usl svr4 manual
23: */
24:
1.1.1.2 root 25: struct vt_cons vt_cons[NR_CONSOLES];
1.1 root 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)
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: /*
1.1.1.4 ! root 66: * We handle the console-specific ioctl's here. We allow the
! 67: * capability to modify any console, not just the fg_console.
1.1 root 68: */
1.1.1.4 ! root 69: int vt_ioctl(struct tty_struct *tty, struct file * file,
! 70: unsigned int cmd, unsigned int arg)
1.1 root 71: {
1.1.1.4 ! root 72: int console;
1.1 root 73: unsigned char ucval;
74:
1.1.1.4 ! root 75: console = tty->line - 1;
! 76:
! 77: if (console < 0 || console >= NR_CONSOLES)
1.1 root 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: }
1.1.1.2 root 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: }
1.1 root 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;
1.1.1.2 root 167: flush_input(tty);
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.