This source file includes following definitions.
- kd_nosound
- kd_mksound
- vt_ioctl
1
2
3
4
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/keyboard.h>
14 #include <linux/kd.h>
15 #include <linux/vt.h>
16 #include <linux/string.h>
17
18 #include <asm/io.h>
19 #include <asm/segment.h>
20
21 #include "vt_kern.h"
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 struct vt_cons vt_cons[NR_CONSOLES];
37
38 extern "C" int sys_ioperm(unsigned long from, unsigned long num, int on);
39
40 extern void change_console(unsigned int new_console);
41 extern void complete_change_console(unsigned int new_console);
42 extern int vt_waitactive(void);
43
44
45
46
47
48 #define GPFIRST 0x3b4
49 #define GPLAST 0x3df
50 #define GPNUM (GPLAST - GPFIRST + 1)
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 static void
68 kd_nosound(unsigned long ignored)
69 {
70
71 outb(inb_p(0x61)&0xFC, 0x61);
72 return;
73 }
74
75 void
76 kd_mksound(unsigned int count, unsigned int ticks)
77 {
78 static struct timer_list sound_timer = { NULL, 0, 0, kd_nosound };
79
80 cli();
81 del_timer(&sound_timer);
82 if (count) {
83
84 outb_p(inb_p(0x61)|3, 0x61);
85
86 outb_p(0xB6, 0x43);
87
88 outb_p(count & 0xff, 0x42);
89 outb((count >> 8) & 0xff, 0x42);
90
91 if (ticks) {
92 sound_timer.expires = ticks;
93 add_timer(&sound_timer);
94 }
95 } else
96 kd_nosound(0);
97 sti();
98 return;
99 }
100
101
102
103
104
105 int vt_ioctl(struct tty_struct *tty, struct file * file,
106 unsigned int cmd, unsigned long arg)
107 {
108 int console, i;
109 unsigned char ucval;
110 struct kbd_struct * kbd;
111
112 console = tty->line - 1;
113
114 if (console < 0 || console >= NR_CONSOLES)
115 return -EINVAL;
116
117 kbd = kbd_table + console;
118 switch (cmd) {
119 case KIOCSOUND:
120 kd_mksound((unsigned int)arg, 0);
121 return 0;
122
123 case KDMKTONE:
124 {
125 unsigned int ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
126
127
128
129
130
131 kd_mksound(arg & 0xffff, ticks);
132 if (ticks == 0)
133 kd_nosound(0);
134 return 0;
135 }
136
137 case KDGKBTYPE:
138
139
140
141 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned char));
142 if (!i)
143 put_fs_byte(KB_101, (char *) arg);
144 return i;
145
146 case KDADDIO:
147 case KDDELIO:
148
149
150
151
152 if (arg < GPFIRST || arg > GPLAST)
153 return -EINVAL;
154 return sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
155
156 case KDENABIO:
157 case KDDISABIO:
158 return sys_ioperm(GPFIRST, GPNUM,
159 (cmd == KDENABIO)) ? -ENXIO : 0;
160
161 case KDSETMODE:
162
163
164
165
166
167 switch (arg) {
168 case KD_GRAPHICS:
169 break;
170 case KD_TEXT0:
171 case KD_TEXT1:
172 arg = KD_TEXT;
173 case KD_TEXT:
174 break;
175 default:
176 return -EINVAL;
177 }
178 if (vt_cons[console].vc_mode == (unsigned char) arg)
179 return 0;
180 vt_cons[console].vc_mode = (unsigned char) arg;
181 if (console != fg_console)
182 return 0;
183
184
185
186 if (arg == KD_TEXT)
187 unblank_screen();
188 else {
189 timer_active &= ~(1<<BLANK_TIMER);
190 blank_screen();
191 }
192 return 0;
193
194 case KDGETMODE:
195 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
196 if (!i)
197 put_fs_long(vt_cons[console].vc_mode, (unsigned long *) arg);
198 return i;
199
200 case KDMAPDISP:
201 case KDUNMAPDISP:
202
203
204
205
206 return -EINVAL;
207
208 case KDSKBMODE:
209 if (arg == K_RAW) {
210 set_vc_kbd_flag(kbd, VC_RAW);
211 } else if (arg == K_XLATE) {
212 clr_vc_kbd_flag(kbd, VC_RAW);
213 }
214 else
215 return -EINVAL;
216 flush_input(tty);
217 return 0;
218
219 case KDGKBMODE:
220 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
221 if (!i) {
222 ucval = vc_kbd_flag(kbd, VC_RAW);
223 put_fs_long(ucval ? K_RAW : K_XLATE, (unsigned long *) arg);
224 }
225 return i;
226
227 case KDGKBENT:
228 {
229 struct kbentry * const a = (struct kbentry *)arg;
230 u_char i;
231 u_char s;
232
233 verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbentry));
234 if ((i = get_fs_byte((char *) &a->kb_index)) >= NR_KEYS)
235 return -EINVAL;
236 if ((s = get_fs_byte((char *) &a->kb_table)) >= NR_KEYMAPS)
237 return -EINVAL;
238 put_fs_word(key_map[s][i], (short *) &a->kb_value);
239 return 0;
240 }
241
242 case KDSKBENT:
243 {
244 const struct kbentry * a = (struct kbentry *)arg;
245 u_char i;
246 u_char s;
247 u_short v;
248
249 verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbentry));
250 if ((i = get_fs_byte((char *) &a->kb_index)) >= NR_KEYS)
251 return -EINVAL;
252 if ((s = get_fs_byte((char *) &a->kb_table)) >= NR_KEYMAPS)
253 return -EINVAL;
254 if (KTYP(v = get_fs_word(&a->kb_value)) >= NR_TYPES)
255 return -EINVAL;
256 if (KVAL(v) > max_vals[KTYP(v)])
257 return -EINVAL;
258 key_map[s][i] = v;
259 return 0;
260 }
261
262 case KDGKBSENT:
263 {
264 const struct kbsentry *a = (struct kbsentry *)arg;
265 u_char i;
266 char *p;
267 u_char *q;
268
269 verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbsentry));
270 if ((i = get_fs_byte(&a->kb_func)) >= NR_FUNC)
271 return -EINVAL;
272 q = a->kb_string;
273 for (p = func_table[i]; *p; p++)
274 put_fs_byte(*p, q++);
275 put_fs_byte(0, q);
276 return 0;
277 }
278
279 case KDSKBSENT:
280 {
281 struct kbsentry * const a = (struct kbsentry *)arg;
282 int delta;
283 char *first_free;
284 u_char i;
285 int k;
286 u_char *p;
287 char *q;
288
289 verify_area(VERIFY_READ, (void *)a, sizeof(struct kbsentry));
290 if ((i = get_fs_byte(&a->kb_func)) >= NR_FUNC)
291 return -EINVAL;
292 delta = -strlen(func_table[i]);
293 for (p = a->kb_string; get_fs_byte(p); p++)
294 delta++;
295 first_free = func_table[NR_FUNC - 1] +
296 strlen(func_table[NR_FUNC - 1]) + 1;
297 if (
298 delta > 0 &&
299 first_free + delta > func_buf + FUNC_BUFSIZE
300 )
301 return -EINVAL;
302 if (i < NR_FUNC - 1) {
303 memmove(
304 func_table[i + 1] + delta,
305 func_table[i + 1],
306 first_free - func_table[i + 1]);
307 for (k = i + 1; k < NR_FUNC; k++)
308 func_table[k] += delta;
309 }
310 for (p = a->kb_string, q = func_table[i]; ; p++, q++)
311 if (!(*q = get_fs_byte(p)))
312 break;
313 return 0;
314 }
315
316 case KDGETLED:
317 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned char));
318 if (i)
319 return i;
320 ucval = 0;
321 if (vc_kbd_flag(kbd, VC_SCROLLOCK))
322 ucval |= LED_SCR;
323 if (vc_kbd_flag(kbd, VC_NUMLOCK))
324 ucval |= LED_NUM;
325 if (vc_kbd_flag(kbd, VC_CAPSLOCK))
326 ucval |= LED_CAP;
327 put_fs_byte(ucval, (char *) arg);
328 return 0;
329
330 case KDSETLED:
331 if (arg & ~7)
332 return -EINVAL;
333 if (arg & LED_SCR)
334 set_vc_kbd_flag(kbd, VC_SCROLLOCK);
335 else
336 clr_vc_kbd_flag(kbd, VC_SCROLLOCK);
337 if (arg & LED_NUM)
338 set_vc_kbd_flag(kbd, VC_NUMLOCK);
339 else
340 clr_vc_kbd_flag(kbd, VC_NUMLOCK);
341 if (arg & LED_CAP)
342 set_vc_kbd_flag(kbd, VC_CAPSLOCK);
343 else
344 clr_vc_kbd_flag(kbd, VC_CAPSLOCK);
345 set_leds();
346 return 0;
347
348 case VT_SETMODE:
349 {
350 struct vt_mode *vtmode = (struct vt_mode *)arg;
351 char mode;
352
353 i = verify_area(VERIFY_WRITE, (void *)vtmode, sizeof(struct vt_mode));
354 if (i)
355 return i;
356 mode = get_fs_byte(&vtmode->mode);
357 if (mode != VT_AUTO && mode != VT_PROCESS)
358 return -EINVAL;
359 vt_cons[console].vt_mode.mode = mode;
360 vt_cons[console].vt_mode.waitv = get_fs_byte(&vtmode->waitv);
361 vt_cons[console].vt_mode.relsig = get_fs_word(&vtmode->relsig);
362 vt_cons[console].vt_mode.acqsig = get_fs_word(&vtmode->acqsig);
363
364 vt_cons[console].vt_mode.frsig = 0;
365 vt_cons[console].vt_pid = current->pid;
366 vt_cons[console].vt_newvt = 0;
367 return 0;
368 }
369
370 case VT_GETMODE:
371 {
372 struct vt_mode *vtmode = (struct vt_mode *)arg;
373
374 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct vt_mode));
375 if (i)
376 return i;
377 put_fs_byte(vt_cons[console].vt_mode.mode, &vtmode->mode);
378 put_fs_byte(vt_cons[console].vt_mode.waitv, &vtmode->waitv);
379 put_fs_word(vt_cons[console].vt_mode.relsig, &vtmode->relsig);
380 put_fs_word(vt_cons[console].vt_mode.acqsig, &vtmode->acqsig);
381 put_fs_word(vt_cons[console].vt_mode.frsig, &vtmode->frsig);
382 return 0;
383 }
384
385
386
387
388
389 case VT_GETSTATE:
390 {
391 struct vt_stat *vtstat = (struct vt_stat *)arg;
392 unsigned short state, mask;
393
394 i = verify_area(VERIFY_WRITE,(void *)vtstat, sizeof(struct vt_stat));
395 if (i)
396 return i;
397 put_fs_word(fg_console + 1, &vtstat->v_active);
398 state = 1;
399 for (i = 1, mask = 2; i <= NR_CONSOLES; ++i, mask <<= 1)
400 if (tty_table[i] && tty_table[i]->count > 0)
401 state |= mask;
402 put_fs_word(state, &vtstat->v_state);
403 return 0;
404 }
405
406
407
408
409 case VT_OPENQRY:
410 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
411 if (i)
412 return i;
413 for (i = 1; i <= NR_CONSOLES; ++i)
414 if (!tty_table[i] || tty_table[i]->count == 0)
415 break;
416 put_fs_long(i <= NR_CONSOLES ? i : -1, (unsigned long *)arg);
417 return 0;
418
419
420
421
422
423
424 case VT_ACTIVATE:
425 if (arg == 0 || arg > NR_CONSOLES)
426 return -ENXIO;
427 change_console(arg - 1);
428 return 0;
429
430
431
432
433 case VT_WAITACTIVE:
434 if (arg == 0 || arg > NR_CONSOLES)
435 return -ENXIO;
436 while (fg_console != arg - 1)
437 {
438 if (vt_waitactive() < 0)
439 return -EINTR;
440 }
441 return 0;
442
443
444
445
446
447
448
449
450
451
452
453 case VT_RELDISP:
454 if (vt_cons[console].vt_mode.mode != VT_PROCESS)
455 return -EINVAL;
456
457
458
459
460 if (vt_cons[console].vt_newvt >= 0)
461 {
462 if (arg == 0)
463
464
465
466
467 vt_cons[console].vt_newvt = -1;
468
469 else
470 {
471
472
473
474
475 int newvt = vt_cons[console].vt_newvt;
476 vt_cons[console].vt_newvt = -1;
477 complete_change_console(newvt);
478 }
479 }
480
481
482
483
484 else
485 {
486
487
488
489 if (arg != VT_ACKACQ)
490 return -EINVAL;
491 }
492
493 return 0;
494
495 default:
496 return -EINVAL;
497 }
498 }