OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [char/] [vt_ioctl.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  linux/drivers/char/vt_ioctl.c
3
 *
4
 *  Copyright (C) 1992 obz under the linux copyright
5
 *
6
 *  Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
7
 *  Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
8
 *  Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
9
 *  Some code moved for less code duplication - Andi Kleen - Mar 1997
10
 *  Check put/get_user, cleanups - acme@conectiva.com.br - Jun 2001
11
 */
12
 
13
#include <linux/types.h>
14
#include <linux/errno.h>
15
#include <linux/sched.h>
16
#include <linux/tty.h>
17
#include <linux/timer.h>
18
#include <linux/kernel.h>
19
#include <linux/kd.h>
20
#include <linux/vt.h>
21
#include <linux/string.h>
22
#include <linux/slab.h>
23
#include <linux/major.h>
24
#include <linux/fs.h>
25
#include <linux/console.h>
26
#include <linux/consolemap.h>
27
#include <linux/signal.h>
28
#include <linux/timex.h>
29
 
30
#include <asm/io.h>
31
#include <asm/uaccess.h>
32
 
33
#include <linux/kbd_kern.h>
34
#include <linux/vt_kern.h>
35
#include <linux/kbd_diacr.h>
36
#include <linux/selection.h>
37
 
38
char vt_dont_switch;
39
extern struct tty_driver *console_driver;
40
 
41
#define VT_IS_IN_USE(i) (console_driver->ttys[i] && console_driver->ttys[i]->count)
42
#define VT_BUSY(i)      (VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
43
 
44
/*
45
 * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
46
 * experimentation and study of X386 SYSV handling.
47
 *
48
 * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
49
 * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
50
 * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
51
 * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
52
 * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
53
 * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
54
 * to the current console is done by the main ioctl code.
55
 */
56
 
57
#ifdef CONFIG_X86
58
#include <linux/syscalls.h>
59
#endif
60
 
61
static void complete_change_console(struct vc_data *vc);
62
 
63
/*
64
 * these are the valid i/o ports we're allowed to change. they map all the
65
 * video ports
66
 */
67
#define GPFIRST 0x3b4
68
#define GPLAST 0x3df
69
#define GPNUM (GPLAST - GPFIRST + 1)
70
 
71
#define i (tmp.kb_index)
72
#define s (tmp.kb_table)
73
#define v (tmp.kb_value)
74
static inline int
75
do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_struct *kbd)
76
{
77
        struct kbentry tmp;
78
        ushort *key_map, val, ov;
79
 
80
        if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
81
                return -EFAULT;
82
 
83
        if (!capable(CAP_SYS_TTY_CONFIG))
84
                perm = 0;
85
 
86
        switch (cmd) {
87
        case KDGKBENT:
88
                key_map = key_maps[s];
89
                if (key_map) {
90
                    val = U(key_map[i]);
91
                    if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
92
                        val = K_HOLE;
93
                } else
94
                    val = (i ? K_HOLE : K_NOSUCHMAP);
95
                return put_user(val, &user_kbe->kb_value);
96
        case KDSKBENT:
97
                if (!perm)
98
                        return -EPERM;
99
                if (!i && v == K_NOSUCHMAP) {
100
                        /* deallocate map */
101
                        key_map = key_maps[s];
102
                        if (s && key_map) {
103
                            key_maps[s] = NULL;
104
                            if (key_map[0] == U(K_ALLOCATED)) {
105
                                        kfree(key_map);
106
                                        keymap_count--;
107
                            }
108
                        }
109
                        break;
110
                }
111
 
112
                if (KTYP(v) < NR_TYPES) {
113
                    if (KVAL(v) > max_vals[KTYP(v)])
114
                                return -EINVAL;
115
                } else
116
                    if (kbd->kbdmode != VC_UNICODE)
117
                                return -EINVAL;
118
 
119
                /* ++Geert: non-PC keyboards may generate keycode zero */
120
#if !defined(__mc68000__) && !defined(__powerpc__)
121
                /* assignment to entry 0 only tests validity of args */
122
                if (!i)
123
                        break;
124
#endif
125
 
126
                if (!(key_map = key_maps[s])) {
127
                        int j;
128
 
129
                        if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
130
                            !capable(CAP_SYS_RESOURCE))
131
                                return -EPERM;
132
 
133
                        key_map = kmalloc(sizeof(plain_map),
134
                                                     GFP_KERNEL);
135
                        if (!key_map)
136
                                return -ENOMEM;
137
                        key_maps[s] = key_map;
138
                        key_map[0] = U(K_ALLOCATED);
139
                        for (j = 1; j < NR_KEYS; j++)
140
                                key_map[j] = U(K_HOLE);
141
                        keymap_count++;
142
                }
143
                ov = U(key_map[i]);
144
                if (v == ov)
145
                        break;  /* nothing to do */
146
                /*
147
                 * Attention Key.
148
                 */
149
                if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN))
150
                        return -EPERM;
151
                key_map[i] = U(v);
152
                if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
153
                        compute_shiftstate();
154
                break;
155
        }
156
        return 0;
157
}
158
#undef i
159
#undef s
160
#undef v
161
 
162
static inline int
163
do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, int perm)
164
{
165
        struct kbkeycode tmp;
166
        int kc = 0;
167
 
168
        if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
169
                return -EFAULT;
170
        switch (cmd) {
171
        case KDGETKEYCODE:
172
                kc = getkeycode(tmp.scancode);
173
                if (kc >= 0)
174
                        kc = put_user(kc, &user_kbkc->keycode);
175
                break;
176
        case KDSETKEYCODE:
177
                if (!perm)
178
                        return -EPERM;
179
                kc = setkeycode(tmp.scancode, tmp.keycode);
180
                break;
181
        }
182
        return kc;
183
}
184
 
