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_struct vt_cons[NR_CONSOLES];
37
38 asmlinkage 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 clr_vc_kbd_flag(kbd, VC_MEDIUMRAW);
212 } else if (arg == K_XLATE) {
213 clr_vc_kbd_flag(kbd, VC_RAW);
214 clr_vc_kbd_flag(kbd, VC_MEDIUMRAW);
215 } else if (arg == K_MEDIUMRAW) {
216 clr_vc_kbd_flag(kbd, VC_RAW);
217 set_vc_kbd_flag(kbd, VC_MEDIUMRAW);
218 } else
219 return -EINVAL;
220 flush_input(tty);
221 return 0;
222
223 case KDGKBMODE:
224 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
225 if (!i) {
226 ucval = vc_kbd_flag(kbd, VC_RAW);
227 if (vc_kbd_flag(kbd, VC_MEDIUMRAW))
228 put_fs_long(K_MEDIUMRAW, (unsigned long *) arg);
229 else
230 put_fs_long(ucval ? K_RAW : K_XLATE,
231 (unsigned long *) arg);
232 }
233 return i;
234
235 case KDGKBENT:
236 {
237 struct kbentry * const a = (struct kbentry *)arg;
238 u_char s;
239
240 i = verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbentry));
241 if (i)
242 return i;
243 if ((i = get_fs_byte((char *) &a->kb_index)) >= NR_KEYS)
244 return -EINVAL;
245 if ((s = get_fs_byte((char *) &a->kb_table)) >= NR_KEYMAPS)
246 return -EINVAL;
247 put_fs_word(key_map[s][i], (short *) &a->kb_value);
248 return 0;
249 }
250
251 case KDSKBENT:
252 {
253 const struct kbentry * a = (struct kbentry *)arg;
254 u_char s;
255 u_short v;
256
257 i = verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbentry));
258 if (i)
259 return i;
260 if ((i = get_fs_byte((char *) &a->kb_index)) >= NR_KEYS)
261 return -EINVAL;
262 if ((s = get_fs_byte((char *) &a->kb_table)) >= NR_KEYMAPS)
263 return -EINVAL;
264 if (KTYP(v = get_fs_word(&a->kb_value)) >= NR_TYPES)
265 return -EINVAL;
266 if (KVAL(v) > max_vals[KTYP(v)])
267 return -EINVAL;
268 key_map[s][i] = v;
269 return 0;
270 }
271
272 case KDGKBSENT:
273 {
274 struct kbsentry *a = (struct kbsentry *)arg;
275 char *p;
276 u_char *q;
277
278 i = verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbsentry));
279 if (i)
280 return i;
281 if ((i = get_fs_byte(&a->kb_func)) >= NR_FUNC)
282 return -EINVAL;
283 q = a->kb_string;
284 for (p = func_table[i]; *p; p++)
285 put_fs_byte(*p, q++);
286 put_fs_byte(0, q);
287 return 0;
288 }
289
290 case KDSKBSENT:
291 {
292 struct kbsentry * const a = (struct kbsentry *)arg;
293 int delta;
294 char *first_free;
295 int k;
296 u_char *p;
297 char *q;
298
299 i = verify_area(VERIFY_READ, (void *)a, sizeof(struct kbsentry));
300 if (i)
301 return i;
302 if ((i = get_fs_byte(&a->kb_func)) >= NR_FUNC)
303 return -EINVAL;
304 delta = -strlen(func_table[i]);
305 for (p = a->kb_string; get_fs_byte(p); p++)
306 delta++;
307 first_free = func_table[NR_FUNC - 1] +
308 strlen(func_table[NR_FUNC - 1]) + 1;
309 if (
310 delta > 0 &&
311 first_free + delta > func_buf + FUNC_BUFSIZE
312 )
313 return -EINVAL;
314 if (i < NR_FUNC - 1) {
315 memmove(
316 func_table[i + 1] + delta,
317 func_table[i + 1],
318 first_free - func_table[i + 1]);
319 for (k = i + 1; k < NR_FUNC; k++)
320 func_table[k] += delta;
321 }
322 for (p = a->kb_string, q = func_table[i]; ; p++, q++)
323 if (!(*q = get_fs_byte(p)))
324 break;
325 return 0;
326 }
327
328 case KDGETLED:
329 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned char));
330 if (i)
331 return i;
332 ucval = 0;
333 if (vc_kbd_flag(kbd, VC_SCROLLOCK))
334 ucval |= LED_SCR;
335 if (vc_kbd_flag(kbd, VC_NUMLOCK))
336 ucval |= LED_NUM;
337 if (vc_kbd_flag(kbd, VC_CAPSLOCK))
338 ucval |= LED_CAP;
339 put_fs_byte(ucval, (char *) arg);
340 return 0;
341
342 case KDSETLED:
343 if (arg & ~7)
344 return -EINVAL;
345 if (arg & LED_SCR)
346 set_vc_kbd_flag(kbd, VC_SCROLLOCK);
347 else
348 clr_vc_kbd_flag(kbd, VC_SCROLLOCK);
349 if (arg & LED_NUM)
350 set_vc_kbd_flag(kbd, VC_NUMLOCK);
351 else
352 clr_vc_kbd_flag(kbd, VC_NUMLOCK);
353 if (arg & LED_CAP)
354 set_vc_kbd_flag(kbd, VC_CAPSLOCK);
355 else
356 clr_vc_kbd_flag(kbd, VC_CAPSLOCK);
357 set_leds();
358 return 0;
359
360 case VT_SETMODE:
361 {
362 struct vt_mode *vtmode = (struct vt_mode *)arg;
363 char mode;
364
365 i = verify_area(VERIFY_WRITE, (void *)vtmode, sizeof(struct vt_mode));
366 if (i)
367 return i;
368 mode = get_fs_byte(&vtmode->mode);
369 if (mode != VT_AUTO && mode != VT_PROCESS)
370 return -EINVAL;
371 vt_cons[console].vt_mode.mode = mode;
372 vt_cons[console].vt_mode.waitv = get_fs_byte(&vtmode->waitv);
373 vt_cons[console].vt_mode.relsig = get_fs_word(&vtmode->relsig);
374 vt_cons[console].vt_mode.acqsig = get_fs_word(&vtmode->acqsig);
375
376 vt_cons[console].vt_mode.frsig = 0;
377 vt_cons[console].vt_pid = current->pid;
378 vt_cons[console].vt_newvt = 0;
379 return 0;
380 }
381
382 case VT_GETMODE:
383 {
384 struct vt_mode *vtmode = (struct vt_mode *)arg;
385
386 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct vt_mode));
387 if (i)
388 return i;
389 put_fs_byte(vt_cons[console].vt_mode.mode, &vtmode->mode);
390 put_fs_byte(vt_cons[console].vt_mode.waitv, &vtmode->waitv);
391 put_fs_word(vt_cons[console].vt_mode.relsig, &vtmode->relsig);
392 put_fs_word(vt_cons[console].vt_mode.acqsig, &vtmode->acqsig);
393 put_fs_word(vt_cons[console].vt_mode.frsig, &vtmode->frsig);
394 return 0;
395 }
396
397
398
399
400
401 case VT_GETSTATE:
402 {
403 struct vt_stat *vtstat = (struct vt_stat *)arg;
404 unsigned short state, mask;
405
406 i = verify_area(VERIFY_WRITE,(void *)vtstat, sizeof(struct vt_stat));
407 if (i)
408 return i;
409 put_fs_word(fg_console + 1, &vtstat->v_active);
410 state = 1;
411 for (i = 1, mask = 2; i <= NR_CONSOLES; ++i, mask <<= 1)
412 if (tty_table[i] && tty_table[i]->count > 0)
413 state |= mask;
414 put_fs_word(state, &vtstat->v_state);
415 return 0;
416 }
417
418
419
420
421 case VT_OPENQRY:
422 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
423 if (i)
424 return i;
425 for (i = 1; i <= NR_CONSOLES; ++i)
426 if (!tty_table[i] || tty_table[i]->count == 0)
427 break;
428 put_fs_long(i <= NR_CONSOLES ? i : -1, (unsigned long *)arg);
429 return 0;
430
431
432
433
434
435
436 case VT_ACTIVATE:
437 if (arg == 0 || arg > NR_CONSOLES)
438 return -ENXIO;
439 change_console(arg - 1);
440 return 0;
441
442
443
444
445 case VT_WAITACTIVE:
446 if (arg == 0 || arg > NR_CONSOLES)
447 return -ENXIO;
448 while (fg_console != arg - 1)
449 {
450 if (vt_waitactive() < 0)
451 return -EINTR;
452 }
453 return 0;
454
455
456
457
458
459
460
461
462
463
464
465 case VT_RELDISP:
466 if (vt_cons[console].vt_mode.mode != VT_PROCESS)
467 return -EINVAL;
468
469
470
471
472 if (vt_cons[console].vt_newvt >= 0)
473 {
474 if (arg == 0)
475
476
477
478
479 vt_cons[console].vt_newvt = -1;
480
481 else
482 {
483
484
485
486
487 int newvt = vt_cons[console].vt_newvt;
488 vt_cons[console].vt_newvt = -1;
489 complete_change_console(newvt);
490 }
491 }
492
493
494
495
496 else
497 {
498
499
500
501 if (arg != VT_ACKACQ)
502 return -EINVAL;
503 }
504
505 return 0;
506
507 default:
508 return -EINVAL;
509 }
510 }