2 * linux/drivers/char/vt.c 4 * Copyright (C) 1992 obz under the linux copyright 6 * Dynamic diacritical handling - aeb@cwi.nl - Dec 1993 7 * Dynamic keymap and string allocation - aeb@cwi.nl - May 1994 10 #include <linux/types.h> 11 #include <linux/errno.h> 12 #include <linux/sched.h> 13 #include <linux/tty.h> 14 #include <linux/timer.h> 15 #include <linux/kernel.h> 18 #include <linux/string.h> 19 #include <linux/malloc.h> 20 #include <linux/major.h> 24 #include <asm/segment.h> 31 externstruct tty_driver console_driver
; 33 #define VT_IS_IN_USE(i) (console_driver.table[i] && console_driver.table[i]->count) 34 #define VT_BUSY(i) (VT_IS_IN_USE(i) || i == fg_console || i == sel_cons) 37 * Console (vt and kd) routines, as defined by USL SVR4 manual, and by 38 * experimentation and study of X386 SYSV handling. 40 * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and 41 * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console, 42 * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will 43 * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to 44 * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using 45 * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing 46 * to the current console is done by the main ioctl code. 49 struct vt_struct
*vt_cons
[MAX_NR_CONSOLES
]; 51 asmlinkage
intsys_ioperm(unsigned long from
,unsigned long num
,int on
); 53 externintgetkeycode(unsigned int scancode
); 54 externintsetkeycode(unsigned int scancode
,unsigned int keycode
); 55 externvoidcompute_shiftstate(void); 56 externvoidchange_console(unsigned int new_console
); 57 externvoidcomplete_change_console(unsigned int new_console
); 58 externintvt_waitactive(void); 59 externvoiddo_blank_screen(int nopowersave
); 61 externunsigned int keymap_count
; 64 * routines to load custom translation table, EGA/VGA font and 65 * VGA colour palette from console.c 67 externintcon_set_trans_old(unsigned char* table
); 68 externintcon_get_trans_old(unsigned char* table
); 69 externintcon_set_trans_new(unsigned short* table
); 70 externintcon_get_trans_new(unsigned short* table
); 71 externvoidcon_clear_unimap(struct unimapinit
*ui
); 72 externintcon_set_unimap(ushort ct
,struct unipair
*list
); 73 externintcon_get_unimap(ushort ct
, ushort
*uct
,struct unipair
*list
); 74 externintcon_set_font(char* fontmap
,int ch512
); 75 externintcon_get_font(char* fontmap
); 76 externintcon_set_cmap(unsigned char*cmap
); 77 externintcon_get_cmap(unsigned char*cmap
); 78 externvoidreset_palette(int currcons
); 79 externintcon_adjust_height(unsigned long fontheight
); 81 externint video_mode_512ch
; 82 externunsigned long video_font_height
; 83 externunsigned long video_scan_lines
; 86 * these are the valid i/o ports we're allowed to change. they map all the 91 #define GPNUM (GPLAST - GPFIRST + 1) 94 * This function is called when the size of the physical screen has been 95 * changed. If either the row or col argument is nonzero, set the appropriate 96 * entry in each winsize structure for all the virtual consoles, then 97 * send SIGWINCH to all processes with a virtual console as controlling 102 kd_size_changed(int row
,int col
) 104 struct task_struct
*p
; 107 if( !row
&& !col
)return0; 109 for( i
=0; i
< MAX_NR_CONSOLES
; i
++ ) 111 if( console_driver
.table
[i
] ) 113 if( row
) console_driver
.table
[i
]->winsize
.ws_row
= row
; 114 if( col
) console_driver
.table
[i
]->winsize
.ws_col
= col
; 120 if( p
->tty
&&MAJOR(p
->tty
->device
) == TTY_MAJOR
&& 121 MINOR(p
->tty
->device
) <= MAX_NR_CONSOLES
&&MINOR(p
->tty
->device
) ) 123 send_sig(SIGWINCH
, p
,1); 131 * Generates sound of some count for some number of clock ticks 132 * [count = 1193180 / frequency] 134 * If freq is 0, will turn off sound, else will turn it on for that time. 135 * If msec is 0, will return immediately, else will sleep for msec time, then 138 * We use the BEEP_TIMER vector since we're using the same method to 139 * generate sound, and we'll overwrite any beep in progress. That may 140 * be something to fix later, if we like. 142 * We also return immediately, which is what was implied within the X 143 * comments - KDMKTONE doesn't put the process to sleep. 146 kd_nosound(unsigned long ignored
) 148 /* disable counter 2 */ 149 outb(inb_p(0x61)&0xFC,0x61); 154 kd_mksound(unsigned int count
,unsigned int ticks
) 156 static struct timer_list sound_timer
= { NULL
, NULL
,0,0, kd_nosound
}; 159 del_timer(&sound_timer
); 161 /* enable counter 2 */ 162 outb_p(inb_p(0x61)|3,0x61); 163 /* set command for counter 2, 2 byte write */ 165 /* select desired HZ */ 166 outb_p(count
&0xff,0x42); 167 outb((count
>>8) &0xff,0x42); 170 sound_timer
.expires
= jiffies
+ticks
; 171 add_timer(&sound_timer
); 180 * We handle the console-specific ioctl's here. We allow the 181 * capability to modify any console, not just the fg_console. 183 intvt_ioctl(struct tty_struct
*tty
,struct file
* file
, 184 unsigned int cmd
,unsigned long arg
) 187 unsigned int console
; 189 struct kbd_struct
* kbd
; 190 struct vt_struct
*vt
= (struct vt_struct
*)tty
->driver_data
; 192 console
= vt
->vc_num
; 194 if(!vc_cons_allocated(console
))/* impossible? */ 198 * To have permissions to do most of the vt ioctls, we either have 199 * to be the owner of the tty, or super-user. 202 if(current
->tty
== tty
||suser()) 205 kbd
= kbd_table
+ console
; 210 kd_mksound((unsigned int)arg
,0); 217 unsigned int ticks
= HZ
* ((arg
>>16) &0xffff) /1000; 220 * Generate the tone for the appropriate number of ticks. 221 * If the time is zero, turn off sound ourselves. 223 kd_mksound(arg
&0xffff, ticks
); 233 i
=verify_area(VERIFY_WRITE
, (void*) arg
,sizeof(unsigned char)); 235 put_user(KB_101
, (char*) arg
); 241 * KDADDIO and KDDELIO may be able to add ports beyond what 242 * we reject here, but to be safe... 244 if(arg
< GPFIRST
|| arg
> GPLAST
) 246 returnsys_ioperm(arg
,1, (cmd
== KDADDIO
)) ? -ENXIO
:0; 250 returnsys_ioperm(GPFIRST
, GPNUM
, 251 (cmd
== KDENABIO
)) ? -ENXIO
:0; 255 * currently, setting the mode from KD_TEXT to KD_GRAPHICS 256 * doesn't do a whole lot. i'm not sure if it should do any 257 * restoration of modes or what... 272 if(vt_cons
[console
]->vc_mode
== (unsigned char) arg
) 274 vt_cons
[console
]->vc_mode
= (unsigned char) arg
; 275 if(console
!= fg_console
) 278 * explicitly blank/unblank the screen if switching modes 287 i
=verify_area(VERIFY_WRITE
, (void*) arg
,sizeof(int)); 289 put_user(vt_cons
[console
]->vc_mode
, (int*) arg
); 295 * these work like a combination of mmap and KDENABIO. 296 * this could be easily finished. 305 kbd
->kbdmode
= VC_RAW
; 308 kbd
->kbdmode
= VC_MEDIUMRAW
; 311 kbd
->kbdmode
= VC_XLATE
; 312 compute_shiftstate(); 315 kbd
->kbdmode
= VC_UNICODE
; 316 compute_shiftstate(); 321 if(tty
->ldisc
.flush_buffer
) 322 tty
->ldisc
.flush_buffer(tty
); 326 i
=verify_area(VERIFY_WRITE
, (void*) arg
,sizeof(int)); 328 ucval
= ((kbd
->kbdmode
== VC_RAW
) ? K_RAW
: 329 (kbd
->kbdmode
== VC_MEDIUMRAW
) ? K_MEDIUMRAW
: 330 (kbd
->kbdmode
== VC_UNICODE
) ? K_UNICODE
: 332 put_user(ucval
, (int*) arg
); 336 /* this could be folded into KDSKBMODE, but for compatibility 337 reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ 341 clr_vc_kbd_mode(kbd
, VC_META
); 344 set_vc_kbd_mode(kbd
, VC_META
); 352 i
=verify_area(VERIFY_WRITE
, (void*) arg
,sizeof(int)); 354 ucval
= (vc_kbd_mode(kbd
, VC_META
) ? K_ESCPREFIX
: 356 put_user(ucval
, (int*) arg
); 362 struct kbkeycode
*const a
= (struct kbkeycode
*)arg
; 366 i
=verify_area(VERIFY_WRITE
, (void*)a
,sizeof(struct kbkeycode
)); 369 sc
=get_user(&a
->scancode
); 373 put_user(kc
, &a
->keycode
); 379 struct kbkeycode
*const a
= (struct kbkeycode
*)arg
; 384 i
=verify_area(VERIFY_READ
, (void*)a
,sizeof(struct kbkeycode
)); 387 sc
=get_user(&a
->scancode
); 388 kc
=get_user(&a
->keycode
); 389 returnsetkeycode(sc
, kc
); 394 struct kbentry
*const a
= (struct kbentry
*)arg
; 395 ushort
*key_map
, val
; 398 i
=verify_area(VERIFY_WRITE
, (void*)a
,sizeof(struct kbentry
)); 401 if((i
=get_user(&a
->kb_index
)) >= NR_KEYS
) 403 if((s
=get_user(&a
->kb_table
)) >= MAX_NR_KEYMAPS
) 405 key_map
= key_maps
[s
]; 408 if(kbd
->kbdmode
!= VC_UNICODE
&&KTYP(val
) >= NR_TYPES
) 411 val
= (i
? K_HOLE
: K_NOSUCHMAP
); 412 put_user(val
, &a
->kb_value
); 418 const struct kbentry
* a
= (struct kbentry
*)arg
; 425 i
=verify_area(VERIFY_READ
, (const void*)a
,sizeof(struct kbentry
)); 428 if((i
=get_user(&a
->kb_index
)) >= NR_KEYS
) 430 if((s
=get_user(&a
->kb_table
)) >= MAX_NR_KEYMAPS
) 432 v
=get_user(&a
->kb_value
); 433 if(!i
&& v
== K_NOSUCHMAP
) { 434 /* disallocate map */ 435 key_map
= key_maps
[s
]; 438 if(key_map
[0] ==U(K_ALLOCATED
)) { 439 kfree_s(key_map
,sizeof(plain_map
)); 446 if(KTYP(v
) < NR_TYPES
) { 447 if(KVAL(v
) > max_vals
[KTYP(v
)]) 450 if(kbd
->kbdmode
!= VC_UNICODE
) 453 /* assignment to entry 0 only tests validity of args */ 457 if(!(key_map
= key_maps
[s
])) { 460 if(keymap_count
>= MAX_NR_OF_USER_KEYMAPS
&& !suser()) 463 key_map
= (ushort
*)kmalloc(sizeof(plain_map
), 467 key_maps
[s
] = key_map
; 468 key_map
[0] =U(K_ALLOCATED
); 469 for(j
=1; j
< NR_KEYS
; j
++) 470 key_map
[j
] =U(K_HOLE
); 475 return0;/* nothing to do */ 477 * Only the Superuser can set or unset the Secure 480 if(((ov
== K_SAK
) || (v
== K_SAK
)) && !suser()) 483 if(!s
&& (KTYP(ov
) == KT_SHIFT
||KTYP(v
) == KT_SHIFT
)) 484 compute_shiftstate(); 490 struct kbsentry
*a
= (struct kbsentry
*)arg
; 495 i
=verify_area(VERIFY_WRITE
, (void*)a
,sizeof(struct kbsentry
)); 498 if((i
=get_user(&a
->kb_func
)) >= MAX_NR_FUNC
|| i
<0) 500 sz
=sizeof(a
->kb_string
) -1;/* sz should have been 505 for( ; *p
&& sz
; p
++, sz
--) 508 return((p
&& *p
) ? -EOVERFLOW
:0); 513 struct kbsentry
*const a
= (struct kbsentry
*)arg
; 515 char*first_free
, *fj
, *fnw
; 522 i
=verify_area(VERIFY_READ
, (void*)a
,sizeof(struct kbsentry
)); 525 if((i
=get_user(&a
->kb_func
)) >= MAX_NR_FUNC
) 529 first_free
= funcbufptr
+ (funcbufsize
- funcbufleft
); 530 for(j
= i
+1; j
< MAX_NR_FUNC
&& !func_table
[j
]; j
++) ; 536 delta
= (q
? -strlen(q
) :1); 537 sz
=sizeof(a
->kb_string
);/* sz should have been 539 for(p
= a
->kb_string
;get_user(p
) && sz
; p
++,sz
--) 543 if(delta
<= funcbufleft
) {/* it fits in current buf */ 544 if(j
< MAX_NR_FUNC
) { 545 memmove(fj
+ delta
, fj
, first_free
- fj
); 546 for(k
= j
; k
< MAX_NR_FUNC
; k
++) 548 func_table
[k
] += delta
; 552 funcbufleft
-= delta
; 553 }else{/* allocate a larger buffer */ 555 while(sz
< funcbufsize
- funcbufleft
+ delta
) 557 fnw
= (char*)kmalloc(sz
, GFP_KERNEL
); 564 memmove(fnw
, funcbufptr
, fj
- funcbufptr
); 565 for(k
=0; k
< j
; k
++) 567 func_table
[k
] = fnw
+ (func_table
[k
] - funcbufptr
); 569 if(first_free
> fj
) { 570 memmove(fnw
+ (fj
- funcbufptr
) + delta
, fj
, first_free
- fj
); 571 for(k
= j
; k
< MAX_NR_FUNC
; k
++) 573 func_table
[k
] = fnw
+ (func_table
[k
] - funcbufptr
) + delta
; 575 if(funcbufptr
!= func_buf
) 576 kfree_s(funcbufptr
, funcbufsize
); 578 funcbufleft
= funcbufleft
- delta
+ sz
- funcbufsize
; 581 for(p
= a
->kb_string
, q
= func_table
[i
]; ; p
++, q
++) 582 if(!(*q
=get_user(p
))) 589 struct kbdiacrs
*a
= (struct kbdiacrs
*)arg
; 591 i
=verify_area(VERIFY_WRITE
, (void*) a
,sizeof(struct kbdiacrs
)); 594 put_user(accent_table_size
, &a
->kb_cnt
); 595 memcpy_tofs(a
->kbdiacr
, accent_table
, 596 accent_table_size
*sizeof(struct kbdiacr
)); 602 struct kbdiacrs
*a
= (struct kbdiacrs
*)arg
; 607 i
=verify_area(VERIFY_READ
, (void*) a
,sizeof(struct kbdiacrs
)); 610 ct
=get_user(&a
->kb_cnt
); 613 accent_table_size
= ct
; 614 memcpy_fromfs(accent_table
, a
->kbdiacr
, ct
*sizeof(struct kbdiacr
)); 618 /* the ioctls below read/set the flags usually shown in the leds */ 619 /* don't use them - they will go away without warning */ 621 i
=verify_area(VERIFY_WRITE
, (void*) arg
,sizeof(unsigned char)); 624 put_user(kbd
->ledflagstate
| 625 (kbd
->default_ledflagstate
<<4), (char*) arg
); 633 kbd
->ledflagstate
= (arg
&7); 634 kbd
->default_ledflagstate
= ((arg
>>4) &7); 638 /* the ioctls below only set the lights, not the functions */ 639 /* for those, see KDGKBLED and KDSKBLED above */ 641 i
=verify_area(VERIFY_WRITE
, (void*) arg
,sizeof(unsigned char)); 644 put_user(getledstate(), (char*) arg
); 650 setledstate(kbd
, arg
); 654 * A process can indicate its willingness to accept signals 655 * generated by pressing an appropriate key combination. 656 * Thus, one can have a daemon that e.g. spawns a new console 657 * upon a keypress and then changes to it. 658 * Probably init should be changed to do this (and have a 659 * field ks (`keyboard signal') in inittab describing the 660 * desired action), so that the number of background daemons 665 externint spawnpid
, spawnsig
; 668 if(arg
<1|| arg
> NSIG
|| arg
== SIGKILL
) 670 spawnpid
= current
->pid
; 677 struct vt_mode
*vtmode
= (struct vt_mode
*)arg
; 682 i
=verify_area(VERIFY_WRITE
, (void*)vtmode
,sizeof(struct vt_mode
)); 685 mode
=get_user(&vtmode
->mode
); 686 if(mode
!= VT_AUTO
&& mode
!= VT_PROCESS
) 688 vt_cons
[console
]->vt_mode
.mode
= mode
; 689 vt_cons
[console
]->vt_mode
.waitv
=get_user(&vtmode
->waitv
); 690 vt_cons
[console
]->vt_mode
.relsig
=get_user(&vtmode
->relsig
); 691 vt_cons
[console
]->vt_mode
.acqsig
=get_user(&vtmode
->acqsig
); 692 /* the frsig is ignored, so we set it to 0 */ 693 vt_cons
[console
]->vt_mode
.frsig
=0; 694 vt_cons
[console
]->vt_pid
= current
->pid
; 695 vt_cons
[console
]->vt_newvt
=0; 701 struct vt_mode
*vtmode
= (struct vt_mode
*)arg
; 703 i
=verify_area(VERIFY_WRITE
, (void*)arg
,sizeof(struct vt_mode
)); 706 put_user(vt_cons
[console
]->vt_mode
.mode
, &vtmode
->mode
); 707 put_user(vt_cons
[console
]->vt_mode
.waitv
, &vtmode
->waitv
); 708 put_user(vt_cons
[console
]->vt_mode
.relsig
, &vtmode
->relsig
); 709 put_user(vt_cons
[console
]->vt_mode
.acqsig
, &vtmode
->acqsig
); 710 put_user(vt_cons
[console
]->vt_mode
.frsig
, &vtmode
->frsig
); 715 * Returns global vt state. Note that VT 0 is always open, since 716 * it's an alias for the current VT, and people can't use it here. 717 * We cannot return state for more than 16 VTs, since v_state is short. 721 struct vt_stat
*vtstat
= (struct vt_stat
*)arg
; 722 unsigned short state
, mask
; 724 i
=verify_area(VERIFY_WRITE
,(void*)vtstat
,sizeof(struct vt_stat
)); 727 put_user(fg_console
+1, &vtstat
->v_active
); 728 state
=1;/* /dev/tty0 is always open */ 729 for(i
=0, mask
=2; i
< MAX_NR_CONSOLES
&& mask
; ++i
, mask
<<=1) 732 put_user(state
, &vtstat
->v_state
); 737 * Returns the first available (non-opened) console. 740 i
=verify_area(VERIFY_WRITE
, (void*) arg
,sizeof(int)); 743 for(i
=0; i
< MAX_NR_CONSOLES
; ++i
) 746 put_user(i
< MAX_NR_CONSOLES
? (i
+1) : -1, (int*) arg
); 750 * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num, 751 * with num >= 1 (switches to vt 0, our console, are not allowed, just 752 * to preserve sanity). 757 if(arg
==0|| arg
> MAX_NR_CONSOLES
) 767 * wait until the specified VT has been activated 772 if(arg
==0|| arg
> MAX_NR_CONSOLES
) 775 while(fg_console
!= arg
) 777 if(vt_waitactive() <0) 783 * If a vt is under process control, the kernel will not switch to it 784 * immediately, but postpone the operation until the process calls this 785 * ioctl, allowing the switch to complete. 787 * According to the X sources this is the behavior: 788 * 0: pending switch-from not OK 789 * 1: pending switch-from OK 790 * 2: completed switch-to OK 795 if(vt_cons
[console
]->vt_mode
.mode
!= VT_PROCESS
) 799 * Switching-from response 801 if(vt_cons
[console
]->vt_newvt
>=0) 805 * Switch disallowed, so forget we were trying 808 vt_cons
[console
]->vt_newvt
= -1; 813 * The current vt has been released, so 814 * complete the switch. 816 int newvt
= vt_cons
[console
]->vt_newvt
; 817 vt_cons
[console
]->vt_newvt
= -1; 818 i
=vc_allocate(newvt
); 821 complete_change_console(newvt
); 826 * Switched-to response 831 * If it's just an ACK, ignore it 840 * Disallocate memory associated to VT (but leave VT1) 843 if(arg
> MAX_NR_CONSOLES
) 846 /* disallocate all unused consoles, but leave 0 */ 847 for(i
=1; i
<MAX_NR_CONSOLES
; i
++) 851 /* disallocate a single console, if possible */ 862 struct vt_sizes
*vtsizes
= (struct vt_sizes
*) arg
; 866 i
=verify_area(VERIFY_READ
, (void*)vtsizes
,sizeof(struct vt_sizes
)); 869 ll
=get_user(&vtsizes
->v_rows
); 870 cc
=get_user(&vtsizes
->v_cols
); 871 i
=vc_resize(ll
, cc
); 872 return i
? i
:kd_size_changed(ll
, cc
); 877 struct vt_consize
*vtconsize
= (struct vt_consize
*) arg
; 878 ushort ll
,cc
,vlin
,clin
,vcol
,ccol
; 881 i
=verify_area(VERIFY_READ
, (void*)vtconsize
,sizeof(struct vt_consize
)); 884 ll
=get_user(&vtconsize
->v_rows
); 885 cc
=get_user(&vtconsize
->v_cols
); 886 vlin
=get_user(&vtconsize
->v_vlin
); 887 clin
=get_user(&vtconsize
->v_clin
); 888 vcol
=get_user(&vtconsize
->v_vcol
); 889 ccol
=get_user(&vtconsize
->v_ccol
); 890 vlin
= vlin
? vlin
: video_scan_lines
; 895 if( ll
!= vlin
/clin
) 896 return EINVAL
;/* Parameters don't add up */ 905 if( cc
!= vcol
/ccol
) 916 video_scan_lines
= vlin
; 918 video_font_height
= clin
; 920 i
=vc_resize(ll
, cc
); 924 kd_size_changed(ll
, cc
); 931 if(vt_cons
[fg_console
]->vc_mode
!= KD_TEXT
) 933 returncon_set_font((char*)arg
,0); 934 /* con_set_font() defined in console.c */ 937 if(vt_cons
[fg_console
]->vc_mode
!= KD_TEXT
|| 940 returncon_get_font((char*)arg
); 941 /* con_get_font() defined in console.c */ 946 returncon_set_cmap((char*)arg
); 947 /* con_set_cmap() defined in console.c */ 950 returncon_get_cmap((char*)arg
); 951 /* con_get_cmap() defined in console.c */ 955 struct consolefontdesc cfdarg
; 959 if(vt_cons
[fg_console
]->vc_mode
!= KD_TEXT
) 961 i
=verify_area(VERIFY_READ
, (void*)arg
, 962 sizeof(struct consolefontdesc
)); 964 memcpy_fromfs(&cfdarg
, (void*)arg
, 965 sizeof(struct consolefontdesc
)); 967 if( cfdarg
.charcount
==256|| 968 cfdarg
.charcount
==512) { 969 i
=con_set_font(cfdarg
.chardata
, 970 cfdarg
.charcount
==512); 973 i
=con_adjust_height(cfdarg
.charheight
); 974 return(i
<=0) ? i
:kd_size_changed(i
,0); 981 struct consolefontdesc cfdarg
; 984 if(vt_cons
[fg_console
]->vc_mode
!= KD_TEXT
) 986 i
=verify_area(VERIFY_WRITE
, (void*)arg
, 987 sizeof(struct consolefontdesc
)); 989 memcpy_fromfs(&cfdarg
, (void*) arg
, 990 sizeof(struct consolefontdesc
)); 991 i
= cfdarg
.charcount
; 992 cfdarg
.charcount
= nchar
= video_mode_512ch
?512:256; 993 cfdarg
.charheight
= video_font_height
; 994 memcpy_tofs((void*) arg
, &cfdarg
, 995 sizeof(struct consolefontdesc
)); 996 if( cfdarg
.chardata
) 1000 returncon_get_font(cfdarg
.chardata
); 1008 returncon_set_trans_old((unsigned char*)arg
); 1011 returncon_get_trans_old((unsigned char*)arg
); 1013 case PIO_UNISCRNMAP
: 1016 returncon_set_trans_new((unsigned short*)arg
); 1018 case GIO_UNISCRNMAP
: 1019 returncon_get_trans_new((unsigned short*)arg
); 1022 {struct unimapinit ui
; 1025 i
=verify_area(VERIFY_READ
, (void*)arg
,sizeof(struct unimapinit
)); 1028 memcpy_fromfs(&ui
, (void*)arg
,sizeof(struct unimapinit
)); 1029 con_clear_unimap(&ui
); 1034 {struct unimapdesc
*ud
; 1036 struct unipair
*list
; 1040 i
=verify_area(VERIFY_READ
, (void*)arg
,sizeof(struct unimapdesc
)); 1042 ud
= (struct unimapdesc
*) arg
; 1043 ct
=get_user(&ud
->entry_ct
); 1044 list
=get_user(&ud
->entries
); 1045 i
=verify_area(VERIFY_READ
, (void*) list
, 1046 ct
*sizeof(struct unipair
)); 1050 returncon_set_unimap(ct
, list
); 1054 {struct unimapdesc
*ud
; 1056 struct unipair
*list
; 1058 i
=verify_area(VERIFY_WRITE
, (void*)arg
,sizeof(struct unimapdesc
)); 1060 ud
= (struct unimapdesc
*) arg
; 1061 ct
=get_user(&ud
->entry_ct
); 1062 list
=get_user(&ud
->entries
); 1064 i
=verify_area(VERIFY_WRITE
, (void*) list
, 1065 ct
*sizeof(struct unipair
)); 1069 returncon_get_unimap(ct
, &(ud
->entry_ct
), list
);