source: rtems/c/src/lib/libbsp/i386/pc386/console/vt.c @ 3cbb63a

4.104.114.84.95
Last change on this file since 3cbb63a was 3cbb63a, checked in by Joel Sherrill <joel.sherrill@…>, on 08/30/00 at 08:15:30

2000-08-26 Rosimildo da Silva <rdasilva@…>

  • Major rework of the "/dev/console" driver.
  • Added termios support for stdin ( keyboard ).
  • Added ioctls() to support modes similar to Linux( XLATE, RAW, MEDIUMRAW ).
  • Added Keyboard mapping and handling of the keyboard's leds.
  • Added Micro FrameBuffer? driver ( "/dev/fb0" ) for bare VGA controller ( 16 colors ).
  • Added PS/2 and Serial mouse support for PC386 BSP.
  • console/defkeymap.c: New file.
  • console/fb_vga.c: New file.
  • console/fb_vga.h: New file.
  • console/i386kbd.h: New file.
  • console/kd.h: New file.
  • console/keyboard.c: New file.
  • console/keyboard.h: New file.
  • console/mouse_parser.c: New file.
  • console/mouse_parser.h: New file.
  • console/pc_keyb.c: New file.
  • console/ps2_drv.h: New file.
  • console/ps2_mouse.c: New file.
  • console/ps2_mouse.h: New file.
  • console/serial_mouse.c: New file.
  • console/serial_mouse.h: New file.
  • console/vgainit.c: New file.
  • console/vt.c: New file.
  • console/Makefile.am: Reflect new files.
  • console/console.c, console/inch.c, console/outch.c: Console functionality modifications.
  • startup/Makefile.am: Pick up tty_drv.c and gdb_glue.c
  • Property mode set to 100644
