|
|
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>
13:
1.1.1.3 ! root 14: #include <asm/io.h>
! 15: #include <asm/segment.h>
! 16:
1.1 root 17: #include "vt_kern.h"
1.1.1.3 ! root 18: #include <sys/kd.h>
! 19: #include <sys/vt.h>
1.1 root 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: /*
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)
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: }
1.1.1.2 root 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: }
1.1 root 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;
1.1.1.2 root 165: flush_input(tty);
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.