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