185
static inline int
186
do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
187
{
188
        struct kbsentry *kbs;
189
        char *p;
190
        u_char *q;
191
        u_char __user *up;
192
        int sz;
193
        int delta;
194
        char *first_free, *fj, *fnw;
195
        int i, j, k;
196
        int ret;
197
 
198
        if (!capable(CAP_SYS_TTY_CONFIG))
199
                perm = 0;
200
 
201
        kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
202
        if (!kbs) {
203
                ret = -ENOMEM;
204
                goto reterr;
205
        }
206
 
207
        /* we mostly copy too much here (512bytes), but who cares ;) */
208
        if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
209
                ret = -EFAULT;
210
                goto reterr;
211
        }
212
        kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
213
        i = kbs->kb_func;
214
 
215
        switch (cmd) {
216
        case KDGKBSENT:
217
                sz = sizeof(kbs->kb_string) - 1; /* sz should have been
218
                                                  a struct member */
219
                up = user_kdgkb->kb_string;
220
                p = func_table[i];
221
                if(p)
222
                        for ( ; *p && sz; p++, sz--)
223
                                if (put_user(*p, up++)) {
224
                                        ret = -EFAULT;
225
                                        goto reterr;
226
                                }
227
                if (put_user('\0', up)) {
228
                        ret = -EFAULT;
229
                        goto reterr;
230
                }
231
                kfree(kbs);
232
                return ((p && *p) ? -EOVERFLOW : 0);
233
        case KDSKBSENT:
234
                if (!perm) {
235
                        ret = -EPERM;
236
                        goto reterr;
237
                }
238
 
239
                q = func_table[i];
240
                first_free = funcbufptr + (funcbufsize - funcbufleft);
241
                for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
242
                        ;
243
                if (j < MAX_NR_FUNC)
244
                        fj = func_table[j];
245
                else
246
                        fj = first_free;
247
 
248
                delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
249
                if (delta <= funcbufleft) {     /* it fits in current buf */
250
                    if (j < MAX_NR_FUNC) {
251
                        memmove(fj + delta, fj, first_free - fj);
252
                        for (k = j; k < MAX_NR_FUNC; k++)
253
                            if (func_table[k])
254
                                func_table[k] += delta;
255
                    }
256
                    if (!q)
257
                      func_table[i] = fj;
258
                    funcbufleft -= delta;
259
                } else {                        /* allocate a larger buffer */
260
                    sz = 256;
261
                    while (sz < funcbufsize - funcbufleft + delta)
262
                      sz <<= 1;
263
                    fnw = kmalloc(sz, GFP_KERNEL);
264
                    if(!fnw) {
265
                      ret = -ENOMEM;
266
                      goto reterr;
267
                    }
268
 
269
                    if (!q)
270
                      func_table[i] = fj;
271
                    if (fj > funcbufptr)
272
                        memmove(fnw, funcbufptr, fj - funcbufptr);
273
                    for (k = 0; k < j; k++)
274
                      if (func_table[k])
275
                        func_table[k] = fnw + (func_table[k] - funcbufptr);
276
 
277
                    if (first_free > fj) {
278
                        memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
279
                        for (k = j; k < MAX_NR_FUNC; k++)
280
                          if (func_table[k])
281
                            func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
282
                    }
283
                    if (funcbufptr != func_buf)
284
                      kfree(funcbufptr);
285
                    funcbufptr = fnw;
286
                    funcbufleft = funcbufleft - delta + sz - funcbufsize;
287
                    funcbufsize = sz;
288
                }
289
                strcpy(func_table[i], kbs->kb_string);
290
                break;
291
        }
292
        ret = 0;
293
reterr:
294
        kfree(kbs);
295
        return ret;
296
}
297
 
298
static inline int
299
do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
300
{
301
        struct consolefontdesc cfdarg;
302
        int i;
303
 
304
        if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc)))
305
                return -EFAULT;
306
 
307
        switch (cmd) {
308
        case PIO_FONTX:
309
                if (!perm)
310
                        return -EPERM;
311
                op->op = KD_FONT_OP_SET;
312
                op->flags = KD_FONT_FLAG_OLD;
313
                op->width = 8;
314
                op->height = cfdarg.charheight;
315
                op->charcount = cfdarg.charcount;
316
                op->data = cfdarg.chardata;
317
                return con_font_op(vc_cons[fg_console].d, op);
318
        case GIO_FONTX: {
319
                op->op = KD_FONT_OP_GET;
320
                op->flags = KD_FONT_FLAG_OLD;
321
                op->width = 8;
322
                op->height = cfdarg.charheight;
323
                op->charcount = cfdarg.charcount;
324
                op->data = cfdarg.chardata;
325
                i = con_font_op(vc_cons[fg_console].d, op);
326
                if (i)
327
                        return i;
328
                cfdarg.charheight = op->height;
329
                cfdarg.charcount = op->charcount;
330
                if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
331
                        return -EFAULT;
332
                return 0;
333
                }
334
        }
335
        return -EINVAL;
336
}
337
 
