source: rtems/c/src/libchip/serial/mc68681.c @ b7ebcea

4.104.114.84.9
Last change on this file since b7ebcea was b7ebcea, checked in by Joel Sherrill <joel.sherrill@…>, on Jun 23, 1998 at 2:59:26 PM

Added close.

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