summaryrefslogblamecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/dmv177/console/console.c
blob: 15e64145f0225e178dee8b726ceeef5ca0231e07 (plain) (tree)
1
2
3
4
5
6
7
  
                                                      


                                               
                                             
  











                                                                           






                                                           
        

   

                        
                   
                   
                    
 
                           

  
                           
   
 


                                                     
 



                
                                     
  
   





                                  





                                            

    
                                     
     
                                     
                                
   

    
                                               
     
 













                                                                                
 





















                                                                    
 


                



                                          
                                                      

 
 





                                  







                                                                   


                                   
                                 







                                  








                                   








                                    
       
  
                      
  
                                                           
   
 



                                       

 
                                  

    
                                     

     
                             
 












                                                                  

     







                                               

    
                          
     



























                                                                              
 



                          
 
 
/*
 *  This file contains the TTY driver for the PPCn_60x
 *
 *  This driver uses the termios pseudo driver.
 *
 *  COPYRIGHT (c) 1998 by Radstone Technology
 *
 *
 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
 *
 * You are hereby granted permission to use, copy, modify, and distribute
 * this file, provided that this notice, plus the above copyright notice
 * and disclaimer, appears in all copies. Radstone Technology will provide
 * no support for this code.
 *
 *  COPYRIGHT (c) 1989-1997.
 *  On-Line Applications Research Corporation (OAR).
 *  Copyright assigned to U.S. Government, 1994.
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *
 *  $Id$
 */

#include <bsp.h>
#include <rtems/libio.h>
#include <stdlib.h>
#include <assert.h>
#include <termios.h>

#include <libchip/serial.h>

/*
 * Load configuration table
 */

extern console_data  Console_Port_Data[];
extern unsigned long  Console_Port_Count;
extern rtems_device_minor_number  Console_Port_Minor;
 
/* PAGE
 *
 *  console_open
 *
 *  open a port as a termios console.
 *
 */
rtems_device_driver console_open(
  rtems_device_major_number major,
  rtems_device_minor_number minor,
  void                    * arg
)
{
  rtems_status_code              status;
  rtems_libio_open_close_args_t *args = arg;
  rtems_libio_ioctl_args_t       IoctlArgs;
  struct termios                 Termios;
  rtems_termios_callbacks        Callbacks;
  console_tbl                   *cptr;

  /*
   * Verify the port number is valid.
   */
  if ( minor > Console_Port_Count ) {
    return RTEMS_INVALID_NUMBER;
  }

  /*
   * Open the port as a termios console driver.
   */

  cptr = &Console_Port_Tbl[minor];
  Callbacks.firstOpen            = cptr->pDeviceFns->deviceFirstOpen;
  Callbacks.lastClose            = cptr->pDeviceFns->deviceLastClose;
  Callbacks.pollRead             = cptr->pDeviceFns->deviceRead;
  Callbacks.write                = cptr->pDeviceFns->deviceWrite;
  Callbacks.setAttributes        = cptr->pDeviceFns->deviceSetAttributes;
  Callbacks.stopRemoteTx         = cptr->pDeviceFlow->deviceStopRemoteTx;
  Callbacks.startRemoteTx        = cptr->pDeviceFlow->deviceStartRemoteTx;
  Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts;

  /* XXX what about 
   *        Console_Port_Tbl[minor].ulMargin,
   *        Console_Port_Tbl[minor].ulHysteresis);
   */

  status = rtems_termios_open ( major, minor, arg, &Callbacks );
  Console_Port_Data[minor].termios_data = args->iop->data1;

  if (minor!=Console_Port_Minor) {
    /*
     * If this is not the console we do not want ECHO and
     * so forth
     */
    IoctlArgs.iop=args->iop;
    IoctlArgs.command=RTEMS_IO_GET_ATTRIBUTES;
    IoctlArgs.buffer=&Termios;
    rtems_termios_ioctl(&IoctlArgs);
    Termios.c_lflag=ICANON;
    IoctlArgs.command=RTEMS_IO_SET_ATTRIBUTES;
    rtems_termios_ioctl(&IoctlArgs);
  }

  if ( (args->iop->flags&LIBIO_FLAGS_READ) &&
      Console_Port_Tbl[minor].pDeviceFlow &&
      Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx) {
    Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx(minor);
  }

  return status;
}
 
void console_reserve_resources(
  rtems_configuration_table *configuration
)
{
  rtems_termios_reserve_resources( configuration, 4 );
}


rtems_device_driver console_close(
  rtems_device_major_number major,
  rtems_device_minor_number minor,
  void                    * arg
)
{
  rtems_libio_open_close_args_t *args = arg;

  if ( (args->iop->flags&LIBIO_FLAGS_READ) &&
        Console_Port_Tbl[minor].pDeviceFlow &&
        Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx) {
    Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor);
  }

  return rtems_termios_close (arg);
}
 
rtems_device_driver console_read(
  rtems_device_major_number major,
  rtems_device_minor_number minor,
  void                    * arg
)
{
  return rtems_termios_read (arg);
}
 
rtems_device_driver console_write(
  rtems_device_major_number major,
  rtems_device_minor_number minor,
  void                    * arg
)
{
  return rtems_termios_write (arg);
}
 
rtems_device_driver console_control(
  rtems_device_major_number major,
  rtems_device_minor_number minor,
  void                    * arg
)
{
  return rtems_termios_ioctl (arg);
}

/* PAGE
 *
 *  console_initialize
 *
 *  Routine called to initialize the console device driver.
 */

rtems_device_driver console_initialize(
  rtems_device_major_number  major,
  rtems_device_minor_number  minor,
  void                      *arg
)
{
  rtems_status_code        status;

  /*
   * initialize the termio interface.
   */

  rtems_termios_initialize();

  for (minor=0; minor<Console_Port_Count; minor++) {
    /*
     * First perform the configuration dependent probe, then the
     * device dependent probe
     */

    if ((!Console_Port_Tbl[minor].deviceProbe ||
         Console_Port_Tbl[minor].deviceProbe(minor)) &&
         Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor)) {
      /*
       * Use this device for the console
       */
      break;
    }
  }
  if ( minor==Console_Port_Count ) {
    /*
     * Failed to find a working device
     */
    rtems_fatal_error_occurred(RTEMS_IO_ERROR);
  }
  
  Console_Port_Minor=minor;

  /*
   * Register Device Names
   */
  status = rtems_io_register_name("/dev/console", major, Console_Port_Minor );
  if (status != RTEMS_SUCCESSFUL) {
    rtems_fatal_error_occurred(status);
  }
  Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(Console_Port_Minor);

  for (minor++;minor<Console_Port_Count;minor++) {
    /*
     * First perform the configuration dependent probe, then the
     * device dependent probe
     */

    if ( (!Console_Port_Tbl[minor].deviceProbe ||
         Console_Port_Tbl[minor].deviceProbe(minor)) &&
         Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor)) {
      status = rtems_io_register_name(
        Console_Port_Tbl[minor].sDeviceName,
        major,
        minor );
      if (status != RTEMS_SUCCESSFUL) {
        rtems_fatal_error_occurred(status);
      }

      /*
       * Initialize the hardware device.
       */

      Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(minor);

    }
  }

  return RTEMS_SUCCESSFUL;
}