338
static inline int
339
do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc)
340
{
341
        struct unimapdesc tmp;
342
 
343
        if (copy_from_user(&tmp, user_ud, sizeof tmp))
344
                return -EFAULT;
345
        if (tmp.entries)
346
                if (!access_ok(VERIFY_WRITE, tmp.entries,
347
                                tmp.entry_ct*sizeof(struct unipair)))
348
                        return -EFAULT;
349
        switch (cmd) {
350
        case PIO_UNIMAP:
351
                if (!perm)
352
                        return -EPERM;
353
                return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
354
        case GIO_UNIMAP:
355
                if (!perm && fg_console != vc->vc_num)
356
                        return -EPERM;
357
                return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
358
        }
359
        return 0;
360
}
361
 
362
/*
363
 * We handle the console-specific ioctl's here.  We allow the
364
 * capability to modify any console, not just the fg_console.
365
 */
366
int vt_ioctl(struct tty_struct *tty, struct file * file,
367
             unsigned int cmd, unsigned long arg)
368
{
369
        struct vc_data *vc = (struct vc_data *)tty->driver_data;
370
        struct console_font_op op;      /* used in multiple places here */
371
        struct kbd_struct * kbd;
372
        unsigned int console;
373
        unsigned char ucval;
374
        void __user *up = (void __user *)arg;
375
        int i, perm;
376
 
377
        console = vc->vc_num;
378
 
379
        if (!vc_cons_allocated(console))        /* impossible? */
380
                return -ENOIOCTLCMD;
381
 
382
        /*
383
         * To have permissions to do most of the vt ioctls, we either have
384
         * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
385
         */
386
        perm = 0;
387
        if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
388
                perm = 1;
389
 
390
        kbd = kbd_table + console;
391
        switch (cmd) {
392
        case KIOCSOUND:
393
                if (!perm)
394
                        return -EPERM;
395
                if (arg)
396
                        arg = CLOCK_TICK_RATE / arg;
397
                kd_mksound(arg, 0);
398
                return 0;
399
 
400
        case KDMKTONE:
401
                if (!perm)
402
                        return -EPERM;
403
        {
404
                unsigned int ticks, count;
405
 
406
                /*
407
                 * Generate the tone for the appropriate number of ticks.
408
                 * If the time is zero, turn off sound ourselves.
409
                 */
410
                ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
411
                count = ticks ? (arg & 0xffff) : 0;
412
                if (count)
413
                        count = CLOCK_TICK_RATE / count;
414
                kd_mksound(count, ticks);
415
                return 0;
416
        }
417
 
418
        case KDGKBTYPE:
419
                /*
420
                 * this is naive.
421
                 */
422
                ucval = KB_101;
423
                goto setchar;
424
 
425
                /*
426
                 * These cannot be implemented on any machine that implements
427
                 * ioperm() in user level (such as Alpha PCs) or not at all.
428
                 *
429
                 * XXX: you should never use these, just call ioperm directly..
430
                 */
431
#ifdef CONFIG_X86
432
        case KDADDIO:
433
        case KDDELIO:
434
                /*
435
                 * KDADDIO and KDDELIO may be able to add ports beyond what
436
                 * we reject here, but to be safe...
437
                 */
438
                if (arg < GPFIRST || arg > GPLAST)
439
                        return -EINVAL;
440
                return sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
441
 
442
        case KDENABIO:
443
        case KDDISABIO:
444
                return sys_ioperm(GPFIRST, GPNUM,
445
                                  (cmd == KDENABIO)) ? -ENXIO : 0;
446
#endif
447
 
448
        /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */
449
 
450
        case KDKBDREP:
451
        {
452
                struct kbd_repeat kbrep;
453
                int err;
454
 
455
                if (!capable(CAP_SYS_TTY_CONFIG))
456
                        return -EPERM;
457
 
458
                if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat)))
459
                        return -EFAULT;
460
                err = kbd_rate(&kbrep);
461
                if (err)
462
                        return err;
463
                if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat)))
464
                        return -EFAULT;
465
                return 0;
466
        }
467
 
468
        case KDSETMODE:
469
                /*
470
                 * currently, setting the mode from KD_TEXT to KD_GRAPHICS
471
                 * doesn't do a whole lot. i'm not sure if it should do any
472
                 * restoration of modes or what...
473
                 *
474
                 * XXX It should at least call into the driver, fbdev's definitely
475
                 * need to restore their engine state. --BenH
476
                 */
477
                if (!perm)
478
                        return -EPERM;
479
                switch (arg) {
480
                case KD_GRAPHICS:
481
                        break;
482
                case KD_TEXT0:
483
                case KD_TEXT1:
484
                        arg = KD_TEXT;
485
                case KD_TEXT:
486
                        break;
487
                default:
488
                        return -EINVAL;
489
                }
490
                if (vc->vc_mode == (unsigned char) arg)
491
                        return 0;
492
                vc->vc_mode = (unsigned char) arg;
493
                if (console != fg_console)
494
                        return 0;
495
                /*
496
                 * explicitly blank/unblank the screen if switching modes
497
                 */
498
                acquire_console_sem();
499
                if (arg == KD_TEXT)
500
                        do_unblank_screen(1);
501
                else
502
                        do_blank_screen(1);
503
                release_console_sem();
504
                return 0;
505
 
506
        case KDGETMODE:
507
                ucval = vc->vc_mode;
508
                goto setint;
509
 
510
        case KDMAPDISP:
511
        case KDUNMAPDISP:
512
                /*
513
                 * these work like a combination of mmap and KDENABIO.
514
                 * this could be easily finished.
515
                 */
516
                return -EINVAL;
517
 
518
        case KDSKBMODE:
519
                if (!perm)
