This source file includes following definitions.
- kd_size_changed
- kd_nosound
- kd_mksound
- vt_ioctl
1
2
3
4
5
6
7
8
9
10 #include <linux/types.h>
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/tty.h>
14 #include <linux/timer.h>
15 #include <linux/kernel.h>
16 #include <linux/kd.h>
17 #include <linux/vt.h>
18 #include <linux/string.h>
19 #include <linux/malloc.h>
20 #include <linux/major.h>
21 #include <linux/fs.h>
22
23 #include <asm/io.h>
24 #include <asm/segment.h>
25
26 #include "kbd_kern.h"
27 #include "vt_kern.h"
28 #include "diacr.h"
29 #include "selection.h"
30
31 extern struct tty_driver console_driver;
32 extern int sel_cons;
33
34 #define VT_IS_IN_USE(i) (console_driver.table[i] && console_driver.table[i]->count)
35 #define VT_BUSY(i) (VT_IS_IN_USE(i) || i == fg_console || i == sel_cons)
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 struct vt_struct *vt_cons[MAX_NR_CONSOLES];
51
52 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
53
54 extern int getkeycode(unsigned int scancode);
55 extern int setkeycode(unsigned int scancode, unsigned int keycode);
56 extern void compute_shiftstate(void);
57 extern void change_console(unsigned int new_console);
58 extern void complete_change_console(unsigned int new_console);
59 extern int vt_waitactive(void);
60 extern void do_blank_screen(int nopowersave);
61 extern void do_unblank_screen(void);
62
63 extern unsigned int keymap_count;
64
65
66
67
68 extern int con_set_trans_old(char * table);
69 extern int con_get_trans_old(char * table);
70 extern int con_set_trans_new(unsigned short * table);
71 extern int con_get_trans_new(unsigned short * table);
72 extern void con_clear_unimap(struct unimapinit *ui);
73 extern int con_set_unimap(ushort ct, struct unipair *list);
74 extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
75 extern int con_set_font(char * fontmap, int ch512);
76 extern int con_get_font(char * fontmap);
77 extern int con_adjust_height(unsigned long fontheight);
78
79 extern int video_mode_512ch;
80 extern unsigned long video_font_height;
81
82
83
84
85
86 #define GPFIRST 0x3b4
87 #define GPLAST 0x3df
88 #define GPNUM (GPLAST - GPFIRST + 1)
89
90
91
92
93
94
95
96
97
98 static void
99 kd_size_changed(int row, int col)
100 {
101 struct task_struct *p;
102 int i;
103
104 if ( !row && !col ) return;
105
106 for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ )
107 {
108 if ( console_driver.table[i] )
109 {
110 if ( row ) console_driver.table[i]->winsize.ws_row = row;
111 if ( col ) console_driver.table[i]->winsize.ws_col = col;
112 }
113 }
114
115 for_each_task(p)
116 {
117 if ( p->tty && MAJOR(p->tty->device) == TTY_MAJOR &&
118 MINOR(p->tty->device) <= MAX_NR_CONSOLES && MINOR(p->tty->device) )
119 {
120 send_sig(SIGWINCH, p, 1);
121 }
122 }
123 }
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 static void
141 kd_nosound(unsigned long ignored)
142 {
143
144 outb(inb_p(0x61)&0xFC, 0x61);
145 return;
146 }
147
148 void
149 kd_mksound(unsigned int count, unsigned int ticks)
150 {
151 static struct timer_list sound_timer = { NULL, NULL, 0, 0, kd_nosound };
152
153 cli();
154 del_timer(&sound_timer);
155 if (count) {
156
157 outb_p(inb_p(0x61)|3, 0x61);
158
159 outb_p(0xB6, 0x43);
160
161 outb_p(count & 0xff, 0x42);
162 outb((count >> 8) & 0xff, 0x42);
163
164 if (ticks) {
165 sound_timer.expires = ticks;
166 add_timer(&sound_timer);
167 }
168 } else
169 kd_nosound(0);
170 sti();
171 return;
172 }
173
174
175
176
177
178 int vt_ioctl(struct tty_struct *tty, struct file * file,
179 unsigned int cmd, unsigned long arg)
180 {
181 int i, perm;
182 unsigned int console;
183 unsigned char ucval;
184 struct kbd_struct * kbd;
185 struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
186
187 console = vt->vc_num;
188
189 if (!vc_cons_allocated(console))
190 return -ENOIOCTLCMD;
191
192
193
194
195
196 perm = 0;
197 if (current->tty == tty || suser())
198 perm = 1;
199
200 kbd = kbd_table + console;
201 switch (cmd) {
202 case KIOCSOUND:
203 if (!perm)
204 return -EPERM;
205 kd_mksound((unsigned int)arg, 0);
206 return 0;
207
208 case KDMKTONE:
209 if (!perm)
210 return -EPERM;
211 {
212 unsigned int ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
213
214
215
216
217
218 kd_mksound(arg & 0xffff, ticks);
219 if (ticks == 0)
220 kd_nosound(0);
221 return 0;
222 }
223
224 case KDGKBTYPE:
225
226
227
228 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned char));
229 if (!i)
230 put_fs_byte(KB_101, (char *) arg);
231 return i;
232
233 case KDADDIO:
234 case KDDELIO:
235
236
237
238
239 if (arg < GPFIRST || arg > GPLAST)
240 return -EINVAL;
241 return sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
242
243 case KDENABIO:
244 case KDDISABIO:
245 return sys_ioperm(GPFIRST, GPNUM,
246 (cmd == KDENABIO)) ? -ENXIO : 0;
247
248 case KDSETMODE:
249
250
251
252
253
254 if (!perm)
255 return -EPERM;
256 switch (arg) {
257 case KD_GRAPHICS:
258 break;
259 case KD_TEXT0:
260 case KD_TEXT1:
261 arg = KD_TEXT;
262 case KD_TEXT:
263 break;
264 default:
265 return -EINVAL;
266 }
267 if (vt_cons[console]->vc_mode == (unsigned char) arg)
268 return 0;
269 vt_cons[console]->vc_mode = (unsigned char) arg;
270 if (console != fg_console)
271 return 0;
272
273
274
275 if (arg == KD_TEXT)
276 do_unblank_screen();
277 else
278 do_blank_screen(1);
279 return 0;
280
281 case KDGETMODE:
282 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
283 if (!i)
284 put_fs_long(vt_cons[console]->vc_mode, (unsigned long *) arg);
285 return i;
286
287 case KDMAPDISP:
288 case KDUNMAPDISP:
289
290
291
292
293 return -EINVAL;
294
295 case KDSKBMODE:
296 if (!perm)
297 return -EPERM;
298 switch(arg) {
299 case K_RAW:
300 kbd->kbdmode = VC_RAW;
301 break;
302 case K_MEDIUMRAW:
303 kbd->kbdmode = VC_MEDIUMRAW;
304 break;
305 case K_XLATE:
306 kbd->kbdmode = VC_XLATE;
307 compute_shiftstate();
308 break;
309 case K_UNICODE:
310 kbd->kbdmode = VC_UNICODE;
311 compute_shiftstate();
312 break;
313 default:
314 return -EINVAL;
315 }
316 if (tty->ldisc.flush_buffer)
317 tty->ldisc.flush_buffer(tty);
318 return 0;
319
320 case KDGKBMODE:
321 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
322 if (!i) {
323 ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW :
324 (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
325 (kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
326 K_XLATE);
327 put_fs_long(ucval, (unsigned long *) arg);
328 }
329 return i;
330
331
332
333 case KDSKBMETA:
334 switch(arg) {
335 case K_METABIT:
336 clr_vc_kbd_mode(kbd, VC_META);
337 break;
338 case K_ESCPREFIX:
339 set_vc_kbd_mode(kbd, VC_META);
340 break;
341 default:
342 return -EINVAL;
343 }
344 return 0;
345
346 case KDGKBMETA:
347 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
348 if (!i) {
349 ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX :
350 K_METABIT);
351 put_fs_long(ucval, (unsigned long *) arg);
352 }
353 return i;
354
355 case KDGETKEYCODE:
356 {
357 struct kbkeycode * const a = (struct kbkeycode *)arg;
358 unsigned int sc;
359 int kc;
360
361 i = verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbkeycode));
362 if (i)
363 return i;
364 sc = get_fs_long((int *) &a->scancode);
365 kc = getkeycode(sc);
366 if (kc < 0)
367 return kc;
368 put_fs_long(kc, (int *) &a->keycode);
369 return 0;
370 }
371
372 case KDSETKEYCODE:
373 {
374 struct kbkeycode * const a = (struct kbkeycode *)arg;
375 unsigned int sc, kc;
376
377 if (!perm)
378 return -EPERM;
379 i = verify_area(VERIFY_READ, (void *)a, sizeof(struct kbkeycode));
380 if (i)
381 return i;
382 sc = get_fs_long((int *) &a->scancode);
383 kc = get_fs_long((int *) &a->keycode);
384 return setkeycode(sc, kc);
385 }
386
387 case KDGKBENT:
388 {
389 struct kbentry * const a = (struct kbentry *)arg;
390 ushort *key_map, val;
391 u_char s;
392
393 i = verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbentry));
394 if (i)
395 return i;
396 if ((i = get_fs_byte((char *) &a->kb_index)) >= NR_KEYS)
397 return -EINVAL;
398 if ((s = get_fs_byte((char *) &a->kb_table)) >= MAX_NR_KEYMAPS)
399 return -EINVAL;
400 key_map = key_maps[s];
401 if (key_map) {
402 val = U(key_map[i]);
403 if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
404 val = K_HOLE;
405 } else
406 val = (i ? K_HOLE : K_NOSUCHMAP);
407 put_fs_word(val, (short *) &a->kb_value);
408 return 0;
409 }
410
411 case KDSKBENT:
412 {
413 const struct kbentry * a = (struct kbentry *)arg;
414 ushort *key_map;
415 u_char s;
416 u_short v, ov;
417
418 if (!perm)
419 return -EPERM;
420 i = verify_area(VERIFY_READ, (void *)a, sizeof(struct kbentry));
421 if (i)
422 return i;
423 if ((i = get_fs_byte((char *) &a->kb_index)) >= NR_KEYS)
424 return -EINVAL;
425 if ((s = get_fs_byte((char *) &a->kb_table)) >= MAX_NR_KEYMAPS)
426 return -EINVAL;
427 v = get_fs_word(&a->kb_value);
428 if (!i && v == K_NOSUCHMAP) {
429
430 key_map = key_maps[s];
431 if (s && key_map) {
432 key_maps[s] = 0;
433 if (key_map[0] == U(K_ALLOCATED)) {
434 kfree_s(key_map, sizeof(plain_map));
435 keymap_count--;
436 }
437 }
438 return 0;
439 }
440
441 if (KTYP(v) < NR_TYPES) {
442 if (KVAL(v) > max_vals[KTYP(v)])
443 return -EINVAL;
444 } else
445 if (kbd->kbdmode != VC_UNICODE)
446 return -EINVAL;
447
448
449 if (!i)
450 return 0;
451
452 if (!(key_map = key_maps[s])) {
453 int j;
454
455 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && !suser())
456 return -EPERM;
457
458 key_map = (ushort *) kmalloc(sizeof(plain_map),
459 GFP_KERNEL);
460 if (!key_map)
461 return -ENOMEM;
462 key_maps[s] = key_map;
463 key_map[0] = U(K_ALLOCATED);
464 for (j = 1; j < NR_KEYS; j++)
465 key_map[j] = U(K_HOLE);
466 keymap_count++;
467 }
468 ov = U(key_map[i]);
469 if (v == ov)
470 return 0;
471
472
473
474
475 if (((ov == K_SAK) || (v == K_SAK)) && !suser())
476 return -EPERM;
477 key_map[i] = U(v);
478 if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
479 compute_shiftstate();
480 return 0;
481 }
482
483 case KDGKBSENT:
484 {
485 struct kbsentry *a = (struct kbsentry *)arg;
486 char *p;
487 u_char *q;
488 int sz;
489
490 i = verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbsentry));
491 if (i)
492 return i;
493 if ((i = get_fs_byte(&a->kb_func)) >= MAX_NR_FUNC || i < 0)
494 return -EINVAL;
495 sz = sizeof(a->kb_string) - 1;
496
497 q = a->kb_string;
498 p = func_table[i];
499 if(p)
500 for ( ; *p && sz; p++, sz--)
501 put_fs_byte(*p, q++);
502 put_fs_byte(0, q);
503 return ((p && *p) ? -EOVERFLOW : 0);
504 }
505
506 case KDSKBSENT:
507 {
508 struct kbsentry * const a = (struct kbsentry *)arg;
509 int delta;
510 char *first_free, *fj, *fnw;
511 int j, k, sz;
512 u_char *p;
513 char *q;
514
515 if (!perm)
516 return -EPERM;
517 i = verify_area(VERIFY_READ, (void *)a, sizeof(struct kbsentry));
518 if (i)
519 return i;
520 if ((i = get_fs_byte(&a->kb_func)) >= MAX_NR_FUNC)
521 return -EINVAL;
522 q = func_table[i];
523
524 first_free = funcbufptr + (funcbufsize - funcbufleft);
525 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) ;
526 if (j < MAX_NR_FUNC)
527 fj = func_table[j];
528 else
529 fj = first_free;
530
531 delta = (q ? -strlen(q) : 1);
532 sz = sizeof(a->kb_string);
533
534 for (p = a->kb_string; get_fs_byte(p) && sz; p++,sz--)
535 delta++;
536 if (!sz)
537 return -EOVERFLOW;
538 if (delta <= funcbufleft) {
539 if (j < MAX_NR_FUNC) {
540 memmove(fj + delta, fj, first_free - fj);
541 for (k = j; k < MAX_NR_FUNC; k++)
542 if (func_table[k])
543 func_table[k] += delta;
544 }
545 if (!q)
546 func_table[i] = fj;
547 funcbufleft -= delta;
548 } else {
549 sz = 256;
550 while (sz < funcbufsize - funcbufleft + delta)
551 sz <<= 1;
552 fnw = (char *) kmalloc(sz, GFP_KERNEL);
553 if(!fnw)
554 return -ENOMEM;
555
556 if (!q)
557 func_table[i] = fj;
558 if (fj > funcbufptr)
559 memmove(fnw, funcbufptr, fj - funcbufptr);
560 for (k = 0; k < j; k++)
561 if (func_table[k])
562 func_table[k] = fnw + (func_table[k] - funcbufptr);
563
564 if (first_free > fj) {
565 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
566 for (k = j; k < MAX_NR_FUNC; k++)
567 if (func_table[k])
568 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
569 }
570 if (funcbufptr != func_buf)
571 kfree_s(funcbufptr, funcbufsize);
572 funcbufptr = fnw;
573 funcbufleft = funcbufleft - delta + sz - funcbufsize;
574 funcbufsize = sz;
575 }
576 for (p = a->kb_string, q = func_table[i]; ; p++, q++)
577 if (!(*q = get_fs_byte(p)))
578 break;
579 return 0;
580 }
581
582 case KDGKBDIACR:
583 {
584 struct kbdiacrs *a = (struct kbdiacrs *)arg;
585
586 i = verify_area(VERIFY_WRITE, (void *) a, sizeof(struct kbdiacrs));
587 if (i)
588 return i;
589 put_fs_long(accent_table_size, &a->kb_cnt);
590 memcpy_tofs(a->kbdiacr, accent_table,
591 accent_table_size*sizeof(struct kbdiacr));
592 return 0;
593 }
594
595 case KDSKBDIACR:
596 {
597 struct kbdiacrs *a = (struct kbdiacrs *)arg;
598 unsigned int ct;
599
600 if (!perm)
601 return -EPERM;
602 i = verify_area(VERIFY_READ, (void *) a, sizeof(struct kbdiacrs));
603 if (i)
604 return i;
605 ct = get_fs_long(&a->kb_cnt);
606 if (ct >= MAX_DIACR)
607 return -EINVAL;
608 accent_table_size = ct;
609 memcpy_fromfs(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr));
610 return 0;
611 }
612
613
614
615 case KDGKBLED:
616 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned char));
617 if (i)
618 return i;
619 put_fs_byte(kbd->ledflagstate |
620 (kbd->default_ledflagstate << 4), (char *) arg);
621 return 0;
622
623 case KDSKBLED:
624 if (!perm)
625 return -EPERM;
626 if (arg & ~0x77)
627 return -EINVAL;
628 kbd->ledflagstate = (arg & 7);
629 kbd->default_ledflagstate = ((arg >> 4) & 7);
630 set_leds();
631 return 0;
632
633
634
635 case KDGETLED:
636 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned char));
637 if (i)
638 return i;
639 put_fs_byte(getledstate(), (char *) arg);
640 return 0;
641
642 case KDSETLED:
643 if (!perm)
644 return -EPERM;
645 setledstate(kbd, arg);
646 return 0;
647
648
649
650
651
652
653
654
655
656
657
658 case KDSIGACCEPT:
659 {
660 extern int spawnpid, spawnsig;
661 if (!perm)
662 return -EPERM;
663 if (arg < 1 || arg > NSIG || arg == SIGKILL)
664 return -EINVAL;
665 spawnpid = current->pid;
666 spawnsig = arg;
667 return 0;
668 }
669
670 case VT_SETMODE:
671 {
672 struct vt_mode *vtmode = (struct vt_mode *)arg;
673 char mode;
674
675 if (!perm)
676 return -EPERM;
677 i = verify_area(VERIFY_WRITE, (void *)vtmode, sizeof(struct vt_mode));
678 if (i)
679 return i;
680 mode = get_fs_byte(&vtmode->mode);
681 if (mode != VT_AUTO && mode != VT_PROCESS)
682 return -EINVAL;
683 vt_cons[console]->vt_mode.mode = mode;
684 vt_cons[console]->vt_mode.waitv = get_fs_byte(&vtmode->waitv);
685 vt_cons[console]->vt_mode.relsig = get_fs_word(&vtmode->relsig);
686 vt_cons[console]->vt_mode.acqsig = get_fs_word(&vtmode->acqsig);
687
688 vt_cons[console]->vt_mode.frsig = 0;
689 vt_cons[console]->vt_pid = current->pid;
690 vt_cons[console]->vt_newvt = 0;
691 return 0;
692 }
693
694 case VT_GETMODE:
695 {
696 struct vt_mode *vtmode = (struct vt_mode *)arg;
697
698 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct vt_mode));
699 if (i)
700 return i;
701 put_fs_byte(vt_cons[console]->vt_mode.mode, &vtmode->mode);
702 put_fs_byte(vt_cons[console]->vt_mode.waitv, &vtmode->waitv);
703 put_fs_word(vt_cons[console]->vt_mode.relsig, &vtmode->relsig);
704 put_fs_word(vt_cons[console]->vt_mode.acqsig, &vtmode->acqsig);
705 put_fs_word(vt_cons[console]->vt_mode.frsig, &vtmode->frsig);
706 return 0;
707 }
708
709
710
711
712
713
714 case VT_GETSTATE:
715 {
716 struct vt_stat *vtstat = (struct vt_stat *)arg;
717 unsigned short state, mask;
718
719 i = verify_area(VERIFY_WRITE,(void *)vtstat, sizeof(struct vt_stat));
720 if (i)
721 return i;
722 put_fs_word(fg_console + 1, &vtstat->v_active);
723 state = 1;
724 for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask; ++i, mask <<= 1)
725 if (VT_IS_IN_USE(i))
726 state |= mask;
727 put_fs_word(state, &vtstat->v_state);
728 return 0;
729 }
730
731
732
733
734 case VT_OPENQRY:
735 i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
736 if (i)
737 return i;
738 for (i = 0; i < MAX_NR_CONSOLES; ++i)
739 if (! VT_IS_IN_USE(i))
740 break;
741 put_fs_long(i < MAX_NR_CONSOLES ? (i+1) : -1,
742 (unsigned long *)arg);
743 return 0;
744
745
746
747
748
749
750 case VT_ACTIVATE:
751 if (!perm)
752 return -EPERM;
753 if (arg == 0 || arg > MAX_NR_CONSOLES)
754 return -ENXIO;
755 arg--;
756 i = vc_allocate(arg);
757 if (i)
758 return i;
759 change_console(arg);
760 return 0;
761
762
763
764
765 case VT_WAITACTIVE:
766 if (!perm)
767 return -EPERM;
768 if (arg == 0 || arg > MAX_NR_CONSOLES)
769 return -ENXIO;
770 arg--;
771 while (fg_console != arg)
772 {
773 if (vt_waitactive() < 0)
774 return -EINTR;
775 }
776 return 0;
777
778
779
780
781
782
783
784
785
786
787
788 case VT_RELDISP:
789 if (!perm)
790 return -EPERM;
791 if (vt_cons[console]->vt_mode.mode != VT_PROCESS)
792 return -EINVAL;
793
794
795
796
797 if (vt_cons[console]->vt_newvt >= 0)
798 {
799 if (arg == 0)
800
801
802
803
804 vt_cons[console]->vt_newvt = -1;
805
806 else
807 {
808
809
810
811
812 int newvt = vt_cons[console]->vt_newvt;
813 vt_cons[console]->vt_newvt = -1;
814 i = vc_allocate(newvt);
815 if (i)
816 return i;
817 complete_change_console(newvt);
818 }
819 }
820
821
822
823
824 else
825 {
826
827
828
829 if (arg != VT_ACKACQ)
830 return -EINVAL;
831 }
832
833 return 0;
834
835
836
837
838 case VT_DISALLOCATE:
839 if (arg > MAX_NR_CONSOLES)
840 return -ENXIO;
841 if (arg == 0) {
842
843 for (i=1; i<MAX_NR_CONSOLES; i++)
844 if (! VT_BUSY(i))
845 vc_disallocate(i);
846 } else {
847
848 arg--;
849 if (VT_BUSY(arg))
850 return -EBUSY;
851 if (arg)
852 vc_disallocate(arg);
853 }
854 return 0;
855
856 case VT_RESIZE:
857 {
858 struct vt_sizes *vtsizes = (struct vt_sizes *) arg;
859 ushort ll,cc;
860 if (!perm)
861 return -EPERM;
862 i = verify_area(VERIFY_READ, (void *)vtsizes, sizeof(struct vt_sizes));
863 if (i)
864 return i;
865 ll = get_fs_word(&vtsizes->v_rows);
866 cc = get_fs_word(&vtsizes->v_cols);
867 return vc_resize(ll, cc);
868 }
869
870 case PIO_FONT:
871 if (!perm)
872 return -EPERM;
873 if (vt_cons[fg_console]->vc_mode != KD_TEXT)
874 return -EINVAL;
875 return con_set_font((char *)arg, 0);
876
877
878 case GIO_FONT:
879 if (vt_cons[fg_console]->vc_mode != KD_TEXT ||
880 video_mode_512ch)
881 return -EINVAL;
882 return con_get_font((char *)arg);
883
884
885 case PIO_FONTX:
886 {
887 struct consolefontdesc cfdarg;
888
889 if (!perm)
890 return -EPERM;
891 if (vt_cons[fg_console]->vc_mode != KD_TEXT)
892 return -EINVAL;
893 i = verify_area(VERIFY_READ, (void *)arg,
894 sizeof(struct consolefontdesc));
895 if (i) return i;
896 memcpy_fromfs(&cfdarg, (void *)arg,
897 sizeof(struct consolefontdesc));
898
899 if ( cfdarg.charcount == 256 ||
900 cfdarg.charcount == 512 ) {
901 i = con_set_font(cfdarg.chardata,
902 cfdarg.charcount == 512);
903 if (i)
904 return i;
905 i = con_adjust_height(cfdarg.charheight);
906 if (i <= 0) return i;
907 kd_size_changed(i, 0);
908 return 0;
909 } else
910 return -EINVAL;
911 }
912
913 case GIO_FONTX:
914 {
915 struct consolefontdesc cfdarg;
916 int nchar;
917
918 if (vt_cons[fg_console]->vc_mode != KD_TEXT)
919 return -EINVAL;
920 i = verify_area(VERIFY_WRITE, (void *)arg,
921 sizeof(struct consolefontdesc));
922 if (i) return i;
923 memcpy_fromfs(&cfdarg, (void *) arg,
924 sizeof(struct consolefontdesc));
925 i = cfdarg.charcount;
926 cfdarg.charcount = nchar = video_mode_512ch ? 512 : 256;
927 cfdarg.charheight = video_font_height;
928 memcpy_tofs((void *) arg, &cfdarg,
929 sizeof(struct consolefontdesc));
930 if ( cfdarg.chardata )
931 {
932 if ( i < nchar )
933 return -ENOMEM;
934 return con_get_font(cfdarg.chardata);
935 } else
936 return 0;
937 }
938
939 case PIO_SCRNMAP:
940 if (!perm)
941 return -EPERM;
942 return con_set_trans_old((char *)arg);
943
944 case GIO_SCRNMAP:
945 return con_get_trans_old((char *)arg);
946
947 case PIO_UNISCRNMAP:
948 if (!perm)
949 return -EPERM;
950 return con_set_trans_new((unsigned short *)arg);
951
952 case GIO_UNISCRNMAP:
953 return con_get_trans_new((unsigned short *)arg);
954
955 case PIO_UNIMAPCLR:
956 { struct unimapinit ui;
957 if (!perm)
958 return -EPERM;
959 i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapinit));
960 if (i)
961 return i;
962 memcpy_fromfs(&ui, (void *)arg, sizeof(struct unimapinit));
963 con_clear_unimap(&ui);
964 return 0;
965 }
966
967 case PIO_UNIMAP:
968 { struct unimapdesc *ud;
969 u_short ct;
970 struct unipair *list;
971
972 if (!perm)
973 return -EPERM;
974 i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapdesc));
975 if (i == 0) {
976 ud = (struct unimapdesc *) arg;
977 ct = get_fs_word(&ud->entry_ct);
978 list = (struct unipair *) get_fs_long(&ud->entries);
979 i = verify_area(VERIFY_READ, (void *) list,
980 ct*sizeof(struct unipair));
981 }
982 if (i)
983 return i;
984 return con_set_unimap(ct, list);
985 }
986
987 case GIO_UNIMAP:
988 { struct unimapdesc *ud;
989 u_short ct;
990 struct unipair *list;
991
992 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct unimapdesc));
993 if (i == 0) {
994 ud = (struct unimapdesc *) arg;
995 ct = get_fs_word(&ud->entry_ct);
996 list = (struct unipair *) get_fs_long(&ud->entries);
997 if (ct)
998 i = verify_area(VERIFY_WRITE, (void *) list,
999 ct*sizeof(struct unipair));
1000 }
1001 if (i)
1002 return i;
1003 return con_get_unimap(ct, &(ud->entry_ct), list);
1004 }
1005
1006 default:
1007 return -ENOIOCTLCMD;
1008 }
1009 }