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