520
                        return -EPERM;
521
                switch(arg) {
522
                  case K_RAW:
523
                        kbd->kbdmode = VC_RAW;
524
                        break;
525
                  case K_MEDIUMRAW:
526
                        kbd->kbdmode = VC_MEDIUMRAW;
527
                        break;
528
                  case K_XLATE:
529
                        kbd->kbdmode = VC_XLATE;
530
                        compute_shiftstate();
531
                        break;
532
                  case K_UNICODE:
533
                        kbd->kbdmode = VC_UNICODE;
534
                        compute_shiftstate();
535
                        break;
536
                  default:
537
                        return -EINVAL;
538
                }
539
                tty_ldisc_flush(tty);
540
                return 0;
541
 
542
        case KDGKBMODE:
543
                ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW :
544
                                 (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
545
                                 (kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
546
                                 K_XLATE);
547
                goto setint;
548
 
549
        /* this could be folded into KDSKBMODE, but for compatibility
550
           reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
551
        case KDSKBMETA:
552
                switch(arg) {
553
                  case K_METABIT:
554
                        clr_vc_kbd_mode(kbd, VC_META);
555
                        break;
556
                  case K_ESCPREFIX:
557
                        set_vc_kbd_mode(kbd, VC_META);
558
                        break;
559
                  default:
560
                        return -EINVAL;
561
                }
562
                return 0;
563
 
564
        case KDGKBMETA:
565
                ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
566
        setint:
567
                return put_user(ucval, (int __user *)arg);
568
 
569
        case KDGETKEYCODE:
570
        case KDSETKEYCODE:
571
                if(!capable(CAP_SYS_TTY_CONFIG))
572
                        perm=0;
573
                return do_kbkeycode_ioctl(cmd, up, perm);
574
 
575
        case KDGKBENT:
576
        case KDSKBENT:
577
                return do_kdsk_ioctl(cmd, up, perm, kbd);
578
 
579
        case KDGKBSENT:
580
        case KDSKBSENT:
581
                return do_kdgkb_ioctl(cmd, up, perm);
582
 
583
        case KDGKBDIACR:
584
        {
585
                struct kbdiacrs __user *a = up;
586
                struct kbdiacr diacr;
587
                int i;
588
 
589
                if (put_user(accent_table_size, &a->kb_cnt))
590
                        return -EFAULT;
591
                for (i = 0; i < accent_table_size; i++) {
592
                        diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr);
593
                        diacr.base = conv_uni_to_8bit(accent_table[i].base);
594
                        diacr.result = conv_uni_to_8bit(accent_table[i].result);
595
                        if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr)))
596
                                return -EFAULT;
597
                }
598
                return 0;
599
        }
600
        case KDGKBDIACRUC:
601
        {
602
                struct kbdiacrsuc __user *a = up;
603
 
604
                if (put_user(accent_table_size, &a->kb_cnt))
605
                        return -EFAULT;
606
                if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc)))
607
                        return -EFAULT;
608
                return 0;
609
        }
610
 
611
        case KDSKBDIACR:
612
        {
613
                struct kbdiacrs __user *a = up;
614
                struct kbdiacr diacr;
615
                unsigned int ct;
616
                int i;
617
 
618
                if (!perm)
619
                        return -EPERM;
620
                if (get_user(ct,&a->kb_cnt))
621
                        return -EFAULT;
622
                if (ct >= MAX_DIACR)
623
                        return -EINVAL;
624
                accent_table_size = ct;
625
                for (i = 0; i < ct; i++) {
626
                        if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr)))
627
                                return -EFAULT;
628
                        accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr);
629
                        accent_table[i].base = conv_8bit_to_uni(diacr.base);
630
                        accent_table[i].result = conv_8bit_to_uni(diacr.result);
631
                }
632
                return 0;
633
        }
634
 
635
        case KDSKBDIACRUC:
636
        {
637
                struct kbdiacrsuc __user *a = up;
638
                unsigned int ct;
639
 
640
                if (!perm)
641
                        return -EPERM;
642
                if (get_user(ct,&a->kb_cnt))
643
                        return -EFAULT;
644
                if (ct >= MAX_DIACR)
645
                        return -EINVAL;
646
                accent_table_size = ct;
647
                if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
648
                        return -EFAULT;
649
                return 0;
650
        }
651
 
652
        /* the ioctls below read/set the flags usually shown in the leds */
653
        /* don't use them - they will go away without warning */
654
        case KDGKBLED:
655
                ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
656
                goto setchar;
657
 
658
        case KDSKBLED:
659
                if (!perm)
660
                        return -EPERM;
661
                if (arg & ~0x77)
662
                        return -EINVAL;
663
                kbd->ledflagstate = (arg & 7);
664
                kbd->default_ledflagstate = ((arg >> 4) & 7);
665
                set_leds();
666
                return 0;
667
 
668
        /* the ioctls below only set the lights, not the functions */
669
        /* for those, see KDGKBLED and KDSKBLED above */
670
        case KDGETLED:
671
                ucval = getledstate();
672
        setchar:
673
                return put_user(ucval, (char __user *)arg);
674
 
675
        case KDSETLED:
676
                if (!perm)
677
                  return -EPERM;
678
                setledstate(kbd, arg);
679
                return 0;
680
 
681
        /*
682
         * A process can indicate its willingness to accept signals
683
         * generated by pressing an appropriate key combination.
684
         * Thus, one can have a daemon that e.g. spawns a new console
685
         * upon a keypress and then changes to it.
686
         * See also the kbrequest field of inittab(5).
687
         */
688
        case KDSIGACCEPT:
689
        {
690
                if (!perm || !capable(CAP_KILL))
691
                  return -EPERM;
692
                if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
693
                  return -EINVAL;
694
 
695
                spin_lock_irq(&vt_spawn_con.lock);
696
                put_pid(vt_spawn_con.pid);
697
                vt_spawn_con.pid = get_pid(task_pid(current));
698
                vt_spawn_con.sig = arg;
699
                spin_unlock_irq(&vt_spawn_con.lock);
700
                return 0;
701
        }
702
 
703
        case VT_SETMODE:
704
        {
705
                struct vt_mode tmp;
706
 
707
                if (!perm)
708
                        return -EPERM;
709
                if (copy_from_user(&tmp, up, sizeof(struct vt_mode)))
710
                        return -EFAULT;
711
                if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS)
712
                        return -EINVAL;
713
                acquire_console_sem();
714
                vc->vt_mode = tmp;
715
                /* the frsig is ignored, so we set it to 0 */
716
                vc->vt_mode.frsig = 0;
717
                put_pid(vc->vt_pid);
718
                vc->vt_pid = get_pid(task_pid(current));
719
                /* no switch is required -- saw@shade.msu.ru */
720
                vc->vt_newvt = -1;
721
                release_console_sem();
722
                return 0;
723
        }
