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

Minix Cross Reference
Minix/kernel/sunkeyboard.c


  1 static char rcsid[] = "$Id: sunkeyboard.c,v 1.5 1996/08/01 02:08:56 paul Exp $";
  2 
  3 /*
  4  * This file contains the keyboard driver for SunOS Minix.  There are three
  5  * groups of functions in this file associated with the three entry points:
  6  *    - keyboard_intr - the function called when a SIGIO is received
  7  *                      indicating that terminal input is available.
  8  *    - kb_init - called to initialise keyboard data structures for a 
  9  *                specified terminal line.  Also, kb_read is installed as
 10  *                the function to call to read input from the specified
 11  *                terminal line.
 12  *    - wreboot - Shutdown smx.  Doesn't really belong in this file.
 13  */
 14  
 15 #include "kernel.h"
 16 #include <termios.h>
 17 #include <minix/callnr.h>
 18 #include <minix/com.h>
 19 #include "tty.h"
 20 #include "proc.h"
 21 #include <sun/syscall.h>
 22 
 23 #define KB_IN_BYTES      1024   /* size of keyboard input buffer */
 24 
 25 #define min(x,y) ((x) < (y) ? (x) : (y))
 26 
 27 #define kb_addr(tp)        (&kb_lines[tty_line(tp)])
 28 
 29 /*
 30  * Keyboard structure, 1 per tty.
 31  */
 32 struct kb_s {
 33     char *ihead;                        /* next free spot in input buffer */
 34     char *itail;                        /* first used spot in input buffer */
 35     int icount;                         /* # codes in buffer */
 36 
 37     char ibuf[KB_IN_BYTES];             /* input buffer */
 38 };
 39 
 40 static struct kb_s kb_lines[NR_CONS];
 41 
 42 
 43 /*
 44  * Local functions
 45  */
 46 static int hw_read(tty_t *tp, char *buffer, int len);
 47 static void input_flush(tty_t *tp);
 48 
 49 static void kb_read(tty_t *tp);
 50 static int func_key(tty_t *tp, int scode);
 51 
 52 
 53 /*===========================================================================*
 54  *                 Functions dealing with the SunOS IO signal                *
 55  *===========================================================================*/
 56 
 57 /*
 58  * Function: keyboard_intr
 59  * Parameter: fd - SunOS file descriptor on which input is available
 60  *
 61  * The function is called when there is input available on the SunOS
 62  * descriptor fd, and fd is associated with one of the smx console devices.
 63  * keyboard_instr must transfer the input to a terminal buffer, and inform
 64  * the terminal driver that new input has arrived. Any terminal input that
 65  * won't fit into the keyboard buffer is discarded.  
 66  *
 67  * Maybe the TTY task should transfer input into the buffer (but
 68  * it's not awoken until the next clock tick).  On the other hand,
 69  * the PC MINIX keyboard interrupt handle also puts characters directly
 70  * into the buffers of the TTY task.
 71  */
 72 static void keyboard_intr(int fd)
 73 {
 74     struct kb_s *kb;
 75     tty_t *tp;
 76     int line;
 77     int num_read, to_read;
 78 
 79     line = (fd - TERMINAL_FD) / 2;
 80     if (line < 0 || line >= NR_CONS) {
 81         panic("Bad fd supplied to keyboard_intr", fd);
 82     }
 83 
 84     tp = &tty_table[line];
 85     kb = kb_addr(tp);  
 86     if (kb->icount < KB_IN_BYTES) {
 87         /*
 88          * If there is space in the buffer then we go ahead and
 89          * try to read from the tty.  If the free buffer space
 90          * (KB_IN_BYTES - kb->icount) is in one chunk then we
 91          * try to fill all of it in a single read.  Otherwise
 92          * we free the space between head and the end of the
 93          * buffer with the first read and, if all of that space
 94          * is filled, wrap head around to the beginning of the
 95          * buffer and try to fill the free space there.
 96          */
 97         to_read = min(KB_IN_BYTES - kb->icount,
 98                       KB_IN_BYTES - (kb->ihead - kb->ibuf));
 99         num_read = hw_read(tp, kb->ihead, to_read);
100         
101         if (num_read > 0) {
102             tp->tty_events = 1;
103             force_timeout();
104             kb->icount += num_read;
105             kb->ihead += num_read;
106 
107             if (kb->ihead == kb->ibuf + KB_IN_BYTES) {
108                 kb->ihead = kb->ibuf;
109                 if (kb->icount < KB_IN_BYTES) {
110                     num_read = hw_read(tp, kb->ihead,
111                                        KB_IN_BYTES - kb->icount);
112 
113                     if (num_read > 0) {
114                         kb->icount += num_read;
115                         kb->ihead += num_read;
116                         /*
117                          * Read at least 1 byte the first time; ihead
118                          * cannot wraparound this time.
119                          */
120                     }
121                 } /* if space in input buffer for a second read */
122             } /* if first read wraps buffer */
123         } /* if first read returns at least one char */
124     } /* if space in input buffer */
125 
126     if (kb->icount == KB_IN_BYTES) {
127         /*
128          * If the buffer is full then there may still be data buffered
129          * by SunOS.  Flush it to make sure that we get a SIGIO
130          * when the next character gets entered.
131          */
132         input_flush(tp);
133     }
134 }
135 
136 
137 /*
138  * Function: hw_read
139  * Parameters: tp - terminal to read from
140  *             buffer - buffer to read into
141  *             len - size of buffer
142  * Returns: value returned by call to SunOS read.
143  *
144  * The terminal input descriptors are the even ones of the terminal
145  * descriptor pair, so the FD to read is simply
146  * TERMINAL_FD + 2 line_number.  The smx bootstrap program sets up
147  * these terminal descriptors.
148  */
149 static int hw_read(tty_t *tp, char *buffer, int len)
150 {
151     return SunOS(SYS_read, TERMINAL_FD + tty_line(tp) * 2, buffer, len);
152 }
153 
154 
155 /*
156  * Function: input_flush
157  * Parameter: tp - terminal to be flushed
158  *
159  * Discard all buffered input for the spcified terminal.
160  */
161 static void input_flush(tty_t *tp)
162 {
163     static char flushbuf[32];
164 
165     while (hw_read(tp, flushbuf, sizeof(flushbuf)) > 0) {
166         ;
167     }
168 }
169 
170 
171 /*===========================================================================*
172  *                        The keyboard driver functions                      *
173  *===========================================================================*/
174 
175 /*
176  * Function: kb_init
177  * Parameter: tp - terminal whose keyboard driver is to be initialised
178  *
179  * Initialize the keyboard driver for the specified terminal line.
180  */
181 void kb_init(tty_t *tp)
182 {
183     register struct kb_s *kb;
184 
185     tp->tty_devread = kb_read;               /* Input function. */
186 
187     /*
188      * Install kerboard_intr as the handler for input received on the
189      * associated SunOS file descriptor.
190      */
191     sunio_install_handler(TERMINAL_FD + tty_line(tp) * 2, keyboard_intr);
192 
193     kb = kb_addr(tp);
194     kb->ihead = kb->itail = kb->ibuf;        /* The input buffer is empty */
195     kb->icount = 0;
196 }
197 
198 
199 /*
200  * Function: kb_read
201  * Parameter: tp - terminal to read input from
202  *
203  * Process characters from the circular keyboard buffer.  Characters are
204  * removed from the keyboard buffer one at a time.  Each is checked to
205  * see if it is a function key used by the kernel.  If so, the character
206  * is actioned and not passed on; otherwise the character is passed on to
207  * in_process().
208  */
209 static void kb_read(tty_t *tp)
210 {
211     struct kb_s *kb;
212     int scode;
213     char ch;
214     
215     kb = kb_addr(tp);
216     
217     lock();
218     while (kb->icount > 0) {
219         scode = *kb->itail++;                   /* take one key scan code */
220         if (kb->itail == kb->ibuf + KB_IN_BYTES) kb->itail = kb->ibuf;
221         kb->icount--;
222 
223         /*
224          * Is it a function keys used for a debug dump?
225          */
226         if (func_key(tp, scode)) continue;
227 
228         /*
229          * It's not a function key.  in_process calls lock, so go into it
230          * "unlocked" as otherwise we'll get a recursive lock error.
231          */
232         ch = scode;
233         unlock();
234         (void) in_process(tp, &ch, 1);
235         lock();
236     }
237     unlock();
238 }
239 
240 
241 /*
242  * Function: func_key
243  * Parameters: tp - terminal line the input was received on
244  *             scode - scan code for key received.
245  * Returns: TRUE if scode should be passed on as user input, FALSE if
246  *          it has been consumed by the kernel
247  * 
248  * Some key-strokes are intercepted by the kernel for its own purposes.
249  * At present two codes are intercepted.  Code 0x1f (^_) is used to
250  * cause an emegency panic when the system is not responding (panic
251  * generates various pieces of debugging info).  The other code is
252  * MLOGIN_HANGUP, which us sent by mlogin when it is about to exit.
253  */
254 static int func_key(tty_t *tp, int scode)
255 {
256     switch(scode) {
257     case 0x1f: /* ^_, I'm desperate---ignored unless typed on the console */
258         if (tty_line(tp) != 0) return FALSE;
259         panic("TERMINAL PANIC", NO_NUM);
260         break;
261 
262     case MLOGIN_HANGUP:
263         hangup(tty_line(tp));
264         break;
265 
266     default:
267         return FALSE;
268     }
269     return TRUE;
270 }
271 
272 
273 /*==========================================================================*
274  *                           reboot section                                 *
275  *==========================================================================*/
276 
277 /*
278  * Function: wreboot
279  * Parameter: how - unused in smx
280  *
281  * Terminates smx by exiting.
282  */
283 void wreboot(int how)
284 {
285     printf("Exiting smx\n");
286     SunOS(SYS_exit, 0);
287     /*NOTREACHED*/
288 }
289 

~ [ 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.