Ignore:
Timestamp:
Jun 12, 2000, 3:00:15 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
edeed26
Parents:
0ab65474
Message:

Merged from 4.5.0-beta3a

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/m68k/mvme167/console/console.c

    r0ab65474 rdf49c60  
    33 *
    44 *  This file contains the MVME167 termios console package. Only asynchronous
    5  *  I/O is supported. Normal I/O uses DMA for output, interrupts for input.
    6  *  Very limited support is provided for polled I/O. Polled I/O is intended
    7  *  only for running the RTEMS test suites, and uses the 167Bug console only.
     5 *  I/O is supported.
    86 *
    97 *  /dev/tty0 is channel 0, Serial Port 1/Console on the MVME712M.
     
    1210 *  /dev/tty3 is channel 3, Serial Port 4 on the MVME712M.
    1311 *
    14  *  /dev/console is fixed to be /dev/tty01, Serial Port 2. 167Bug is given
    15  *  Serial Port 1/Console. Do not open /dev/tty00.
     12 *  Normal I/O uses DMA for output, interrupts for input. /dev/console is
     13 *  fixed to be /dev/tty01, Serial Port 2. Very limited support is provided
     14 *  for polled I/O. Polled I/O is intended only for running the RTEMS test
     15 *  suites. In all cases, Serial Port 1/Console is allocated to 167Bug and
     16 *  is the dedicated debugger port. We configure GDB to use 167Bug for
     17 *  debugging. When debugging with GDB or 167Bug, do not open /dev/tty00.
    1618 *
    1719 *  Modern I/O chips often contain a number of I/O devices that can operate
    1820 *  almost independently of each other. Typically, in RTEMS, all devices in
    1921 *  an I/O chip are handled by a single device driver, but that need not be
    20  *  always the case. Each device driver must supply six entry  points in the
     22 *  always the case. Each device driver must supply six entry points in the
    2123 *  Device Driver Table: a device initialization function, as well as an open,
    2224 *  close, read, write and a control function. RTEMS assigns a device major
     
    6062 *  configuration, and that configuration then changed through a series of
    6163 *  device driver control calls. There is no standard API in RTEMS to switch
    62  *   a serial line to some synchronous protocol.
     64 *  a serial line to some synchronous protocol.
    6365 *
    6466 *  A better approach is to treat each channel as a separate device, each with
     
    9799 *  multiple tasks is likely to cause significant problems! Concurrency
    98100 *  control is implemented in the termios package.
    99 *
     101 *
    100102 *  THE INTERRUPT LEVEL IS SET TO 1 FOR ALL CHANNELS.
    101103 *  If the CD2401 is to be used for high speed synchronous serial I/O, the
     
    126128#define M167_INIT
    127129
     130#include <stdarg.h>
     131#include <stdio.h>
    128132#include <termios.h>
    129133#include <bsp.h>                /* Must be before libio.h */
    130134#include <rtems/libio.h>
    131135
    132 #define CD2401_INT_LEVEL 1      /* Interrupt level for the CD2401 */
    133 #define CD2401_POLLED_IO 0      /* 0 for interrupt-driven, 1 for polled I/O */
    134 
    135136
    136137/* Channel info */
    137 /* static */ struct {
     138/* static */ volatile struct {
    138139  void *tty;                    /* Really a struct rtems_termios_tty * */
    139140  int len;                      /* Record nb of chars being TX'ed */
    140141  const char *buf;              /* Record where DMA is coming from */
    141   rtems_unsigned16 used_buf_A;  /* Nb of times we used output DMA channel A */
    142   rtems_unsigned16 used_buf_B;  /* Nb of times we used output DMA channel B */
    143   rtems_unsigned16 wait_buf_A;  /* Nb of times we waited for output DMA channel A */
    144   rtems_unsigned16 wait_buf_B;  /* Nb of times we waited for output DMA channel B */
    145142  rtems_unsigned32 spur_cnt;    /* Nb of spurious ints so far */
    146143  rtems_unsigned32 spur_dev;    /* Indo on last spurious int */
    147144  rtems_unsigned32 buserr_addr; /* Faulting address */
    148145  rtems_unsigned32 buserr_type; /* Reason of bus error during DMA */
     146  rtems_unsigned8  own_buf_A;   /* If true, buffer A belongs to the driver */
     147  rtems_unsigned8  own_buf_B;   /* If true, buffer B belongs to the driver */
     148  rtems_unsigned8  txEmpty;     /* If true, the output FIFO is supposed to be empty */
    149149} CD2401_Channel_Info[4];
    150150
     
    167167rtems_isr_entry Prev_modem_isr;     /* Previous modem/timer isr */
    168168
     169
     170/* Define the following symbol to trace the calls to this driver */
     171/* #define CD2401_RECORD_DEBUG_INFO */
     172#include "console-recording.c"
     173
     174
    169175/* Utility functions */
     176void cd2401_udelay( unsigned long delay );
    170177void cd2401_chan_cmd( rtems_unsigned8 channel, rtems_unsigned8 cmd, rtems_unsigned8 wait );
    171178rtems_unsigned16 cd2401_bitrate_divisor( rtems_unsigned32 clkrate, rtems_unsigned32* bitrate );
     
    186193int cd2401_stopRemoteTx( int minor );
    187194int cd2401_write( int minor, const char *buf, int len );
     195int cd2401_drainOutput( int minor );
    188196int _167Bug_pollRead( int minor );
    189197int _167Bug_pollWrite( int minor, const char *buf, int len );
     
    193201 *  Utility functions.
    194202 */
     203
     204/*
     205 *  Assumes that clock ticks 1 million times per second.
     206 *
     207 *  MAXIMUM DELAY IS ABOUT 20 ms
     208 *
     209 *  Input parameters:
     210 *    delay: Number of microseconds to delay.
     211 *
     212 *  Output parameters: NONE
     213 *
     214 *  Return values: NONE
     215 */
     216 void cd2401_udelay
     217(
     218  unsigned long delay
     219)
     220{
     221  unsigned long i = 20000;  /* In case clock is off */
     222  rtems_interval ticks_per_second, start_ticks, end_ticks, current_ticks;
     223   
     224  rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second );
     225  rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks );
     226  end_ticks = start_ticks + delay;
     227 
     228  do {
     229    rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &current_ticks);
     230  } while ( --i && (current_ticks <= end_ticks) );
     231 
     232  CD2401_RECORD_DELAY_INFO(( start_ticks, end_ticks, current_ticks, i ));
     233}
     234
    195235
    196236/*
     
    289329
    290330  for ( i = 3; i >= 0; i-- ) {
    291     /*
    292      *  Paranoia -- Should already be blank because array should be in bss
    293      *  section, which is explicitly zeroed at boot time.
    294      */
    295331    CD2401_Channel_Info[i].tty = NULL;
    296332    CD2401_Channel_Info[i].len = 0;
    297333    CD2401_Channel_Info[i].buf = NULL;
    298     CD2401_Channel_Info[i].used_buf_A = 0;
    299     CD2401_Channel_Info[i].used_buf_B = 0;
    300     CD2401_Channel_Info[i].wait_buf_A = 0;
    301     CD2401_Channel_Info[i].wait_buf_B = 0;
    302334    CD2401_Channel_Info[i].spur_cnt = 0;
    303335    CD2401_Channel_Info[i].spur_dev = 0;
    304336    CD2401_Channel_Info[i].buserr_type = 0;
    305337    CD2401_Channel_Info[i].buserr_addr = 0;
     338    CD2401_Channel_Info[i].own_buf_A = TRUE;
     339    CD2401_Channel_Info[i].own_buf_B = TRUE;
     340    CD2401_Channel_Info[i].txEmpty = TRUE;
    306341  }
    307342
     
    438473
    439474  cd2401->meoir = 0;            /* EOI */
     475  CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO(( ch,
     476                                          CD2401_Channel_Info[ch].spur_dev,
     477                                          CD2401_Channel_Info[ch].spur_cnt ));
    440478}
    441479
     
    473511    cd2401->ier &= 0xDF;            /* Disable rx timeout interrupt */
    474512  cd2401->reoir = 0x08;             /* EOI; exception char not read */
     513  CD2401_RECORD_RE_ISR_SPURIOUS_INFO(( ch,
     514                                       CD2401_Channel_Info[ch].spur_dev,
     515                                       CD2401_Channel_Info[ch].spur_cnt ));
    475516}
    476517
     
    493534{
    494535  char c;
    495   rtems_unsigned8 ch, nchars;
    496 
     536  rtems_unsigned8 ch, status, nchars, i, total;
     537  char buffer[256];
     538
     539  status = cd2401->u5.b.risrl;
    497540  ch = cd2401->licr >> 2;
    498541
    499   /* Has this channel been initialized? */
    500   if (CD2401_Channel_Info[ch].tty) {
    501     /* Yes, read chars, enqueue them, and issue EOI */
    502     nchars = cd2401->rfoc;      /* Number of chars to retrieve from rx FIFO */
     542  /* Has this channel been initialized or is it a condition we ignore? */
     543  if ( CD2401_Channel_Info[ch].tty && !status ) {
     544    /* Normal Rx Int, read chars, enqueue them, and issue EOI */
     545    total = nchars = cd2401->rfoc;  /* Nb of chars to retrieve from rx FIFO */
     546    i = 0;
    503547    while ( nchars-- > 0 ) {
    504       c = (char)cd2401->dr;     /* Next char in rx FIFO */
    505       rtems_termios_enqueue_raw_characters (
    506         CD2401_Channel_Info[ch].tty,
    507         &c,
    508         1 );
     548      c = (char)cd2401->dr;         /* Next char in rx FIFO */
     549      rtems_termios_enqueue_raw_characters( CD2401_Channel_Info[ch].tty ,&c, 1 );
     550      buffer[i++] = c;
    509551    }
    510     cd2401->reoir = 0;          /* EOI */
     552    cd2401->reoir = 0;              /* EOI */
     553    CD2401_RECORD_RX_ISR_INFO(( ch, total, buffer ));
    511554  } else {
    512555    /* No, record as spurious interrupt */
     
    514557        (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl;
    515558    CD2401_Channel_Info[ch].spur_cnt++;
    516     cd2401->reoir = 0x04;       /* EOI - character not read */
     559    cd2401->reoir = 0x04;           /* EOI - character not read */
     560    CD2401_RECORD_RX_ISR_SPURIOUS_INFO(( ch, status,
     561                                         CD2401_Channel_Info[ch].spur_dev,
     562                                         CD2401_Channel_Info[ch].spur_cnt ));
    517563  }
    518564}
     
    535581)
    536582{
    537   rtems_unsigned8 ch, status, buserr;
     583  rtems_unsigned8 ch, status, buserr, initial_ier, final_ier;
    538584
    539585  status = cd2401->tisr;
    540586  ch = cd2401->licr >> 2;
     587  initial_ier = cd2401->ier;
    541588
    542589  /* Has this channel been initialized? */
     
    546593        (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr;
    547594    CD2401_Channel_Info[ch].spur_cnt++;
    548     cd2401->ier &= 0xFC;        /* Shut up, whoever you are */
    549     cd2401->teoir = 0x88;       /* EOI - Terminate buffer and no transfer */
     595    final_ier = cd2401->ier &= 0xFC;/* Shut up, whoever you are */
     596    cd2401->teoir = 0x88;           /* EOI - Terminate buffer and no transfer */
     597    CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, final_ier,
     598                                         CD2401_Channel_Info[ch].spur_dev,
     599                                         CD2401_Channel_Info[ch].spur_cnt ));
    550600    return;
    551601  }
     
    563613        (((rtems_unsigned32)cd2401->tcbadru) << 16) | cd2401->tcbadrl;
    564614
    565     cd2401->teoir = 0x80;       /* EOI - terminate bad buffer */
     615    cd2401->teoir = 0x80;           /* EOI - terminate bad buffer */
     616    CD2401_RECORD_TX_ISR_BUSERR_INFO(( ch, status, initial_ier, buserr,
     617                                       CD2401_Channel_Info[ch].buserr_type,
     618                                       CD2401_Channel_Info[ch].buserr_addr ));
    566619    return;
    567620  }
    568621
    569622  if ( status & 0x20 ) {
    570     /* DMA done */
    571     cd2401->ier &= 0xFC;        /* Shut up the interrupts */
    572    
     623    /* DMA done -- Turn off TxD int, turn on TxMpty */
     624    final_ier = cd2401->ier = (cd2401->ier & 0xFE) | 0x02;
     625    if( status & 0x08 ) {
     626      /* Transmit buffer B was released */
     627      CD2401_Channel_Info[ch].own_buf_B = TRUE;
     628    }
     629    else {
     630      /* Transmit buffer A was released */
     631      CD2401_Channel_Info[ch].own_buf_A = TRUE;
     632    }
     633    CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier,
     634                                CD2401_Channel_Info[ch].txEmpty ));
     635
    573636    /* This call can result in a call to cd2401_write() */
    574637    rtems_termios_dequeue_characters (
    575638        CD2401_Channel_Info[ch].tty,
    576639        CD2401_Channel_Info[ch].len );
    577     cd2401->teoir = 0x08;       /* EOI - no data transfered */
     640    cd2401->teoir = 0x08;           /* EOI - no data transfered */
     641  }
     642  else if ( status & 0x02 ) {
     643    /* TxEmpty */
     644    CD2401_Channel_Info[ch].txEmpty = TRUE;
     645    final_ier = cd2401->ier &= 0xFD;/* Shut up the interrupts */
     646    cd2401->teoir = 0x08;           /* EOI - no data transfered */
     647    CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier,
     648                                CD2401_Channel_Info[ch].txEmpty ));
    578649  }
    579650  else {
     
    582653        (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr;
    583654    CD2401_Channel_Info[ch].spur_cnt++;
    584     cd2401->teoir = 0x08;       /* EOI - no data transfered */
     655    cd2401->teoir = 0x08;           /* EOI - no data transfered */
     656    CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, 0xFF,
     657                                         CD2401_Channel_Info[ch].spur_dev,
     658                                         CD2401_Channel_Info[ch].spur_cnt ));
    585659  }
    586660}
     
    616690  struct termios termios;
    617691  rtems_status_code sc;
     692  rtems_interrupt_level level;
     693
     694  rtems_interrupt_disable (level);
    618695
    619696  /*
     
    635712  if (sc != RTEMS_SUCCESSFUL)
    636713    rtems_fatal_error_occurred (sc);
    637    
     714
    638715  /*
    639716   *  Turn off hardware flow control. It is a pain with 3-wire cables.
     
    647724  if (sc != RTEMS_SUCCESSFUL)
    648725    rtems_fatal_error_occurred (sc);
    649  
     726
    650727  /* Mark that the channel as initialized */
    651728  CD2401_Channel_Info[minor].tty = args->iop->data1;
     
    662739  }
    663740
     741  CD2401_RECORD_FIRST_OPEN_INFO(( minor, Init_count ));
     742 
     743  rtems_interrupt_enable (level);
     744
    664745  /* Return something */
    665746  return RTEMS_SUCCESSFUL;
     
    683764)
    684765{
     766  rtems_interrupt_level level;
     767
     768  rtems_interrupt_disable (level);
     769 
    685770  /* Mark that the channel is no longer is use */
    686771  CD2401_Channel_Info[minor].tty = NULL;
     
    697782  }
    698783
     784  CD2401_RECORD_LAST_CLOSE_INFO(( minor, Init_count ));
     785 
     786  rtems_interrupt_enable (level);
     787
    699788  /* return something */
    700789  return RTEMS_SUCCESSFUL;
     
    730819  rtems_unsigned8 hw_flow_ctl, sw_flow_ctl, extra_flow_ctl;
    731820  rtems_unsigned8 icrnl, igncr, inlcr, brkint, ignbrk, parmrk, istrip;
     821  rtems_unsigned8 need_reinitialization = FALSE;
     822  rtems_unsigned8 read_enabled;
    732823  rtems_unsigned16 tx_period, rx_period;
    733824  rtems_unsigned32 out_baud, in_baud;
    734 
    735   /* Set up the line parameters */
     825  rtems_interrupt_level level;
     826
     827  /* Determine what the line parameters should be */
    736828
    737829  /* Output baud rate */
     
    877969    istrip = 0;                 /* Leave as 8 bits */
    878970
    879  
    880   /* Clear channel and disable rx and tx */
    881   cd2401_chan_cmd (minor, 0x40, 1);
    882  
     971  rx_period = cd2401_bitrate_divisor( 20000000Ul, &in_baud );
     972  tx_period = cd2401_bitrate_divisor( 20000000Ul, &out_baud );
     973
     974  /*
     975   *  If this is the first time that the line characteristics are set up, then
     976   *  the device must be re-initialized.
     977   *  Also check if we need to change anything. It is preferable to not touch
     978   *  the device if nothing changes. As soon as we touch it, it tends to
     979   *  glitch. If anything changes, we reprogram all registers. This is
     980   *  harmless.
     981   */
     982  if ( ( CD2401_Channel_Info[minor].tty == 0 ) ||
     983       ( cd2401->cor1 != (parodd | parenb | ignpar | csize) ) ||
     984       ( cd2401->cor2 != (sw_flow_ctl | hw_flow_ctl) ) ||
     985       ( cd2401->cor3 != (extra_flow_ctl | cstopb) )  ||
     986       ( cd2401->cor6 != (igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck) ) ||
     987       ( cd2401->cor7 != istrip ) ||
     988       ( cd2401->u1.async.schr1 != t->c_cc[VSTART] ) ||
     989       ( cd2401->u1.async.schr2 != t->c_cc[VSTOP] ) ||
     990       ( cd2401->rbpr != (unsigned char)rx_period ) ||
     991       ( cd2401->rcor != (unsigned char)(rx_period >> 8) ) ||
     992       ( cd2401->tbpr != (unsigned char)tx_period ) ||
     993       ( cd2401->tcor != ( (tx_period >> 3) & 0xE0 ) ) )
     994    need_reinitialization = TRUE;
     995
    883996  /* Write to the ports */
     997  rtems_interrupt_disable (level);
     998
    884999  cd2401->car = minor;          /* Select channel */
    885   cd2401->cmr = 0x42;           /* Interrupt Rx, DMA Tx, async mode */
    886   cd2401->cor1 = parodd | parenb | ignpar | csize;
    887   cd2401->cor2 = sw_flow_ctl | hw_flow_ctl;
    888   cd2401->cor3 = extra_flow_ctl | cstopb;
    889   cd2401->cor4 = 0x0A;          /* No DSR/DCD/CTS detect; FIFO threshold of 10 */
    890   cd2401->cor5 = 0x0A;          /* No DSR/DCD/CTS detect; DTR threshold of 10 */
    891   cd2401->cor6 = igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck;
    892   cd2401->cor7 = istrip;        /* No LNext; ignore XON/XOFF if frame error; no tx translations */
    893   cd2401->u1.async.schr1 =
    894       t->c_cc[VSTART];          /* Special char 1: XON character */
    895   cd2401->u1.async.schr2 =
    896       t->c_cc[VSTOP];           /* special char 2: XOFF character */
    897   /* Special chars 3 and 4, char range, LNext, RFAR[1..4] and CRC are unused, left as is. */
    898 
    899   /* Set baudrates for receiver and transmitter */
    900   rx_period = cd2401_bitrate_divisor( 20000000Ul, &in_baud );
    901   cd2401->rbpr = (unsigned char)rx_period;
    902   cd2401->rcor = (unsigned char)(rx_period >> 8); /* no DPLL */
    903   tx_period = cd2401_bitrate_divisor( 20000000Ul, &out_baud );
    904   cd2401->tbpr = (unsigned char)tx_period;
    905   cd2401->tcor = (tx_period >> 3) & 0xE0;         /* no x1 ext clk, no loopback */
    906 
    907   /* NEED TO LOOK AT THIS LINE! */
    908   /* Timeout for 4 chars at 9600, 8 bits per char, 1 stop bit */
    909   cd2401->u2.w.rtpr  = 0x04;
    910 
    911   /*  And finally:  */
    912   if ( t->c_cflag & CREAD ) {
    913     /* Re-initialize channel, enable rx and tx */
    914     cd2401_chan_cmd (minor, 0x2A, 1);
    915     /* Enable rx data ints */
    916     cd2401->ier = 0x08;
    917   } else {
    918     /* Re-initialize channel, enable tx, disable rx */
    919     cd2401_chan_cmd (minor, 0x29, 1);
    920   }
     1000  read_enabled = cd2401->csr & 0x80 ? TRUE : FALSE;
     1001 
     1002  if ( (t->c_cflag & CREAD ? TRUE : FALSE ) != read_enabled ) {
     1003    /* Read enable status is changing */
     1004    need_reinitialization = TRUE;
     1005  }
     1006 
     1007  if ( need_reinitialization ) {
     1008    /*
     1009     *  Could not find a way to test whether the CD2401 was done transmitting.
     1010     *  The TxEmpty interrupt does not seem to indicate that the FIFO is empty
     1011     *  in DMA mode. So, just wait a while for output to drain. May not be
     1012     *  enough, but it will have to do (should be long enough for 1 char at
     1013     *  9600 bsp)...
     1014     */
     1015    cd2401_udelay( 2000L );
     1016 
     1017    /* Clear channel */
     1018    cd2401_chan_cmd (minor, 0x40, 1);
     1019
     1020    cd2401->car = minor;        /* Select channel */
     1021    cd2401->cmr = 0x42;         /* Interrupt Rx, DMA Tx, async mode */
     1022    cd2401->cor1 = parodd | parenb | ignpar | csize;
     1023    cd2401->cor2 = sw_flow_ctl | hw_flow_ctl;
     1024    cd2401->cor3 = extra_flow_ctl | cstopb;
     1025    cd2401->cor4 = 0x0A;        /* No DSR/DCD/CTS detect; FIFO threshold of 10 */
     1026    cd2401->cor5 = 0x0A;        /* No DSR/DCD/CTS detect; DTR threshold of 10 */
     1027    cd2401->cor6 = igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck;
     1028    cd2401->cor7 = istrip;      /* No LNext; ignore XON/XOFF if frame error; no tx translations */
     1029    /* Special char 1: XON character */
     1030    cd2401->u1.async.schr1 = t->c_cc[VSTART];
     1031    /* special char 2: XOFF character */
     1032    cd2401->u1.async.schr2 = t->c_cc[VSTOP];
     1033   
     1034    /*
     1035     *  Special chars 3 and 4, char range, LNext, RFAR[1..4] and CRC
     1036     *  are unused, left as is.
     1037     */
     1038
     1039    /* Set baudrates for receiver and transmitter */
     1040    cd2401->rbpr = (unsigned char)rx_period;
     1041    cd2401->rcor = (unsigned char)(rx_period >> 8); /* no DPLL */
     1042    cd2401->tbpr = (unsigned char)tx_period;
     1043    cd2401->tcor = (tx_period >> 3) & 0xE0;         /* no x1 ext clk, no loopback */
     1044 
     1045    /* Timeout for 4 chars at 9600, 8 bits per char, 1 stop bit */
     1046    cd2401->u2.w.rtpr  = 0x04;  /* NEED TO LOOK AT THIS LINE! */
     1047   
     1048    if ( t->c_cflag & CREAD ) {
     1049      /* Re-initialize channel, enable rx and tx */
     1050      cd2401_chan_cmd (minor, 0x2A, 1);
     1051      /* Enable rx data ints */
     1052      cd2401->ier = 0x08;
     1053    } else {
     1054      /* Re-initialize channel, enable tx, disable rx */
     1055      cd2401_chan_cmd (minor, 0x29, 1);
     1056    }
     1057  }   
     1058 
     1059  CD2401_RECORD_SET_ATTRIBUTES_INFO(( minor, need_reinitialization, csize,
     1060                                      cstopb, parodd, parenb, ignpar, inpck,
     1061                                      hw_flow_ctl, sw_flow_ctl, extra_flow_ctl,
     1062                                      icrnl, igncr, inlcr, brkint, ignbrk,
     1063                                      parmrk, istrip, tx_period, rx_period,
     1064                                      out_baud, in_baud ));
     1065
     1066  rtems_interrupt_enable (level);
     1067 
     1068  /*
     1069   *  Looks like the CD2401 needs time to settle after initialization. Give it
     1070   *  10 ms. I don't really believe it, but if output resumes to quickly after
     1071   *  this call, the first few characters are not right.   
     1072   */
     1073  if ( need_reinitialization )
     1074    cd2401_udelay( 10000L );
    9211075
    9221076  /* Return something */
     
    9501104)
    9511105{
    952   cd2401->car = minor;          /* Select channel */
    953   cd2401->stcr = 0x01;          /* Send SCHR1 ahead of chars in FIFO */
     1106  rtems_interrupt_level level;
     1107
     1108  rtems_interrupt_disable (level);
     1109
     1110  cd2401->car = minor;              /* Select channel */
     1111  cd2401->stcr = 0x01;              /* Send SCHR1 ahead of chars in FIFO */
     1112
     1113  CD2401_RECORD_START_REMOTE_TX_INFO(( minor ));
     1114 
     1115  rtems_interrupt_enable (level);
    9541116
    9551117  /* Return something */
     
    9591121
    9601122/*
    961  *  cd2401_stopRemoreTx
     1123 *  cd2401_stopRemoteTx
    9621124 *
    9631125 *  Defined as a callback, but it would appear that it is never called. The
     
    9841146)
    9851147{
    986   cd2401->car = minor;          /* Select channel */
    987   cd2401->stcr = 0x02;          /* Send SCHR2 ahead of chars in FIFO */
     1148  rtems_interrupt_level level;
     1149
     1150  rtems_interrupt_disable (level);
     1151
     1152  cd2401->car = minor;              /* Select channel */
     1153  cd2401->stcr = 0x02;              /* Send SCHR2 ahead of chars in FIFO */
     1154
     1155  CD2401_RECORD_STOP_REMOTE_TX_INFO(( minor ));
     1156
     1157  rtems_interrupt_enable (level);
    9881158
    9891159  /* Return something */
     
    9931163
    9941164/*
    995  * cd2401_write
     1165 *  cd2401_write
    9961166 *
    9971167 *  Initiate DMA output. Termios guarantees that the buffer does not wrap
     
    10181188)
    10191189{
    1020   cd2401->car = minor;          /* Select channel */
     1190  cd2401->car = minor;              /* Select channel */
    10211191
    10221192  if ( (cd2401->dmabsts & 0x08) == 0 ) {
    10231193    /* Next buffer is A. Wait for it to be ours. */
    1024     if ( cd2401->atbsts & 0x01 ) {
    1025       CD2401_Channel_Info[minor].wait_buf_A++;
    1026       while ( cd2401->atbsts & 0x01 );
    1027     }
    1028     CD2401_Channel_Info[minor].used_buf_A++;
     1194    while ( cd2401->atbsts & 0x01 );
     1195
     1196    CD2401_Channel_Info[minor].own_buf_A = FALSE;
    10291197    CD2401_Channel_Info[minor].len = len;
    10301198    CD2401_Channel_Info[minor].buf = buf;
     
    10321200    cd2401->atbadrl = (rtems_unsigned16)( (rtems_unsigned32) buf );
    10331201    cd2401->atbcnt = len;
    1034     cd2401->atbsts = 0x03;      /* CD2401 owns buffer, int when empty */
     1202    CD2401_RECORD_WRITE_INFO(( len, buf, 'A' ));
     1203    cd2401->atbsts = 0x03;          /* CD2401 owns buffer, int when empty */
    10351204  }
    10361205  else {
    10371206    /* Next buffer is B. Wait for it to be ours. */
    1038     if ( cd2401->btbsts & 0x01 ) {
    1039       CD2401_Channel_Info[minor].wait_buf_B++;
    1040       while ( cd2401->btbsts & 0x01 );
    1041     }
    1042     CD2401_Channel_Info[minor].used_buf_B++;
     1207    while ( cd2401->btbsts & 0x01 );
     1208
     1209    CD2401_Channel_Info[minor].own_buf_B = FALSE;
    10431210    CD2401_Channel_Info[minor].len = len;
    10441211    CD2401_Channel_Info[minor].buf = buf;
     
    10461213    cd2401->btbadrl = (rtems_unsigned16)( (rtems_unsigned32) buf );
    10471214    cd2401->btbcnt = len;
    1048     cd2401->btbsts = 0x03;      /* CD2401 owns buffer, int when empty */
    1049   }
    1050   /* Should TxD interrupts be enabled before I set up the DMA transfer? */
    1051   cd2401->ier |= 0x01;          /* enable TxD ints */
     1215    CD2401_RECORD_WRITE_INFO(( len, buf, 'B' ));
     1216    cd2401->btbsts = 0x03;          /* CD2401 owns buffer, int when empty */
     1217  }
     1218  /* Nuts -- Need TxD ints */
     1219  CD2401_Channel_Info[minor].txEmpty = FALSE;
     1220  cd2401->ier |= 0x01;
    10521221
    10531222  /* Return something */
    10541223  return RTEMS_SUCCESSFUL;
    10551224}
     1225
     1226#if 0
     1227/*
     1228 *  cd2401_drainOutput
     1229 *
     1230 *  Wait for the txEmpty indication on the specified channel.
     1231 *
     1232 *  Input parameters:
     1233 *    minor - selected channel
     1234 *
     1235 *  Output parameters:  NONE
     1236 *
     1237 *  Return value: IGNORED
     1238 *
     1239 *  MUST NOT BE EXECUTED WITH THE CD2401 INTERRUPTS DISABLED!
     1240 *  The txEmpty flag is set by the tx ISR.
     1241 */
     1242int cd2401_drainOutput(
     1243  int minor
     1244)
     1245{
     1246  CD2401_RECORD_DRAIN_OUTPUT_INFO(( CD2401_Channel_Info[minor].txEmpty,
     1247                                    CD2401_Channel_Info[minor].own_buf_A,
     1248                                    CD2401_Channel_Info[minor].own_buf_B ));
     1249   
     1250  while( ! (CD2401_Channel_Info[minor].txEmpty &&
     1251            CD2401_Channel_Info[minor].own_buf_A &&
     1252            CD2401_Channel_Info[minor].own_buf_B) );
     1253       
     1254  /* Return something */
     1255  return RTEMS_SUCCESSFUL;
     1256}
     1257#endif
    10561258
    10571259
     
    10801282  int char_not_available;
    10811283  unsigned char c;
    1082  
     1284
    10831285  /* Check for a char in the input FIFO */
    1084   asm volatile( "trap   #15       /* Trap to 167Bug (.INSTAT) */
    1085                  .short 0x01
    1086                  move   %%cc, %0  /* Get condition codes */
    1087                  andil  #4, %0"
    1088     : "=d" (char_not_available) :: "%%cc" );
    1089    
     1286  asm volatile( "movew  #0x1, -(%%sp)   /* Code for .INSTAT */
     1287                 movew  %1, -(%%sp)     /* Channel */
     1288                 trap   #15             /* Trap to 167Bug */
     1289                 .short 0x60            /* Code for .REDIR */
     1290                 move   %%cc, %0        /* Get condition codes */
     1291                 andil  #4, %0"         /* Keep the Zero bit */
     1292    : "=d" (char_not_available) : "d" (minor): "%%cc" );
     1293
    10901294  if (char_not_available)
    10911295    return -1;
    1092    
     1296
    10931297  /* Read the char and return it */
    1094   asm volatile( "subq.l #2,%%a7   /* Space for result */
    1095                  trap   #15       /* Trap to 167 Bug (.INCHR) */
    1096                  .short 0x00
    1097                  moveb  (%%a7)+, %0"
    1098     : "=d" (c) );
    1099    
     1298  asm volatile( "subq.l #2,%%a7         /* Space for result */
     1299                 movew  #0x0, -(%%sp)   /* Code for .INCHR */
     1300                 movew  %1, -(%%sp)     /* Channel */
     1301                 trap   #15             /* Trap to 167 Bug */
     1302                 .short 0x60            /* Code for .REDIR */
     1303                 moveb  (%%a7)+, %0"    /* Pop char into c */
     1304    : "=d" (c) : "d" (minor) );
     1305
    11001306  return (int)c;
    11011307}
     
    11061312 *
    11071313 *  Output buffer through 167Bug. Returns only once every character has been
    1108  *  sent (polled output). 
     1314 *  sent (polled output).
    11091315 *
    11101316 *  Input parameters:
     
    11281334{
    11291335  const char *endbuf = buf + len;
    1130  
    1131   asm volatile( "pea    (%0)
    1132                  pea    (%1)
    1133                  trap   #15     /* trap to 167Bug (.OUTSTR) */
    1134                  .short 0x21"
    1135     :: "a" (endbuf), "a" (buf) );
    1136    
     1336
     1337  asm volatile( "pea    (%0)            /* endbuf */
     1338                 pea    (%1)            /* buf */
     1339                 movew  #0x21, -(%%sp)  /* Code for .OUTSTR */
     1340                 movew  %2, -(%%sp)     /* Channel */
     1341                 trap   #15             /* Trap to 167Bug */
     1342                 .short 0x60"           /* Code for .REDIR */
     1343    :: "a" (endbuf), "a" (buf), "d" (minor) );
     1344
    11371345  /* Return something */
    11381346  return RTEMS_SUCCESSFUL;
     1347}
     1348
     1349
     1350/*
     1351 *  Print functions: prototyped in bsp.h
     1352 *  Debug printing on Channel 1
     1353 */
     1354 
     1355void printk( char *fmt, ... )
     1356{
     1357  va_list  ap;                  /* points to each unnamed argument in turn */
     1358  static char buf[256];
     1359  unsigned int level;
     1360 
     1361  _CPU_ISR_Disable(level);
     1362 
     1363  va_start(ap, fmt);            /* make ap point to 1st unnamed arg */
     1364  vsprintf(buf, fmt, ap);       /* send output to buffer */
     1365 
     1366  BSP_output_string(buf);       /* print buffer -- Channel 1 */
     1367 
     1368  va_end(ap);                           /* clean up and re-enable interrupts */
     1369  _CPU_ISR_Enable(level);
     1370}
     1371
     1372
     1373void BSP_output_string( char * buf )
     1374{
     1375  int len = strlen(buf);                       
     1376  rtems_status_code sc;
     1377 
     1378  /* The first argument forces a print to Port2 (ttyS1) */
     1379  sc = _167Bug_pollWrite(1, buf, len);
     1380  if (sc != RTEMS_SUCCESSFUL)
     1381    rtems_fatal_error_occurred (sc);
    11391382}
    11401383
     
    11451388 ***************
    11461389 *
    1147  *  All these functions are prototyped in rtems/c/src/lib/include/console.h,
    1148  *  except console_reserve_resources(), which is prototyped in
    1149  *  rtems/c/src/lib/libbsp/m68k/mvme167/include/bsp.h
    1150  */
    1151 
    1152 /*
    1153  * Reserve resources consumed by this driver. Allocate enough space in the
    1154  * object table to hold semaphores for 4 minor devices.
    1155  */
    1156 void console_reserve_resources(
    1157   rtems_configuration_table *configuration
    1158 )
    1159 {
    1160   rtems_termios_reserve_resources (configuration, 4);
    1161 }
     1390 *  All these functions are prototyped in rtems/c/src/lib/include/console.h.
     1391 */
    11621392
    11631393/*
     
    12301460    0                           /* outputUsesInterrupts */
    12311461  };
    1232  
     1462
    12331463#else
    12341464
     
    12431473    1                           /* outputUsesInterrupts */
    12441474  };
    1245  
     1475
    12461476#endif
    12471477
Note: See TracChangeset for help on using the changeset viewer.