724
 
725
        case VT_GETMODE:
726
        {
727
                struct vt_mode tmp;
728
                int rc;
729
 
730
                acquire_console_sem();
731
                memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
732
                release_console_sem();
733
 
734
                rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
735
                return rc ? -EFAULT : 0;
736
        }
737
 
738
        /*
739
         * Returns global vt state. Note that VT 0 is always open, since
740
         * it's an alias for the current VT, and people can't use it here.
741
         * We cannot return state for more than 16 VTs, since v_state is short.
742
         */
743
        case VT_GETSTATE:
744
        {
745
                struct vt_stat __user *vtstat = up;
746
                unsigned short state, mask;
747
 
748
                if (put_user(fg_console + 1, &vtstat->v_active))
749
                        return -EFAULT;
750
                state = 1;      /* /dev/tty0 is always open */
751
                for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask; ++i, mask <<= 1)
752
                        if (VT_IS_IN_USE(i))
753
                                state |= mask;
754
                return put_user(state, &vtstat->v_state);
755
        }
756
 
757
        /*
758
         * Returns the first available (non-opened) console.
759
         */
760
        case VT_OPENQRY:
761
                for (i = 0; i < MAX_NR_CONSOLES; ++i)
762
                        if (! VT_IS_IN_USE(i))
763
                                break;
764
                ucval = i < MAX_NR_CONSOLES ? (i+1) : -1;
765
                goto setint;
766
 
767
        /*
768
         * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num,
769
         * with num >= 1 (switches to vt 0, our console, are not allowed, just
770
         * to preserve sanity).
771
         */
772
        case VT_ACTIVATE:
773
                if (!perm)
774
                        return -EPERM;
775
                if (arg == 0 || arg > MAX_NR_CONSOLES)
776
                        return -ENXIO;
777
                arg--;
778
                acquire_console_sem();
779
                i = vc_allocate(arg);
780
                release_console_sem();
781
                if (i)
782
                        return i;
783
                set_console(arg);
784
                return 0;
785
 
786
        /*
787
         * wait until the specified VT has been activated
788
         */
789
        case VT_WAITACTIVE:
790
                if (!perm)
791
                        return -EPERM;
792
                if (arg == 0 || arg > MAX_NR_CONSOLES)
793
                        return -ENXIO;
794
                return vt_waitactive(arg-1);
795
 
796
        /*
797
         * If a vt is under process control, the kernel will not switch to it
798
         * immediately, but postpone the operation until the process calls this
799
         * ioctl, allowing the switch to complete.
800
         *
801
         * According to the X sources this is the behavior:
802
         *      0:      pending switch-from not OK
803
         *      1:      pending switch-from OK
804
         *      2:      completed switch-to OK
805
         */
806
        case VT_RELDISP:
807
                if (!perm)
808
                        return -EPERM;
809
                if (vc->vt_mode.mode != VT_PROCESS)
810
                        return -EINVAL;
811
 
812
                /*
813
                 * Switching-from response
814
                 */
815
                acquire_console_sem();
816
                if (vc->vt_newvt >= 0) {
817
                        if (arg == 0)
818
                                /*
819
                                 * Switch disallowed, so forget we were trying
820
                                 * to do it.
821
                                 */
822
                                vc->vt_newvt = -1;
823
 
824
                        else {
825
                                /*
826
                                 * The current vt has been released, so
827
                                 * complete the switch.
828
                                 */
829
                                int newvt;
830
                                newvt = vc->vt_newvt;
831
                                vc->vt_newvt = -1;
832
                                i = vc_allocate(newvt);
833
                                if (i) {
834
                                        release_console_sem();
835
                                        return i;
836
                                }
837
                                /*
838
                                 * When we actually do the console switch,
839
                                 * make sure we are atomic with respect to
840
                                 * other console switches..
841
                                 */
842
                                complete_change_console(vc_cons[newvt].d);
843
                        }
844
                }
845
 
846
                /*
847
                 * Switched-to response
848
                 */
849
                else
850
                {
851
                        /*
852
                         * If it's just an ACK, ignore it
853
                         */
854
                        if (arg != VT_ACKACQ) {
855
                                release_console_sem();
856
                                return -EINVAL;
857
                        }
858
                }
