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