source: rtems/c/src/lib/libchip/serial/mc68681.c @ 4f0ffa57

4.104.114.84.95
Last change on this file since 4f0ffa57 was 4f0ffa57, checked in by Joel Sherrill <joel.sherrill@…>, on 06/23/98 at 17:42:46

Removed RTS and DTR handling code since the MC68681 seems to only have
automatic handling of RTS/CTS. This only protects the on-chip buffers
and FIFOs -- not the termios queues as the RTS/CTS code in here did. It
may be necessary in the future to enable this automatic support.

Interrupt processing code added.

In some places, channel and duart base addresses were swapped.

  • Property mode set to 100644
File size: 18.9 KB
Line 
1/*
2 *  This file contains the termios TTY driver for the Motorola MC68681.
3 *
4 *  This part is available from a number of secondary sources.
5 *  In particular, we know about the following:
6 *
7 *     + Exar 88c681 and 68c681
8 *
9 *  COPYRIGHT (c) 1989-1998.
10 *  On-Line Applications Research Corporation (OAR).
11 *  Copyright assigned to U.S. Government, 1994.
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.OARcorp.com/rtems/license.html.
16 *
17 *  $Id$
18 */
19
20#include <rtems.h>
21#include <rtems/libio.h>
22#include <stdlib.h>
23#include <ringbuf.h>
24
25#include <libchip/serial.h>
26#include "mc68681_p.h"
27#include "mc68681.h"
28
29/*
30 * Flow control is only supported when using interrupts
31 */
32
33console_fns mc68681_fns =
34{
35  mc68681_probe,                  /* deviceProbe */
36  mc68681_open,                   /* deviceFirstOpen */
37  mc68681_flush,                  /* deviceLastClose */
38  NULL,                           /* deviceRead */
39  mc68681_write_support_int,      /* deviceWrite */
40  mc68681_initialize_interrupts,  /* deviceInitialize */
41  mc68681_write_polled,           /* deviceWritePolled */
42  mc68681_set_attributes,         /* deviceSetAttributes */
43  FALSE,                          /* deviceOutputUsesInterrupts */
44};
45
46console_fns mc68681_fns_polled =
47{
48  mc68681_probe,                       /* deviceProbe */
49  mc68681_open,                        /* deviceFirstOpen */
50  mc68681_close,                       /* deviceLastClose */
51  mc68681_inbyte_nonblocking_polled,   /* deviceRead */
52  mc68681_write_support_polled,        /* deviceWrite */
53  mc68681_init,                        /* deviceInitialize */
54  mc68681_write_polled,                /* deviceWritePolled */
55  mc68681_set_attributes,              /* deviceSetAttributes */
56  FALSE,                               /* deviceOutputUsesInterrupts */
57};
58
59extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
60
61/*
62 *  Console Device Driver Entry Points
63 */
64
65/*
66 *  mc68681_probe
67 *
68 *  Default probe routine which simply say the port is present.
69 */
70
71static boolean mc68681_probe(int minor)
72{
73  /*
74   * If the configuration dependent probe has located the device then
75   * assume it is there
76   */
77  return(TRUE);
78}
79
80/*
81 *  mc68681_baud_rate
82 *
83 *  This routine returns the proper ACR bit and baud rate field values
84 *  based on the requested baud rate.  The baud rate set to be used
85 *  must be configured by the user.
86 */
87
88static int mc68681_baud_rate(
89  int           minor,
90  int           baud,
91  unsigned int *baud_mask_p,
92  unsigned int *acr_bit_p
93)
94{
95  unsigned int baud_mask;
96  unsigned int acr_bit;
97  int          status;
98
99  baud_mask = 0;
100  acr_bit = 0;
101  status = 0;
102
103  if ( !(Console_Port_Tbl[minor].ulDataPort & MC68681_DATA_BAUD_RATE_SET_1) )
104    acr_bit = 1;
105
106  if (!(baud & CBAUD)) {
107    *baud_mask_p = 0x0B;     /* default to 9600 baud */
108    *acr_bit_p   = acr_bit;
109    return status;
110  }
111
112  if ( !acr_bit ) {
113    /*
114     *  Baud Rate Set 1
115     */
116
117    switch (baud & CBAUD) {
118      case B50:    baud_mask = 0x00; break;
119      case B110:   baud_mask = 0x01; break;
120      case B134:   baud_mask = 0x02; break;
121      case B200:   baud_mask = 0x03; break;
122      case B300:   baud_mask = 0x04; break;
123      case B600:   baud_mask = 0x05; break;
124      case B1200:  baud_mask = 0x06; break;
125      case B2400:  baud_mask = 0x08; break;
126      case B4800:  baud_mask = 0x09; break;
127      case B9600:  baud_mask = 0x0B; break;
128      case B38400: baud_mask = 0x0C; break;
129
130      case B0:
131      case B75:
132      case B150:
133      case B1800:
134      case B19200:
135      case B57600:
136      case B115200:
137      case B230400:
138      case B460800:
139        status = -1;
140        break;
141    }
142  } else {
143    /*
144     *  Baud Rate Set 2
145     */
146
147    switch (baud & CBAUD) {
148      case B75:    baud_mask = 0x00; break;
149      case B110:   baud_mask = 0x01; break;
150      case B134:   baud_mask = 0x02; break;
151      case B150:   baud_mask = 0x03; break;
152      case B300:   baud_mask = 0x04; break;
153      case B600:   baud_mask = 0x05; break;
154      case B1200:  baud_mask = 0x06; break;
155      case B1800:  baud_mask = 0x0A; break;
156      case B2400:  baud_mask = 0x08; break;
157      case B4800:  baud_mask = 0x09; break;
158      case B9600:  baud_mask = 0x0B; break;
159      case B19200: baud_mask = 0x0C; break;
160
161      case B0:
162      case B50:
163      case B200:
164      case B38400:
165      case B57600:
166      case B115200:
167      case B230400:
168      case B460800:
169        status = -1;
170        break;
171    }
172  }
173
174  *baud_mask_p = baud_mask;
175  *acr_bit_p   = acr_bit;
176  return status;
177}
178
179/*
180 *  mc68681_set_attributes
181 *
182 *  This function sets the DUART channel to reflect the requested termios
183 *  port settings.
184 */
185
186static int mc68681_set_attributes(
187  int minor,
188  const struct termios *t
189)
190{
191  unsigned32             pMC68681_port;
192  unsigned32             pMC68681;
193  unsigned int           mode1;
194  unsigned int           mode2;
195  unsigned int           baud_mask;
196  unsigned int           acr_bit;
197  setRegister_f          setReg;
198  rtems_interrupt_level  Irql;
199
200  pMC68681      = Console_Port_Tbl[minor].ulCtrlPort1;
201  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
202  setReg        = Console_Port_Tbl[minor].setRegister;
203
204  /*
205   *  Set the baud rate
206   */
207
208  if ( mc68681_baud_rate( minor, t->c_cflag, &baud_mask, &acr_bit ) == -1 )
209    return -1;
210
211  baud_mask |=  baud_mask << 4;
212  acr_bit   <<= 7;
213
214  /*
215   *  Parity
216   */
217
218  mode1 = 0;
219  mode2 = 0;
220
221  if (t->c_cflag & PARENB) {
222    if (t->c_cflag & PARODD)
223      mode1 |= 0x04;
224    else
225      mode1 |= 0x04;
226  } else {
227   mode1 |= 0x10;
228  }
229
230  /*
231   *  Character Size
232   */
233
234  if (t->c_cflag & CSIZE) {
235    switch (t->c_cflag & CSIZE) {
236      case CS5:  break;
237      case CS6:  mode1 |= 0x01;  break;
238      case CS7:  mode1 |= 0x02;  break;
239      case CS8:  mode1 |= 0x03;  break;
240    }
241  } else {
242    mode1 |= 0x03;       /* default to 9600,8,N,1 */
243  }
244
245  /*
246   *  Stop Bits
247   */
248 
249  if (t->c_cflag & CSTOPB) {
250    mode2 |= 0x07;                      /* 2 stop bits */
251  } else {
252    if ((t->c_cflag & CSIZE) == CS5)    /* CS5 and 2 stop bits not supported */
253      return -1;
254    mode2 |= 0x0F;                      /* 1 stop bit */
255  }
256
257  rtems_interrupt_disable(Irql);
258    (*setReg)( pMC68681, MC68681_AUX_CTRL_REG, acr_bit );
259    (*setReg)( pMC68681_port, MC68681_CLOCK_SELECT, baud_mask );
260    (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_MR_PTR );
261    (*setReg)( pMC68681_port, MC68681_MODE, mode1 );
262    (*setReg)( pMC68681_port, MC68681_MODE, mode2 );
263  rtems_interrupt_enable(Irql);
264  return 0;
265}
266
267/*
268 *  mc68681_initialize_context
269 *
270 *  This function sets the default values of the per port context structure.
271 */
272
273static void mc68681_initialize_context(
274  int               minor,
275  mc68681_context  *pmc68681Context
276)
277{
278  int          port;
279  unsigned int pMC68681;
280 
281  pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
282
283  pmc68681Context->mate = -1;
284
285  for (port=0 ; port<Console_Port_Count ; port++ ) {
286    if ( Console_Port_Tbl[port].ulCtrlPort1 == pMC68681 ) {
287      pmc68681Context->mate = port;
288      break;
289    }
290  }
291
292}
293
294/*
295 *  mc68681_build_imr
296 *
297 *  This function returns the value for the interrupt mask register for this
298 *  DUART.  Since this is a shared register, we must look at the other port
299 *  on this chip to determine whether or not it is using interrupts.
300 */
301
302static unsigned int mc68681_build_imr(
303  int  minor,
304  int  enable_flag
305)
306{
307  int              mate;
308  unsigned int     mask;
309  unsigned int     mate_mask;
310  unsigned int     pMC68681;
311  unsigned int     pMC68681_port;
312  mc68681_context *pmc68681Context;
313 
314  pMC68681       = Console_Port_Tbl[minor].ulCtrlPort1;
315  pMC68681_port  = Console_Port_Tbl[minor].ulCtrlPort2;
316  pmc68681Context = (mc68681_context *) Console_Port_Data[minor].pDeviceContext;
317  mate            = pmc68681Context->mate;
318
319  mate_mask = 0;
320
321  /*
322   *  Decide if the other port on this DUART is using interrupts
323   */
324
325  if ( mate != -1 ) {
326    if ( Console_Port_Tbl[mate].pDeviceFns->deviceOutputUsesInterrupts )
327      mate_mask = 0x03;
328
329    /*
330     *  If equal, then minor is A so the mate must be B
331     */
332
333    if ( pMC68681 == pMC68681_port )
334      mate_mask <<= 4;
335  }
336
337  /*
338   *  Add in minor's mask
339   */
340
341  mask = 0;
342  if ( enable_flag ) {
343    if ( Console_Port_Tbl[minor].pDeviceFns->deviceOutputUsesInterrupts ) {
344      if ( pMC68681 == pMC68681_port )
345         mask = 0x03;
346      else
347         mask = 0x30;
348    }
349  }
350
351  return mask | mate_mask;
352}
353
354/*
355 *  mc68681_init
356 *
357 *  This function initializes the DUART to a quiecsent state.
358 */
359
360static void mc68681_init(int minor)
361{
362  unsigned32              pMC68681_port;
363  unsigned32              pMC68681;
364  mc68681_context        *pmc68681Context;
365  setRegister_f           setReg;
366  getRegister_f           getReg;
367
368  pmc68681Context = (mc68681_context *) malloc(sizeof(mc68681_context));
369
370  Console_Port_Data[minor].pDeviceContext = (void *)pmc68681Context;
371
372  mc68681_initialize_context( minor, pmc68681Context );
373
374  pMC68681      = Console_Port_Tbl[minor].ulCtrlPort1;
375  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
376  setReg        = Console_Port_Tbl[minor].setRegister;
377  getReg        = Console_Port_Tbl[minor].getRegister;
378
379  /*
380   *  Reset everything and leave this port disabled.
381   */
382
383  (*setReg)( pMC68681, MC68681_COMMAND, MC68681_MODE_REG_RESET_RX );
384  (*setReg)( pMC68681, MC68681_COMMAND, MC68681_MODE_REG_RESET_TX );
385  (*setReg)( pMC68681, MC68681_COMMAND, MC68681_MODE_REG_RESET_ERROR );
386  (*setReg)( pMC68681, MC68681_COMMAND, MC68681_MODE_REG_RESET_BREAK );
387  (*setReg)( pMC68681, MC68681_COMMAND, MC68681_MODE_REG_STOP_BREAK );
388  (*setReg)( pMC68681, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_TX );
389  (*setReg)( pMC68681, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_RX );
390
391
392  (*setReg)( pMC68681, MC68681_MODE_REG_1A, 0x00 );
393  (*setReg)( pMC68681, MC68681_MODE_REG_2A, 0x02 );
394
395  /*
396   *  Disable interrupts on RX and TX for this port
397   */
398
399  (*setReg)( pMC68681, MC68681_INTERRUPT_MASK_REG, mc68681_build_imr(minor, 0));
400}
401
402/*
403 *  mc68681_open
404 *
405 *  This function opens a port for communication.
406 *
407 *  Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
408 */
409
410static int mc68681_open(
411  int      major,
412  int      minor,
413  void    *arg
414)
415{
416  unsigned32             pMC68681;
417  unsigned32             pMC68681_port;
418  unsigned int           baud;
419  unsigned int           acr;
420  unsigned int           vector;
421  rtems_interrupt_level  Irql;
422  setRegister_f          setReg;
423
424  pMC68681      = Console_Port_Tbl[minor].ulCtrlPort1;
425  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
426  setReg        = Console_Port_Tbl[minor].setRegister;
427  vector        = Console_Port_Tbl[minor].ulIntVector;
428
429  (void) mc68681_baud_rate( minor, B9600, &baud, &acr );
430
431  /*
432   *  Set the DUART channel to a default useable state
433   */
434
435  rtems_interrupt_disable(Irql);
436    (*setReg)( pMC68681, MC68681_AUX_CTRL_REG, acr );
437    (*setReg)( pMC68681_port, MC68681_CLOCK_SELECT, baud );
438    (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_MR_PTR );
439    (*setReg)( pMC68681_port, MC68681_MODE, 0x13 );
440    (*setReg)( pMC68681_port, MC68681_MODE, 0x07 );
441  rtems_interrupt_enable(Irql);
442
443  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_ENABLE_TX );
444  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_ENABLE_RX );
445
446  (*setReg)( pMC68681, MC68681_INTERRUPT_VECTOR_REG, vector );
447
448  return RTEMS_SUCCESSFUL;
449}
450
451/*
452 *  mc68681_close
453 *
454 *  This function shuts down the requested port.
455 */
456
457static int mc68681_close(
458  int      major,
459  int      minor,
460  void    *arg
461)
462{
463  unsigned32      pMC68681;
464  unsigned32      pMC68681_port;
465  setRegister_f   setReg;
466
467  pMC68681      = Console_Port_Tbl[minor].ulCtrlPort1;
468  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
469  setReg        = Console_Port_Tbl[minor].setRegister;
470
471  /*
472   *  Disable interrupts from this channel and then disable it totally.
473   */
474
475  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_TX );
476  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_RX );
477
478  return(RTEMS_SUCCESSFUL);
479}
480
481/*
482 *  mc68681_write_polled
483 *
484 *  This routine polls out the requested character.
485 */
486
487static void mc68681_write_polled(
488  int   minor,
489  char  cChar
490)
491{
492  unsigned32              pMC68681_port;
493  unsigned char           ucLineStatus;
494  int                     iTimeout;
495  getRegister_f           getReg;
496  setRegister_f           setReg;
497
498  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
499  getReg        = Console_Port_Tbl[minor].getRegister;
500  setReg        = Console_Port_Tbl[minor].setRegister;
501
502  /*
503   * wait for transmitter holding register to be empty
504   */
505  iTimeout = 1000;
506  ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
507  while ((ucLineStatus & MC68681_TX_READY) == 0) {
508
509    /*
510     * Yield while we wait
511     */
512
513     if(_System_state_Is_up(_System_state_Get())) {
514       rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
515     }
516     ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
517     if(!--iTimeout) {
518       break;
519     }
520  }
521
522  /*
523   * transmit character
524   */
525
526  (*setReg)(pMC68681_port, MC68681_TX_BUFFER, cChar);
527}
528
529/*
530 *  mc68681_process
531 *
532 *  This routine is the per port console interrupt handler.
533 */
534
535static void mc68681_process(
536  int  minor
537)
538{
539  unsigned32              pMC68681;
540  unsigned32              pMC68681_port;
541  volatile unsigned8      ucLineStatus;
542  char                    cChar;
543  getRegister_f           getReg;
544  setRegister_f           setReg;
545
546  pMC68681      = Console_Port_Tbl[minor].ulCtrlPort1;
547  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
548  getReg        = Console_Port_Tbl[minor].getRegister;
549  setReg        = Console_Port_Tbl[minor].setRegister;
550
551  /*
552   * Deal with any received characters
553   */
554  while(TRUE) {
555    ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
556    if(!(ucLineStatus & MC68681_RX_READY)) {
557      break;
558    }
559    /*
560     *  If there is a RX error, then dump all the data.
561     */
562    if ( ucLineStatus & MC68681_RX_ERRORS ) {
563      do {
564        cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
565        ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
566      } while ( ucLineStatus & MC68681_RX_READY );
567      continue;
568    }
569    cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
570    rtems_termios_enqueue_raw_characters(
571      Console_Port_Data[minor].termios_data,
572      &cChar,
573      1
574    );
575  }
576
577  /*
578   *  Deal with the transmitter
579   */
580
581  while(TRUE) {
582    if(Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer)) {
583      Console_Port_Data[minor].bActive = FALSE;
584
585      /*
586       * There is no data to transmit
587       */
588      break;
589    }
590
591    ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
592    if(!(ucLineStatus & (MC68681_TX_EMPTY|MC68681_TX_READY))) {
593      /*
594       *  We'll get another interrupt when the TX can take another character.
595       */
596      break;
597    }
598
599    Ring_buffer_Remove_character( &Console_Port_Data[minor].TxBuffer, cChar);
600    /*
601     * transmit character
602     */
603    (*setReg)(pMC68681_port, MC68681_TX_BUFFER, cChar);
604  }
605
606}
607
608/*
609 *  mc68681_isr
610 *
611 *  This is the single interrupt entry point which parcels interrupts
612 *  out to the various ports.
613 */
614
615static rtems_isr mc68681_isr(
616  rtems_vector_number vector
617)
618{
619  int     minor;
620
621  for(minor=0 ; minor<Console_Port_Count ; minor++) {
622    if(vector == Console_Port_Tbl[minor].ulIntVector) {
623      mc68681_process(minor);
624    }
625  }
626}
627
628/*
629 *  mc68681_flush
630 *
631 *  This routine waits before all output is completed before closing
632 *  the requested port.
633 *
634 *  NOTE:  This is the "interrupt mode" close entry point.
635 */
636
637static int mc68681_flush(int major, int minor, void *arg)
638{
639  while(!Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer)) {
640    /*
641     * Yield while we wait
642     */
643    if(_System_state_Is_up(_System_state_Get())) {
644      rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
645    }
646  }
647
648  mc68681_close(major, minor, arg);
649
650  return(RTEMS_SUCCESSFUL);
651}
652
653/*
654 *  mc68681_enable_interrupts
655 *
656 *  This function initializes the hardware for this port to use interrupts.
657 */
658
659static void mc68681_enable_interrupts(
660  int minor
661)
662{
663  unsigned32            pMC68681;
664  setRegister_f         setReg;
665
666  pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
667  setReg   = Console_Port_Tbl[minor].setRegister;
668
669  /*
670   *  Enable interrupts on RX and TX -- not break
671   */
672
673  (*setReg)( pMC68681, MC68681_INTERRUPT_MASK_REG, mc68681_build_imr(minor, 1));
674}
675
676/*
677 *  mc68681_initialize_interrupts
678 *
679 *  This routine initializes the console's receive and transmit
680 *  ring buffers and loads the appropriate vectors to handle the interrupts.
681 */
682
683static void mc68681_initialize_interrupts(int minor)
684{
685  mc68681_init(minor);
686
687  Ring_buffer_Initialize(&Console_Port_Data[minor].TxBuffer);
688
689  Console_Port_Data[minor].bActive = FALSE;
690
691  set_vector(mc68681_isr, Console_Port_Tbl[minor].ulIntVector, 1);
692
693  mc68681_enable_interrupts(minor);
694}
695
696/*
697 *  mc68681_write_support_int
698 *
699 *  Console Termios output entry point when using interrupt driven output.
700 */
701
702static int mc68681_write_support_int(
703  int   minor,
704  const char *buf,
705  int   len
706)
707{
708  int i;
709  unsigned32 Irql;
710
711  for(i=0 ; i<len ;) {
712    if(Ring_buffer_Is_full(&Console_Port_Data[minor].TxBuffer)) {
713      if(!Console_Port_Data[minor].bActive) {
714        /*
715         * Wake up the device
716         */
717        rtems_interrupt_disable(Irql);
718        Console_Port_Data[minor].bActive = TRUE;
719        mc68681_process(minor);
720        rtems_interrupt_enable(Irql);
721      } else {
722        /*
723         * Yield
724         */
725        rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
726      }
727
728      /*
729       * Wait for ring buffer to empty
730       */
731      continue;
732    }
733    else {
734      Ring_buffer_Add_character( &Console_Port_Data[minor].TxBuffer, buf[i]);
735      i++;
736    }
737  }
738
739  /*
740   * Ensure that characters are on the way
741   */
742
743  if(!Console_Port_Data[minor].bActive) {
744    /*
745     * Wake up the device
746     */
747    rtems_interrupt_disable(Irql);
748    Console_Port_Data[minor].bActive = TRUE;
749    mc68681_process(minor);
750    rtems_interrupt_enable(Irql);
751  }
752
753  return (len);
754}
755
756/*
757 *  mc68681_write_support_polled
758 *
759 *  Console Termios output entry point when using polled output.
760 *
761 */
762
763static int mc68681_write_support_polled(
764  int         minor,
765  const char *buf,
766  int         len
767)
768{
769  int nwrite = 0;
770
771  /*
772   * poll each byte in the string out of the port.
773   */
774  while (nwrite < len) {
775    /*
776     * transmit character
777     */
778    mc68681_write_polled(minor, *buf++);
779    nwrite++;
780  }
781
782  /*
783   * return the number of bytes written.
784   */
785  return nwrite;
786}
787
788/*
789 *  mc68681_inbyte_nonblocking_polled
790 *
791 *  Console Termios polling input entry point.
792 */
793
794static int mc68681_inbyte_nonblocking_polled(
795  int minor
796)
797{
798  unsigned32           pMC68681_port;
799  unsigned char        ucLineStatus;
800  char                 cChar;
801  getRegister_f        getReg;
802
803  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
804  getReg        = Console_Port_Tbl[minor].getRegister;
805
806  ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
807  if(ucLineStatus & MC68681_RX_READY) {
808    cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
809    return (int)cChar;
810  } else {
811    return -1;
812  }
813}
Note: See TracBrowser for help on using the repository browser.