859
                release_console_sem();
860
 
861
                return 0;
862
 
863
         /*
864
          * Disallocate memory associated to VT (but leave VT1)
865
          */
866
         case VT_DISALLOCATE:
867
                if (arg > MAX_NR_CONSOLES)
868
                        return -ENXIO;
869
                if (arg == 0) {
870
                    /* deallocate all unused consoles, but leave 0 */
871
                        acquire_console_sem();
872
                        for (i=1; i<MAX_NR_CONSOLES; i++)
873
                                if (! VT_BUSY(i))
874
                                        vc_deallocate(i);
875
                        release_console_sem();
876
                } else {
877
                        /* deallocate a single console, if possible */
878
                        arg--;
879
                        if (VT_BUSY(arg))
880
                                return -EBUSY;
881
                        if (arg) {                            /* leave 0 */
882
                                acquire_console_sem();
883
                                vc_deallocate(arg);
884
                                release_console_sem();
885
                        }
886
                }
887
                return 0;
888
 
889
        case VT_RESIZE:
890
        {
891
                struct vt_sizes __user *vtsizes = up;
892
                struct vc_data *vc;
893
 
894
                ushort ll,cc;
895
                if (!perm)
896
                        return -EPERM;
897
                if (get_user(ll, &vtsizes->v_rows) ||
898
                    get_user(cc, &vtsizes->v_cols))
899
                        return -EFAULT;
900
 
901
                for (i = 0; i < MAX_NR_CONSOLES; i++) {
902
                        vc = vc_cons[i].d;
903
 
904
                        if (vc) {
905
                                vc->vc_resize_user = 1;
906
                                vc_lock_resize(vc_cons[i].d, cc, ll);
907
                        }
908
                }
909
 
910
                return 0;
911
        }
912
 
913
        case VT_RESIZEX:
914
        {
915
                struct vt_consize __user *vtconsize = up;
916
                ushort ll,cc,vlin,clin,vcol,ccol;
917
                if (!perm)
918
                        return -EPERM;
919
                if (!access_ok(VERIFY_READ, vtconsize,
920
                                sizeof(struct vt_consize)))
921
                        return -EFAULT;
922
                __get_user(ll, &vtconsize->v_rows);
923
                __get_user(cc, &vtconsize->v_cols);
924
                __get_user(vlin, &vtconsize->v_vlin);
925
                __get_user(clin, &vtconsize->v_clin);
926
                __get_user(vcol, &vtconsize->v_vcol);
927
                __get_user(ccol, &vtconsize->v_ccol);
928
                vlin = vlin ? vlin : vc->vc_scan_lines;
929
                if (clin) {
930
                        if (ll) {
931
                                if (ll != vlin/clin)
932
                                        return -EINVAL; /* Parameters don't add up */
933
                        } else
934
                                ll = vlin/clin;
935
                }
936
                if (vcol && ccol) {
937
                        if (cc) {
938
                                if (cc != vcol/ccol)
939
                                        return -EINVAL;
940
                        } else
941
                                cc = vcol/ccol;
942
                }
943
 
944
                if (clin > 32)
945
                        return -EINVAL;
946
 
947
                for (i = 0; i < MAX_NR_CONSOLES; i++) {
948
                        if (!vc_cons[i].d)
949
                                continue;
950
                        acquire_console_sem();
951
                        if (vlin)
952
                                vc_cons[i].d->vc_scan_lines = vlin;
953
                        if (clin)
954
                                vc_cons[i].d->vc_font.height = clin;
955
                        vc_cons[i].d->vc_resize_user = 1;
956
                        vc_resize(vc_cons[i].d, cc, ll);
957
                        release_console_sem();
958
                }
959
                return 0;
960
        }
961
 
962
        case PIO_FONT: {
963
                if (!perm)
964
                        return -EPERM;
965
                op.op = KD_FONT_OP_SET;
966
                op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
967
                op.width = 8;
968
                op.height = 0;
969
                op.charcount = 256;
970
                op.data = up;
971
                return con_font_op(vc_cons[fg_console].d, &op);
972
        }
973
 
974
        case GIO_FONT: {
975
                op.op = KD_FONT_OP_GET;
976
                op.flags = KD_FONT_FLAG_OLD;
977
                op.width = 8;
978
                op.height = 32;
979
                op.charcount = 256;
980
                op.data = up;
981
                return con_font_op(vc_cons[fg_console].d, &op);
982
        }
983
 
984
        case PIO_CMAP:
985
                if (!perm)
986
                        return -EPERM;
987
                return con_set_cmap(up);
988
 
989
        case GIO_CMAP:
990
                return con_get_cmap(up);
991
 
992
        case PIO_FONTX:
993
        case GIO_FONTX:
994
                return do_fontx_ioctl(cmd, up, perm, &op);
995
 
996
        case PIO_FONTRESET:
997
        {
998
                if (!perm)
999
                        return -EPERM;
1000
 
1001
#ifdef BROKEN_GRAPHICS_PROGRAMS
1002
                /* With BROKEN_GRAPHICS_PROGRAMS defined, the default
1003
                   font is not saved. */
1004
                return -ENOSYS;
1005
#else
1006
                {
1007
                op.op = KD_FONT_OP_SET_DEFAULT;
1008
                op.data = NULL;
1009
                i = con_font_op(vc_cons[fg_console].d, &op);
1010
                if (i)
1011
                        return i;
1012
                con_set_default_unimap(vc_cons[fg_console].d);
1013
                return 0;
1014
                }
1015
#endif
1016
        }
