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