File size: 7.3 KB
Line 
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 * by: Rosimildo da Silva --
13 * Ported to RTEMS to provide the basic interface to the console
14 * driver. Removed all stuff not required, such as VT_, Fonts, etc.
15 */
16
17#include <sys/types.h>
18#include <errno.h>
19
20#include <i386_io.h>
21#include <rtems/kd.h>
22#include <rtems/keyboard.h>
23
24/*
25 * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
26 * experimentation and study of X386 SYSV handling.
27 *
28 * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
29 * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
30 * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
31 * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
32 * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
33 * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
34 * to the current console is done by the main ioctl code.
35 */
36
37struct vt_struct *vt_cons[MAX_NR_CONSOLES];
38
39/* Keyboard type: Default is KB_101, but can be set by machine
40 * specific code.
41 */
42unsigned char keyboard_type = KB_101;
43
44/*
45 * Generates sound of some frequency for some number of clock ticks
46 *
47 * If freq is 0, will turn off sound, else will turn it on for that time.
48 * If msec is 0, will return immediately, else will sleep for msec time, then
49 * turn sound off.
50 *
51 * We also return immediately, which is what was implied within the X
52 * comments - KDMKTONE doesn't put the process to sleep.
53 */
54
55#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
56    || (defined(__mips__) && !defined(CONFIG_SGI))
57
58static void
59kd_nosound(unsigned long ignored)
60{
61        /* disable counter 2 */
62        outb(inb_p(0x61)&0xFC, 0x61);
63        return;
64}
65
66void
67_kd_mksound(unsigned int hz, unsigned int ticks)
68{
69        unsigned int count = 0;
70
71        if (hz > 20 && hz < 32767)
72                count = 1193180 / hz;
73       
74        cli();
75/*      del_timer(&sound_timer);  */
76        if (count) {
77                /* enable counter 2 */
78                outb_p(inb_p(0x61)|3, 0x61);
79                /* set command for counter 2, 2 byte write */
80                outb_p(0xB6, 0x43);
81                /* select desired HZ */
82                outb_p(count & 0xff, 0x42);
83                outb((count >> 8) & 0xff, 0x42);
84
85/*
86                if (ticks) {
87                        sound_timer.expires = jiffies+ticks;
88                        add_timer(&sound_timer);
89                }
90*/
91        } else
92                kd_nosound(0);
93
94        sti();
95        return;
96}
97
98#else
99
100void
101_kd_mksound(unsigned int hz, unsigned int ticks)
102{
103}
104
105#endif
106
107void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
108
109
110#define i (tmp.kb_index)
111#define s (tmp.kb_table)
112#define v (tmp.kb_value)
113static inline int
114do_kdsk_ioctl(int cmd, struct kbentry *user_kbe, int perm, struct kbd_struct *kbd)
115{
116        struct kbentry tmp;
117        ushort *key_map, val;
118
119        tmp = *user_kbe;
120        if (i >= NR_KEYS || s >= MAX_NR_KEYMAPS)
121                return -EINVAL;
122
123        switch (cmd) {
124        case KDGKBENT:
125                key_map = key_maps[s];
126                if (key_map) {
127                    val = U(key_map[i]);
128                    if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
129                        val = K_HOLE;
130                } else
131                    val = (i ? K_HOLE : K_NOSUCHMAP);
132                user_kbe->kb_value = val;
133                return 0;
134
135        case KDSKBENT:
136                return -EINVAL;
137        }
138        return 0;
139}
140#undef i
141#undef s
142#undef v
143
144
145#define  HZ  100
146
147static inline int
148do_kbkeycode_ioctl(int cmd, struct kbkeycode *user_kbkc, int perm)
149{
150        struct kbkeycode tmp;
151        int kc = 0;
152
153        tmp = *user_kbkc;
154        switch (cmd) {
155        case KDGETKEYCODE:
156                kc = getkeycode(tmp.scancode);
157                if (kc >= 0)
158                        user_kbkc->keycode = kc;
159                break;
160        case KDSETKEYCODE:
161                if (!perm)
162                        return -EPERM;
163                kc = setkeycode(tmp.scancode, tmp.keycode);
164                break;
165        }
166        return kc;
167}
168
169static inline int
170do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm)
171{
172        return -EINVAL;
173}
174
175/*
176 * We handle the console-specific ioctl's here.  We allow the
177 * capability to modify any console, not just the fg_console.
178 */
179int vt_ioctl( unsigned int cmd, unsigned long arg)
180{
181        int perm;
182        unsigned int console;
183        unsigned char ucval;
184        struct kbd_struct * kbd;
185
186   console = 0;
187        /*
188         * To have permissions to do most of the vt ioctls, we either have
189         * to be the owner of the tty, or super-user.
190         */
191        perm = 1;
192        kbd = kbd_table + console;
193        switch (cmd) {
194        case KIOCSOUND:
195                if (!perm)
196                        return -EPERM;
197                if (arg)
198                        arg = 1193180 / arg;
199                kd_mksound(arg, 0);
200                return 0;
201
202        case KDMKTONE:
203                if (!perm)
204                        return -EPERM;
205        {
206                unsigned int ticks, count;
207               
208                /*
209                 * Generate the tone for the appropriate number of ticks.
210                 * If the time is zero, turn off sound ourselves.
211                 */
212                ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
213                count = ticks ? (arg & 0xffff) : 0;
214                if (count)
215                        count = 1193180 / count;
216                kd_mksound(count, ticks);
217                return 0;
218        }
219
220        case KDGKBTYPE:
221                /*
222                 * this is naive.
223                 */
224                ucval = keyboard_type;
225                goto setchar;
226
227        case KDSETMODE:
228        case KDGETMODE:
229                return -EINVAL;
230
231        case KDSKBMODE:
232                if (!perm)
233                        return -EPERM;
234                switch(arg) {
235                  case K_RAW:
236                        kbd->kbdmode = VC_RAW;
237                        break;
238                  case K_MEDIUMRAW:
239                        kbd->kbdmode = VC_MEDIUMRAW;
240                        break;
241                  case K_XLATE:
242                        kbd->kbdmode = VC_XLATE;
243                        compute_shiftstate();
244                        break;
245                  case K_UNICODE:
246                        kbd->kbdmode = VC_UNICODE;
247                        compute_shiftstate();
248                        break;
249                  default:
250                        return -EINVAL;
251                }
252                return 0;
253
254        case KDGKBMODE:
255                ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW :
256                                 (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
257                                 (kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
258                                 K_XLATE);
259                goto setint;
260
261        /* this could be folded into KDSKBMODE, but for compatibility
262           reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
263        case KDSKBMETA:
264                switch(arg) {
265                  case K_METABIT:
266                        clr_vc_kbd_mode(kbd, VC_META);
267                        break;
268                  case K_ESCPREFIX:
269                        set_vc_kbd_mode(kbd, VC_META);
270                        break;
271                  default:
272                        return -EINVAL;
273                }
274                return 0;
275
276        case KDGKBMETA:
277                ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
278        setint:
279                *(int *)arg = ucval;
280                return 0;
281
282        case KDGETKEYCODE:
283        case KDSETKEYCODE:
284                return do_kbkeycode_ioctl(cmd, (struct kbkeycode *)arg, perm);
285
286        case KDGKBENT:
287        case KDSKBENT:
288                return do_kdsk_ioctl(cmd, (struct kbentry *)arg, perm, kbd);
289
290        case KDGKBDIACR:
291        {
292                struct kbdiacrs *a = (struct kbdiacrs *)arg;
293                a->kb_cnt = accent_table_size;
294                memcpy( a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr) );
295                return 0;
296        }
297
298        case KDSKBDIACR:
299        {
300                struct kbdiacrs *a = (struct kbdiacrs *)arg;
301                unsigned int ct;
302
303                if (!perm)
304                        return -EPERM;
305                ct = a->kb_cnt;
306                if (ct >= MAX_DIACR)
307                        return -EINVAL;
308                accent_table_size = ct;
309                memcpy(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr));
310                return 0;
311        }
312
313        /* the ioctls below read/set the flags usually shown in the leds */
314        /* don't use them - they will go away without warning */
315        case KDGKBLED:
316                ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
317                goto setchar;
318
319        case KDSKBLED:
320                if (!perm)
321                        return -EPERM;
322                if (arg & ~0x77)
323                        return -EINVAL;
324                kbd->ledflagstate = (arg & 7);
325                kbd->default_ledflagstate = ((arg >> 4) & 7);
326                set_leds();
327                return 0;
328
329        /* the ioctls below only set the lights, not the functions */
330        /* for those, see KDGKBLED and KDSKBLED above */
331        case KDGETLED:
332                ucval = getledstate();
333        setchar:
334                *(char*)arg = ucval;
335      return 0;
336
337        case KDSETLED:
338                if (!perm)
339                  return -EPERM;
340                setledstate(kbd, arg);
341                return 0;
342
343        default:
344                return -EINVAL;
345        }
346}
347
Note: See TracBrowser for help on using the repository browser.