1017
 
1018
        case KDFONTOP: {
1019
                if (copy_from_user(&op, up, sizeof(op)))
1020
                        return -EFAULT;
1021
                if (!perm && op.op != KD_FONT_OP_GET)
1022
                        return -EPERM;
1023
                i = con_font_op(vc, &op);
1024
                if (i) return i;
1025
                if (copy_to_user(up, &op, sizeof(op)))
1026
                        return -EFAULT;
1027
                return 0;
1028
        }
1029
 
1030
        case PIO_SCRNMAP:
1031
                if (!perm)
1032
                        return -EPERM;
1033
                return con_set_trans_old(up);
1034
 
1035
        case GIO_SCRNMAP:
1036
                return con_get_trans_old(up);
1037
 
1038
        case PIO_UNISCRNMAP:
1039
                if (!perm)
1040
                        return -EPERM;
1041
                return con_set_trans_new(up);
1042
 
1043
        case GIO_UNISCRNMAP:
1044
                return con_get_trans_new(up);
1045
 
1046
        case PIO_UNIMAPCLR:
1047
              { struct unimapinit ui;
1048
                if (!perm)
1049
                        return -EPERM;
1050
                i = copy_from_user(&ui, up, sizeof(struct unimapinit));
1051
                if (i) return -EFAULT;
1052
                con_clear_unimap(vc, &ui);
1053
                return 0;
1054
              }
1055
 
1056
        case PIO_UNIMAP:
1057
        case GIO_UNIMAP:
1058
                return do_unimap_ioctl(cmd, up, perm, vc);
1059
 
1060
        case VT_LOCKSWITCH:
1061
                if (!capable(CAP_SYS_TTY_CONFIG))
1062
                   return -EPERM;
1063
                vt_dont_switch = 1;
1064
                return 0;
1065
        case VT_UNLOCKSWITCH:
1066
                if (!capable(CAP_SYS_TTY_CONFIG))
1067
                   return -EPERM;
1068
                vt_dont_switch = 0;
1069
                return 0;
1070
        case VT_GETHIFONTMASK:
1071
                return put_user(vc->vc_hi_font_mask, (unsigned short __user *)arg);
1072
        default:
1073
                return -ENOIOCTLCMD;
1074
        }
1075
}
1076
 
1077
/*
1078
 * Sometimes we want to wait until a particular VT has been activated. We
1079
 * do it in a very simple manner. Everybody waits on a single queue and
1080
 * get woken up at once. Those that are satisfied go on with their business,
1081
 * while those not ready go back to sleep. Seems overkill to add a wait
1082
 * to each vt just for this - usually this does nothing!
1083
 */
1084
static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue);
1085
 
1086
/*
1087
 * Sleeps until a vt is activated, or the task is interrupted. Returns
1088
 * 0 if activation, -EINTR if interrupted by a signal handler.
1089
 */
1090
int vt_waitactive(int vt)
1091
{
1092
        int retval;
1093
        DECLARE_WAITQUEUE(wait, current);
1094
 
1095
        add_wait_queue(&vt_activate_queue, &wait);
1096
        for (;;) {
1097
                retval = 0;
1098
 
1099
                /*
1100
                 * Synchronize with redraw_screen(). By acquiring the console
1101
                 * semaphore we make sure that the console switch is completed
1102
                 * before we return. If we didn't wait for the semaphore, we
1103
                 * could return at a point where fg_console has already been
1104
                 * updated, but the console switch hasn't been completed.
1105
                 */
1106
                acquire_console_sem();
1107
                set_current_state(TASK_INTERRUPTIBLE);
1108
                if (vt == fg_console) {
1109
                        release_console_sem();
1110
                        break;
1111
                }
1112
                release_console_sem();
1113
                retval = -ERESTARTNOHAND;
1114
                if (signal_pending(current))
1115
                        break;
1116
                schedule();
1117
        }
1118
        remove_wait_queue(&vt_activate_queue, &wait);
1119
        __set_current_state(TASK_RUNNING);
1120
        return retval;
1121
}
1122
 
1123
#define vt_wake_waitactive() wake_up(&vt_activate_queue)
1124
 
1125
void reset_vc(struct vc_data *vc)
1126
{
1127
        vc->vc_mode = KD_TEXT;
1128
        kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
1129
        vc->vt_mode.mode = VT_AUTO;
1130
        vc->vt_mode.waitv = 0;
1131
        vc->vt_mode.relsig = 0;
1132
        vc->vt_mode.acqsig = 0;
1133
        vc->vt_mode.frsig = 0;
1134
        put_pid(vc->vt_pid);
1135
        vc->vt_pid = NULL;
1136
        vc->vt_newvt = -1;
1137
        if (!in_interrupt())    /* Via keyboard.c:SAK() - akpm */
1138
                reset_palette(vc);
1139
}
1140
 
1141
void vc_SAK(struct work_struct *work)
1142
{
1143
        struct vc *vc_con =
1144
                container_of(work, struct vc, SAK_work);
1145
        struct vc_data *vc;
1146
        struct tty_struct *tty;
1147
 
1148
        acquire_console_sem();
1149
        vc = vc_con->d;
1150
        if (vc) {
1151
                tty = vc->vc_tty;
1152
                /*
1153
                 * SAK should also work in all raw modes and reset
1154
                 * them properly.
1155
                 */
1156
                if (tty)
1157
                        __do_SAK(tty);
1158
                reset_vc(vc);
1159
        }
1160
        release_console_sem();
1161
}
1162
 
