~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/char/vt.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.