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