1163
/*
1164
 * Performs the back end of a vt switch
1165
 */
1166
static void complete_change_console(struct vc_data *vc)
1167
{
1168
        unsigned char old_vc_mode;
1169
 
1170
        last_console = fg_console;
1171
 
1172
        /*
1173
         * If we're switching, we could be going from KD_GRAPHICS to
1174
         * KD_TEXT mode or vice versa, which means we need to blank or
1175
         * unblank the screen later.
1176
         */
1177
        old_vc_mode = vc_cons[fg_console].d->vc_mode;
1178
        switch_screen(vc);
1179
 
1180
        /*
1181
         * This can't appear below a successful kill_pid().  If it did,
1182
         * then the *blank_screen operation could occur while X, having
1183
         * received acqsig, is waking up on another processor.  This
1184
         * condition can lead to overlapping accesses to the VGA range
1185
         * and the framebuffer (causing system lockups).
1186
         *
1187
         * To account for this we duplicate this code below only if the
1188
         * controlling process is gone and we've called reset_vc.
1189
         */
1190
        if (old_vc_mode != vc->vc_mode) {
1191
                if (vc->vc_mode == KD_TEXT)
1192
                        do_unblank_screen(1);
1193
                else
1194
                        do_blank_screen(1);
1195
        }
1196
 
1197
        /*
1198
         * If this new console is under process control, send it a signal
1199
         * telling it that it has acquired. Also check if it has died and
1200
         * clean up (similar to logic employed in change_console())
1201
         */
1202
        if (vc->vt_mode.mode == VT_PROCESS) {
1203
                /*
1204
                 * Send the signal as privileged - kill_pid() will
1205
                 * tell us if the process has gone or something else
1206
                 * is awry
1207
                 */
1208
                if (kill_pid(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
1209
                /*
1210
                 * The controlling process has died, so we revert back to
1211
                 * normal operation. In this case, we'll also change back
1212
                 * to KD_TEXT mode. I'm not sure if this is strictly correct
1213
                 * but it saves the agony when the X server dies and the screen
1214
                 * remains blanked due to KD_GRAPHICS! It would be nice to do
1215
                 * this outside of VT_PROCESS but there is no single process
1216
                 * to account for and tracking tty count may be undesirable.
1217
                 */
1218
                        reset_vc(vc);
1219
 
1220
                        if (old_vc_mode != vc->vc_mode) {
1221
                                if (vc->vc_mode == KD_TEXT)
1222
                                        do_unblank_screen(1);
1223
                                else
1224
                                        do_blank_screen(1);
1225
                        }
1226
                }
1227
        }
1228
 
1229
        /*
1230
         * Wake anyone waiting for their VT to activate
1231
         */
1232
        vt_wake_waitactive();
1233
        return;
1234
}
1235
 
1236
/*
1237
 * Performs the front-end of a vt switch
1238
 */
1239
void change_console(struct vc_data *new_vc)
1240
{
1241
        struct vc_data *vc;
1242
 
1243
        if (!new_vc || new_vc->vc_num == fg_console || vt_dont_switch)
1244
                return;
1245
 
1246
        /*
1247
         * If this vt is in process mode, then we need to handshake with
1248
         * that process before switching. Essentially, we store where that
1249
         * vt wants to switch to and wait for it to tell us when it's done
1250
         * (via VT_RELDISP ioctl).
1251
         *
1252
         * We also check to see if the controlling process still exists.
1253
         * If it doesn't, we reset this vt to auto mode and continue.
1254
         * This is a cheap way to track process control. The worst thing
1255
         * that can happen is: we send a signal to a process, it dies, and
1256
         * the switch gets "lost" waiting for a response; hopefully, the
1257
         * user will try again, we'll detect the process is gone (unless
1258
         * the user waits just the right amount of time :-) and revert the
1259
         * vt to auto control.
1260
         */
1261
        vc = vc_cons[fg_console].d;
1262
        if (vc->vt_mode.mode == VT_PROCESS) {
1263
                /*
1264
                 * Send the signal as privileged - kill_pid() will
1265
                 * tell us if the process has gone or something else
1266
                 * is awry.
1267
                 *
1268
                 * We need to set vt_newvt *before* sending the signal or we
1269
                 * have a race.
1270
                 */
1271
                vc->vt_newvt = new_vc->vc_num;
1272
                if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
1273
                        /*
1274
                         * It worked. Mark the vt to switch to and
1275
                         * return. The process needs to send us a
1276
                         * VT_RELDISP ioctl to complete the switch.
1277
                         */
1278
                        return;
1279
                }
1280
 
1281
                /*
1282
                 * The controlling process has died, so we revert back to
1283
                 * normal operation. In this case, we'll also change back
1284
                 * to KD_TEXT mode. I'm not sure if this is strictly correct
1285
                 * but it saves the agony when the X server dies and the screen
1286
                 * remains blanked due to KD_GRAPHICS! It would be nice to do
1287
                 * this outside of VT_PROCESS but there is no single process
1288
                 * to account for and tracking tty count may be undesirable.
1289
                 */
1290
                reset_vc(vc);
1291
 
1292
                /*
1293
                 * Fall through to normal (VT_AUTO) handling of the switch...
1294
                 */
1295
        }
1296
 
1297
        /*
1298
         * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
1299
         */
1300
        if (vc->vc_mode == KD_GRAPHICS)
1301
                return;
1302
 
1303
        complete_change_console(new_vc);
1304
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.