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

Location:
c/src/lib/libbsp/m68k/mvme167/console
Files:
3 edited

Legend:

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

    r0ab65474 rdf49c60  
    1 ## 
     1##
    22## $Id$
    3 ## 
     3##
    44
    55AUTOMAKE_OPTIONS = foreign 1.4
  • c/src/lib/libbsp/m68k/mvme167/console/console-recording.c

    r0ab65474 rdf49c60  
     1/*
     2 *  Copyright (c) 2000, National Research Council of Canada
     3 *
     4 *  The license and distribution terms for this file may be
     5 *  found in the file LICENSE in this distribution or at
     6 *  http://www.OARcorp.com/rtems/license.html.
     7 */
     8 
     9/* CD2401 CONSOLE DRIVER DEBUG INFO RECORDING */
     10
     11#ifdef CD2401_RECORD_DEBUG_INFO
     12
     13/* Control individual recording here. That way, we don't clutter console.c */
     14#define CD2401_RECORD_WRITE
     15#define CD2401_RECORD_TX_ISR
     16#define CD2401_RECORD_RX_ISR
     17#define CD2401_RECORD_RE_ISR
     18#define CD2401_RECORD_MODEM_ISR
     19#define CD2401_RECORD_SET_ATTRIBUTE
     20#define CD2401_RECORD_FIRST_OPEN
     21#define CD2401_RECORD_LAST_CLOSE
     22#define CD2401_RECORD_START_REMOTE_TX
     23#define CD2401_RECORD_STOP_REMOTE_TX
     24#define CD2401_RECORD_DRAIN_OUTPUT
     25#define CD2401_RECORD_DELAY
     26
     27
     28/* Call the data recording functions */
     29#ifdef CD2401_RECORD_WRITE
     30#define CD2401_RECORD_WRITE_INFO( args )              cd2401_record_write_info args
     31#else
     32#define CD2401_RECORD_WRITE_INFO( args )
     33#endif
     34
     35#ifdef CD2401_RECORD_TX_ISR
     36#define CD2401_RECORD_TX_ISR_INFO( args )             cd2401_record_tx_isr_info args
     37#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args )    cd2401_record_tx_isr_spurious_info args
     38#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args )      cd2401_record_tx_isr_buserr_info args
     39#else
     40#define CD2401_RECORD_TX_ISR_INFO( args )
     41#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args )
     42#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args )
     43#endif
     44
     45#ifdef CD2401_RECORD_RX_ISR
     46#define CD2401_RECORD_RX_ISR_INFO( args )             cd2401_record_rx_isr_info args
     47#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args )    cd2401_record_rx_isr_spurious_info args
     48#else
     49#define CD2401_RECORD_RX_ISR_INFO( args )
     50#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args )
     51#endif
     52
     53#ifdef CD2401_RECORD_RE_ISR
     54#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args )    cd2401_record_re_isr_spurious_info args
     55#else
     56#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args )
     57#endif
     58
     59#ifdef CD2401_RECORD_MODEM_ISR
     60#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) cd2401_record_modem_isr_spurious_info args
     61#else
     62#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args )
     63#endif
     64
     65#ifdef CD2401_RECORD_SET_ATTRIBUTES
     66#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args )     cd2401_record_set_attributes_info args
     67#else
     68#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args )
     69#endif
     70
     71#ifdef CD2401_RECORD_FIRST_OPEN
     72#define CD2401_RECORD_FIRST_OPEN_INFO( args )         cd2401_record_first_open_info args
     73#else
     74#define CD2401_RECORD_FIRST_OPEN_INFO( args )
     75#endif
     76
     77#ifdef CD2401_RECORD_LAST_CLOSE
     78#define CD2401_RECORD_LAST_CLOSE_INFO( args )         cd2401_record_last_close_info args
     79#else
     80#define CD2401_RECORD_LAST_CLOSE_INFO( args )
     81#endif
     82
     83#ifdef CD2401_RECORD_START_REMOTE_TX
     84#define CD2401_RECORD_START_REMOTE_TX_INFO( args )    cd2401_record_start_remote_tx_info args
     85#else
     86#define CD2401_RECORD_START_REMOTE_TX_INFO( args )
     87#endif
     88
     89#ifdef CD2401_RECORD_STOP_REMOTE_TX
     90#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args )     cd2401_record_stop_remote_tx_info args
     91#else
     92#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args )
     93#endif
     94
     95#ifdef CD2401_RECORD_DRAIN_OUTPUT
     96#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args )       cd2401_record_drain_output_info args
     97#else
     98#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args )
     99#endif
     100
     101#ifdef CD2401_RECORD_DELAY
     102#define CD2401_RECORD_DELAY_INFO( args )              cd2401_record_delay_info args
     103#else
     104#define CD2401_RECORD_DELAY_INFO( args )
     105#endif
     106
     107
     108/* Define the data and the recording functions */
     109#define CD2401_DEBUG_BUFFER_SIZE     256
     110#define CD2401_DEBUG_CHAR_BUFSIZE     64
     111#define CD2401_WRITE_INFO              1
     112#define CD2401_TX_ISR_INFO             2
     113#define CD2401_TX_ISR_SPURIOUS_INFO    3
     114#define CD2401_TX_ISR_BUSERR_INFO      4
     115#define CD2401_RX_ISR_INFO             5
     116#define CD2401_RX_ISR_SPURIOUS_INFO    6
     117#define CD2401_RE_ISR_SPURIOUS_INFO    7
     118#define CD2401_MODEM_ISR_SPURIOUS_INFO 8
     119#define CD2401_FIRST_OPEN_INFO         9
     120#define CD2401_LAST_CLOSE_INFO        10
     121#define CD2401_START_REMOTE_TX_INFO   11
     122#define CD2401_STOP_REMOTE_TX_INFO    12
     123#define CD2401_SET_ATTRIBUTE_INFO     13
     124#define CD2401_DRAIN_OUTPUT_INFO      14
     125#define CD2401_DELAY_INFO             15
     126
     127
     128struct cd2401_debug_info {
     129  short discriminant;
     130  short record_size;
     131  union {
     132    struct cd2401_write_info {
     133      int length;
     134      char buffer[CD2401_DEBUG_CHAR_BUFSIZE];
     135      char dmabuf;
     136    } write_info;
     137    struct cd2401_tx_isr_info {
     138      unsigned char channel;
     139      unsigned char status;
     140      unsigned char initial_ier;
     141      unsigned char final_ier;
     142      rtems_unsigned8 txEmpty;
     143    } tx_isr_info;
     144    struct cd2401_tx_isr_spurious_info {
     145      unsigned char channel;
     146      unsigned char status;
     147      unsigned char initial_ier;
     148      unsigned char final_ier;
     149      unsigned long spurdev;
     150      unsigned long spurcount;
     151    } tx_isr_spurious_info;
     152    struct cd2401_tx_isr_buserr_info {
     153      unsigned char channel;
     154      unsigned char status;
     155      unsigned char initial_ier;
     156      unsigned char buserr;
     157      unsigned long type;
     158      unsigned long addr;
     159    } tx_isr_buserr_info;
     160    struct cd2401_rx_isr_info {
     161      unsigned char channel;
     162      int length;
     163      char buffer[CD2401_DEBUG_CHAR_BUFSIZE];
     164    } rx_isr_info;
     165    struct cd2401_rx_isr_spurious_info {
     166      unsigned char channel;
     167      unsigned char status;
     168      unsigned long spurdev;
     169      unsigned long spurcount;
     170    } rx_isr_spurious_info;
     171    struct cd2401_re_isr_spurious_info {
     172      unsigned char channel;
     173      unsigned long spurdev;
     174      unsigned long spurcount;
     175    } re_isr_spurious_info;
     176    struct cd2401_modem_isr_spurious_info {
     177      unsigned char channel;
     178      unsigned long spurdev;
     179      unsigned long spurcount;
     180    } modem_isr_spurious_info;
     181    struct cd2401_first_open_info {
     182      unsigned char channel;
     183      rtems_unsigned8 init_count;
     184    } first_open_info;
     185    struct cd2401_last_close_info {
     186      unsigned char channel;
     187      rtems_unsigned8 init_count;
     188    } last_close_info;
     189    struct cd2401_start_remote_tx_info {
     190      unsigned char channel;
     191    } start_remote_tx_info;
     192    struct cd2401_stop_remote_tx_info {
     193      unsigned char channel;
     194    } stop_remote_tx_info;
     195    struct cd2401_set_attribute_info {
     196      int minor;
     197      rtems_unsigned8 need_reinit;
     198      rtems_unsigned8 txEmpty;
     199      rtems_unsigned8 csize;
     200      rtems_unsigned8 cstopb;
     201      rtems_unsigned8 parodd;
     202      rtems_unsigned8 parenb;
     203      rtems_unsigned8 ignpar;
     204      rtems_unsigned8 inpck;
     205      rtems_unsigned8 hw_flow_ctl;
     206      rtems_unsigned8 sw_flow_ctl;
     207      rtems_unsigned8 extra_flow_ctl;
     208      rtems_unsigned8 icrnl;
     209      rtems_unsigned8 igncr;
     210      rtems_unsigned8 inlcr;
     211      rtems_unsigned8 brkint;
     212      rtems_unsigned8 ignbrk;
     213      rtems_unsigned8 parmrk;
     214      rtems_unsigned8 istrip;
     215      rtems_unsigned16 tx_period;
     216      rtems_unsigned16 rx_period;
     217      rtems_unsigned32 out_baud;
     218      rtems_unsigned32 in_baud;
     219    } set_attribute_info;
     220    struct cd2401_drain_output_info {
     221      rtems_unsigned8 txEmpty;
     222      rtems_unsigned8 own_buf_A;
     223      rtems_unsigned8 own_buf_B;
     224    } drain_output_info;
     225    struct cd2401_delay_info {
     226      rtems_interval start;
     227      rtems_interval end;
     228      rtems_interval current;
     229      unsigned long loop_count;
     230    } delay_info;
     231  } u;
     232};
     233
     234struct cd2401_debug_info cd2401_debug_buffer[CD2401_DEBUG_BUFFER_SIZE];
     235int cd2401_debug_index = 0;
     236
     237#include <string.h>
     238
     239int cd2401_get_record_size(
     240  int size
     241)
     242{
     243  /* Not the best way to do this */
     244  return size + 4;
     245}
     246 
     247 
     248void cd2401_record_write_info(
     249  int len,
     250  const char * buf,
     251  char dmabuf
     252)
     253{
     254  int max_length;
     255 
     256  max_length = (len < CD2401_DEBUG_CHAR_BUFSIZE ) ? len : CD2401_DEBUG_CHAR_BUFSIZE;
     257 
     258  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     259  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_WRITE_INFO;
     260  cd2401_debug_buffer[cd2401_debug_index].record_size =
     261      cd2401_get_record_size( sizeof( struct cd2401_write_info ) );
     262  cd2401_debug_buffer[cd2401_debug_index].u.write_info.length = len;
     263  memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.write_info.buffer), buf, max_length );
     264  cd2401_debug_buffer[cd2401_debug_index].u.write_info.dmabuf = dmabuf;
     265   
     266  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     267}
     268
     269
     270void cd2401_record_tx_isr_info(
     271  unsigned char ch,
     272  unsigned char status,
     273  unsigned char initial_ier,
     274  unsigned char final_ier,
     275  rtems_unsigned8 txEmpty
     276)
     277{
     278  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     279  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_INFO;
     280  cd2401_debug_buffer[cd2401_debug_index].record_size =
     281      cd2401_get_record_size( sizeof( struct cd2401_tx_isr_info ) );
     282  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.channel = ch;
     283  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.status = status;
     284  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.initial_ier = initial_ier;
     285  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.final_ier = final_ier;
     286  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.txEmpty = txEmpty;
     287 
     288  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     289}
     290
     291
     292void cd2401_record_tx_isr_spurious_info(
     293  unsigned char ch,
     294  unsigned char status,
     295  unsigned char initial_ier,
     296  unsigned char final_ier,
     297  unsigned char spur_dev,
     298  unsigned char spur_cnt
     299)
     300{
     301  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     302  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_SPURIOUS_INFO;
     303  cd2401_debug_buffer[cd2401_debug_index].record_size =
     304      cd2401_get_record_size( sizeof( struct cd2401_tx_isr_spurious_info ) );
     305  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.channel = ch;
     306  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.status = status;
     307  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.initial_ier = initial_ier;
     308  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.final_ier = final_ier;
     309  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurdev = spur_dev;
     310  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurcount = spur_cnt;
     311 
     312  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     313}
     314
     315
     316void cd2401_record_tx_isr_buserr_info(
     317  unsigned char ch,
     318  unsigned char status,
     319  unsigned char initial_ier,
     320  unsigned char buserr,
     321  unsigned long buserr_type,
     322  unsigned long buserr_addr
     323)
     324{
     325  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     326  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_BUSERR_INFO;
     327  cd2401_debug_buffer[cd2401_debug_index].record_size =
     328    cd2401_get_record_size( sizeof( struct cd2401_tx_isr_buserr_info ) );
     329  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.channel = ch;
     330  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.status = status;
     331  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.initial_ier = initial_ier;
     332  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.buserr = buserr;
     333  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.type = buserr_type;
     334  cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.addr = buserr_addr;
     335 
     336  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     337}
     338
     339
     340void cd2401_record_rx_isr_info(
     341  unsigned char ch,
     342  unsigned char total,
     343  char * buffer
     344)
     345{
     346  int max_length;
     347 
     348  max_length = (total < CD2401_DEBUG_CHAR_BUFSIZE ) ? total : CD2401_DEBUG_CHAR_BUFSIZE;
     349 
     350  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     351  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_INFO;
     352  cd2401_debug_buffer[cd2401_debug_index].record_size =
     353      cd2401_get_record_size( sizeof( struct cd2401_rx_isr_info ) );
     354  cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.length = max_length;
     355 memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.buffer), buffer, max_length );
     356   
     357  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     358}
     359
     360
     361void cd2401_record_rx_isr_spurious_info(
     362  unsigned char ch,
     363  unsigned char status,
     364  rtems_unsigned32 spur_dev,
     365  rtems_unsigned32 spur_cnt
     366)
     367{
     368  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     369  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_SPURIOUS_INFO;
     370  cd2401_debug_buffer[cd2401_debug_index].record_size =
     371      cd2401_get_record_size( sizeof( struct cd2401_rx_isr_spurious_info ) );
     372  cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.channel = ch;
     373  cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.status = status;
     374  cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurdev = spur_dev;
     375  cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurcount = spur_cnt;
     376   
     377  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     378}
     379
     380
     381void cd2401_record_re_isr_spurious_info(
     382  unsigned char ch,
     383  rtems_unsigned32 spur_dev,
     384  rtems_unsigned32 spur_cnt
     385)
     386{
     387  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     388  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RE_ISR_SPURIOUS_INFO;
     389  cd2401_debug_buffer[cd2401_debug_index].record_size =
     390      cd2401_get_record_size( sizeof( struct cd2401_re_isr_spurious_info ) );
     391  cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.channel = ch;
     392  cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurdev = spur_dev;
     393  cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurcount = spur_cnt;
     394   
     395  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     396}
     397
     398
     399void cd2401_record_modem_isr_spurious_info(
     400  unsigned char ch,
     401  rtems_unsigned32 spur_dev,
     402  rtems_unsigned32 spur_cnt
     403)
     404{
     405  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     406  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_MODEM_ISR_SPURIOUS_INFO;
     407  cd2401_debug_buffer[cd2401_debug_index].record_size =
     408      cd2401_get_record_size( sizeof( struct cd2401_modem_isr_spurious_info ) );
     409  cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.channel = ch;
     410  cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurdev = spur_dev;
     411  cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurcount = spur_cnt;
     412   
     413  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     414}
     415
     416
     417void cd2401_record_first_open_info(
     418  unsigned char ch,
     419  rtems_unsigned8 init_count
     420)
     421{
     422  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     423  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_FIRST_OPEN_INFO;
     424  cd2401_debug_buffer[cd2401_debug_index].record_size =
     425      cd2401_get_record_size( sizeof( struct cd2401_first_open_info ) );
     426  cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.channel = ch;
     427  cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.init_count = init_count;
     428   
     429  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     430}
     431
     432
     433void cd2401_record_last_close_info(
     434  unsigned char ch,
     435  rtems_unsigned8 init_count
     436)
     437{
     438  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     439  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_LAST_CLOSE_INFO;
     440  cd2401_debug_buffer[cd2401_debug_index].record_size =
     441      cd2401_get_record_size( sizeof( struct cd2401_last_close_info ) );
     442  cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.channel = ch;
     443  cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.init_count = init_count;
     444   
     445  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     446}
     447
     448
     449void cd2401_record_start_remote_tx_info(
     450  unsigned char ch
     451)
     452{
     453  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     454  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_START_REMOTE_TX_INFO;
     455  cd2401_debug_buffer[cd2401_debug_index].record_size =
     456      cd2401_get_record_size( sizeof( struct cd2401_start_remote_tx_info ) );
     457  cd2401_debug_buffer[cd2401_debug_index].u.start_remote_tx_info.channel = ch;
     458   
     459  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     460}
     461
     462
     463void cd2401_record_stop_remote_tx_info(
     464  unsigned char ch
     465)
     466{
     467  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     468  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_STOP_REMOTE_TX_INFO;
     469  cd2401_debug_buffer[cd2401_debug_index].record_size =
     470      cd2401_get_record_size( sizeof( struct cd2401_stop_remote_tx_info ) );
     471  cd2401_debug_buffer[cd2401_debug_index].u.stop_remote_tx_info.channel = ch;
     472   
     473  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     474}
     475
     476
     477void cd2401_record_set_attributes_info(
     478  int minor,
     479  rtems_unsigned8 need_reinit,
     480  rtems_unsigned8 csize,
     481  rtems_unsigned8 cstopb,
     482  rtems_unsigned8 parodd,
     483  rtems_unsigned8 parenb,
     484  rtems_unsigned8 ignpar,
     485  rtems_unsigned8 inpck,
     486  rtems_unsigned8 hw_flow_ctl,
     487  rtems_unsigned8 sw_flow_ctl,
     488  rtems_unsigned8 extra_flow_ctl,
     489  rtems_unsigned8 icrnl,
     490  rtems_unsigned8 igncr,
     491  rtems_unsigned8 inlcr,
     492  rtems_unsigned8 brkint,
     493  rtems_unsigned8 ignbrk,
     494  rtems_unsigned8 parmrk,
     495  rtems_unsigned8 istrip,
     496  rtems_unsigned16 tx_period,
     497  rtems_unsigned16 rx_period,
     498  rtems_unsigned32 out_baud,
     499  rtems_unsigned32 in_baud
     500)
     501{
     502  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     503  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_SET_ATTRIBUTE_INFO;
     504  cd2401_debug_buffer[cd2401_debug_index].record_size =
     505  cd2401_get_record_size( sizeof( struct cd2401_set_attribute_info ) );
     506  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.minor = minor;
     507  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.need_reinit = need_reinit;
     508  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.txEmpty = CD2401_Channel_Info[minor].txEmpty;
     509  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.csize = csize;
     510  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.cstopb = cstopb;
     511  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parodd = parodd;
     512  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parenb = parenb;
     513  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignpar = ignpar;
     514  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inpck = inpck;
     515  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.hw_flow_ctl = hw_flow_ctl;
     516  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.sw_flow_ctl = sw_flow_ctl;
     517  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.extra_flow_ctl = extra_flow_ctl;
     518  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.icrnl = icrnl;
     519  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.igncr = igncr;
     520  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inlcr = inlcr;
     521  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.brkint = brkint;
     522  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignbrk = ignbrk;
     523  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parmrk = parmrk;
     524  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.istrip = istrip;
     525  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.tx_period = tx_period;
     526  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.rx_period = rx_period;
     527  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.out_baud = out_baud;
     528  cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.in_baud = in_baud;
     529 
     530  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     531}
     532
     533
     534void cd2401_record_drain_output_info(
     535  rtems_unsigned8 txEmpty,
     536  rtems_unsigned8 own_buf_A,
     537  rtems_unsigned8 own_buf_B
     538)
     539{
     540  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     541  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DRAIN_OUTPUT_INFO;
     542  cd2401_debug_buffer[cd2401_debug_index].record_size =
     543      cd2401_get_record_size( sizeof( struct cd2401_drain_output_info ) );
     544  cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.txEmpty = txEmpty;
     545  cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_A = own_buf_A;
     546  cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_B = own_buf_B;
     547 
     548  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     549}
     550
     551
     552void cd2401_record_delay_info(
     553  rtems_interval start,
     554  rtems_interval end,
     555  rtems_interval current,
     556  unsigned long loop_count
     557)
     558{
     559  memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info )  );
     560  cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DELAY_INFO;
     561  cd2401_debug_buffer[cd2401_debug_index].record_size =
     562      cd2401_get_record_size( sizeof( struct cd2401_delay_info ) );
     563  cd2401_debug_buffer[cd2401_debug_index].u.delay_info.start = start;
     564  cd2401_debug_buffer[cd2401_debug_index].u.delay_info.end = end;
     565  cd2401_debug_buffer[cd2401_debug_index].u.delay_info.current = current;
     566  cd2401_debug_buffer[cd2401_debug_index].u.delay_info.loop_count = loop_count;
     567 
     568  cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
     569}
     570
     571
     572#else
     573
     574/* Do not call the data recording functions */
     575#define CD2401_RECORD_WRITE_INFO( args )
     576#define CD2401_RECORD_TX_ISR_INFO( args )
     577#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args )
     578#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args )
     579#define CD2401_RECORD_RX_ISR_INFO( args )
     580#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args )
     581#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args )
     582#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args )
     583#define CD2401_RECORD_FIRST_OPEN_INFO( args )
     584#define CD2401_RECORD_LAST_CLOSE_INFO( args )
     585#define CD2401_RECORD_START_REMOTE_TX_INFO( args )
     586#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args )
     587#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args )
     588#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args )
     589#define CD2401_RECORD_DELAY_INFO( args )
     590
     591#endif
  • 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.