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