source: rtems/c/src/lib/libbsp/i386/pc386/console/vt.c @ 7a0a5531

4.104.114.84.95
Last change on this file since 7a0a5531 was 7a0a5531, checked in by Joel Sherrill <joel.sherrill@…>, on 01/05/01 at 13:33:31

2001-01-05 Joel Sherrill <joel@…>

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