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