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 void
66 kd_nosound(void)
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 if (count)
77 {
78
79 outb_p(inb_p(0x61)|3, 0x61);
80
81 outb_p(0xB6, 0x43);
82
83 outb_p(count & 0xff, 0x42);
84 outb((count >> 8) & 0xff, 0x42);
85
86 if (ticks)
87 {
88 timer_table[BEEP_TIMER].expires = jiffies + ticks;
89 timer_table[BEEP_TIMER].fn = kd_nosound;
90 timer_active |= (1 << BEEP_TIMER);
91 }
92 }
93
94 else
95 kd_nosound();
96
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();
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, (unsigned 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 KDGETLED:
227 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned char));
228 if (i)
229 return i;
230 ucval = 0;
231 if (vc_kbd_flag(kbd, VC_SCROLLOCK))
232 ucval |= LED_SCR;
233 if (vc_kbd_flag(kbd, VC_NUMLOCK))
234 ucval |= LED_NUM;
235 if (vc_kbd_flag(kbd, VC_CAPSLOCK))
236 ucval |= LED_CAP;
237 put_fs_byte(ucval, (unsigned char *) arg);
238 return 0;
239
240 case KDSETLED:
241 if (arg & ~7)
242 return -EINVAL;
243 if (arg & LED_SCR)
244 set_vc_kbd_flag(kbd, VC_SCROLLOCK);
245 else
246 clr_vc_kbd_flag(kbd, VC_SCROLLOCK);
247 if (arg & LED_NUM)
248 set_vc_kbd_flag(kbd, VC_NUMLOCK);
249 else
250 clr_vc_kbd_flag(kbd, VC_NUMLOCK);
251 if (arg & LED_CAP)
252 set_vc_kbd_flag(kbd, VC_CAPSLOCK);
253 else
254 clr_vc_kbd_flag(kbd, VC_CAPSLOCK);
255 set_leds();
256 return 0;
257
258 case VT_SETMODE:
259 {
260 struct vt_mode *vtmode = (struct vt_mode *)arg;
261 char mode;
262
263 i = verify_area(VERIFY_WRITE, (void *)vtmode, sizeof(struct vt_mode));
264 if (i)
265 return i;
266 mode = get_fs_byte(&vtmode->mode);
267 if (mode != VT_AUTO && mode != VT_PROCESS)
268 return -EINVAL;
269 vt_cons[console].vt_mode.mode = mode;
270 vt_cons[console].vt_mode.waitv = get_fs_byte(&vtmode->waitv);
271 vt_cons[console].vt_mode.relsig = get_fs_word(&vtmode->relsig);
272 vt_cons[console].vt_mode.acqsig = get_fs_word(&vtmode->acqsig);
273
274 vt_cons[console].vt_mode.frsig = 0;
275 vt_cons[console].vt_pid = current->pid;
276 vt_cons[console].vt_newvt = 0;
277 return 0;
278 }
279
280 case VT_GETMODE:
281 {
282 struct vt_mode *vtmode = (struct vt_mode *)arg;
283
284 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct vt_mode));
285 if (i)
286 return i;
287 put_fs_byte(vt_cons[console].vt_mode.mode, &vtmode->mode);
288 put_fs_byte(vt_cons[console].vt_mode.waitv, &vtmode->waitv);
289 put_fs_word(vt_cons[console].vt_mode.relsig, &vtmode->relsig);
290 put_fs_word(vt_cons[console].vt_mode.acqsig, &vtmode->acqsig);
291 put_fs_word(vt_cons[console].vt_mode.frsig, &vtmode->frsig);
292 return 0;
293 }
294
295
296
297
298
299 case VT_GETSTATE:
300 {
301 struct vt_stat *vtstat = (struct vt_stat *)arg;
302 unsigned short state, mask;
303
304 i = verify_area(VERIFY_WRITE,(void *)vtstat, sizeof(struct vt_stat));
305 if (i)
306 return i;
307 put_fs_word(fg_console + 1, &vtstat->v_active);
308 state = 1;
309 for (i = 1, mask = 2; i <= NR_CONSOLES; ++i, mask <<= 1)
310 if (tty_table[i] && tty_table[i]->count > 0)
311 state |= mask;
312 put_fs_word(state, &vtstat->v_state);
313 return 0;
314 }
315
316
317
318
319 case VT_OPENQRY:
320 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
321 if (i)
322 return i;
323 for (i = 1; i <= NR_CONSOLES; ++i)
324 if (!tty_table[i] || tty_table[i]->count == 0)
325 break;
326 put_fs_long(i <= NR_CONSOLES ? i : -1, (unsigned long *)arg);
327 return 0;
328
329
330
331
332
333
334 case VT_ACTIVATE:
335 if (arg == 0 || arg > NR_CONSOLES)
336 return -ENXIO;
337 change_console(arg - 1);
338 return 0;
339
340
341
342
343 case VT_WAITACTIVE:
344 if (arg == 0 || arg > NR_CONSOLES)
345 return -ENXIO;
346 while (fg_console != arg - 1)
347 {
348 if (vt_waitactive() < 0)
349 return -EINTR;
350 }
351 return 0;
352
353
354
355
356
357
358
359
360
361
362
363 case VT_RELDISP:
364 if (vt_cons[console].vt_mode.mode != VT_PROCESS)
365 return -EINVAL;
366
367
368
369
370 if (vt_cons[console].vt_newvt >= 0)
371 {
372 if (arg == 0)
373
374
375
376
377 vt_cons[console].vt_newvt = -1;
378
379 else
380 {
381
382
383
384
385 int newvt = vt_cons[console].vt_newvt;
386 vt_cons[console].vt_newvt = -1;
387 complete_change_console(newvt);
388 }
389 }
390
391
392
393
394 else
395 {
396
397
398
399 if (arg != VT_ACKACQ)
400 return -EINVAL;
401 }
402
403 return 0;
404
405 default:
406 return -EINVAL;
407 }
408 }