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