From ba692232fa53278801b9f17318b8f6692bd3d92c Mon Sep 17 00:00:00 2001 From: Jennifer Averett Date: Tue, 18 Oct 2011 18:23:51 +0000 Subject: 2011-10-18 Jennifer Averett PR 1917/bsps * console.c: Modifications to add dynamic tables for libchip serial drivers. * console_control.c, console_private.h, console_read.c, console_select.c, console_write.c: New files. --- c/src/lib/libbsp/shared/ChangeLog | 8 + c/src/lib/libbsp/shared/console.c | 293 ++++++++++++++++++------------ c/src/lib/libbsp/shared/console_control.c | 46 +++++ c/src/lib/libbsp/shared/console_private.h | 92 ++++++++++ c/src/lib/libbsp/shared/console_read.c | 45 +++++ c/src/lib/libbsp/shared/console_select.c | 102 +++++++++++ c/src/lib/libbsp/shared/console_write.c | 45 +++++ 7 files changed, 513 insertions(+), 118 deletions(-) create mode 100644 c/src/lib/libbsp/shared/console_control.c create mode 100644 c/src/lib/libbsp/shared/console_private.h create mode 100644 c/src/lib/libbsp/shared/console_read.c create mode 100644 c/src/lib/libbsp/shared/console_select.c create mode 100644 c/src/lib/libbsp/shared/console_write.c (limited to 'c') diff --git a/c/src/lib/libbsp/shared/ChangeLog b/c/src/lib/libbsp/shared/ChangeLog index f5da4d8aaf..1570508392 100644 --- a/c/src/lib/libbsp/shared/ChangeLog +++ b/c/src/lib/libbsp/shared/ChangeLog @@ -1,3 +1,11 @@ +2011-10-18 Jennifer Averett + + PR 1917/bsps + * console.c: Modifications to add dynamic tables for libchip serial + drivers. + * console_control.c, console_private.h, console_read.c, + console_select.c, console_write.c: New files. + 2011-08-30 Joel Sherrill * bootcard.c: Revert patch and add comment clarifying code and need for diff --git a/c/src/lib/libbsp/shared/console.c b/c/src/lib/libbsp/shared/console.c index b103dbdf94..05d59cbe93 100644 --- a/c/src/lib/libbsp/shared/console.c +++ b/c/src/lib/libbsp/shared/console.c @@ -1,10 +1,13 @@ -/* - * This file contains the generic console driver shell used - * by all console drivers using libchip. +/** + * @file * - * This driver uses the termios pseudo driver. + * @ingroup Console * - * COPYRIGHT (c) 1989-1997. + * @brief Extension of the generic libchip console driver shell + */ + +/* + * COPYRIGHT (c) 1989-2011. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -16,30 +19,101 @@ #include #include -#include #include #include #include #include #include +#include "console_private.h" + +unsigned long Console_Port_Count = 0; +console_tbl **Console_Port_Tbl = NULL; +console_data *Console_Port_Data = NULL; +rtems_device_minor_number Console_Port_Minor = 0; +bool console_initialized = false; /* - * Configuration Information + * console_initialize_pointers + * + * This method is used to initialize the table of pointers to the + * serial port configuration structure entries. */ +static void console_initialize_pointers(void) +{ + int i; + + if ( Console_Port_Tbl ) + return; + + Console_Port_Count = Console_Configuration_Count; + Console_Port_Tbl = malloc( Console_Port_Count * sizeof( console_tbl * ) ); + if (Console_Port_Tbl == NULL) + rtems_panic("No memory for console pointers"); + + for (i=0 ; i < Console_Port_Count ; i++) + Console_Port_Tbl[i] = &Console_Configuration_Ports[i]; +} -extern console_data Console_Port_Data[]; -extern unsigned long Console_Port_Count; -extern rtems_device_minor_number Console_Port_Minor; - -/*PAGE +/* + * console_register_devices * + * This method is used to add dynamically discovered devices to the + * set of serial ports supported. + */ +void console_register_devices( + console_tbl *new_ports, + size_t number_of_ports +) +{ + int old_number_of_ports; + int i; + + console_initialize_pointers(); + + /* + * console_initialize has been invoked so it is now too late to + * register devices. + */ + if ( console_initialized == true ) { + printk( "Attempt to register console devices after driver initialized\n" ); + rtems_fatal_error_occurred( 0xdead0001 ); + } + + /* + * Allocate memory for the console port extension + */ + old_number_of_ports = Console_Port_Count; + Console_Port_Count += number_of_ports; + Console_Port_Tbl = realloc( + Console_Port_Tbl, + Console_Port_Count * sizeof( console_tbl * ) + ); + if ( Console_Port_Tbl == NULL ) { + printk( "Unable to allocate pointer table for registering console devices\n" ); + rtems_fatal_error_occurred( 0xdead0002 ); + } + + Console_Port_Data = calloc( Console_Port_Count, sizeof( console_data ) ); + if ( Console_Port_Data == NULL ) { + printk( "Unable to allocate data table for console devices\n" ); + rtems_fatal_error_occurred( 0xdead0003 ); + } + + /* + * Now add the new devices at the end. + */ + + for (i=0 ; i < number_of_ports ; i++) { + Console_Port_Tbl[old_number_of_ports + i] = &new_ports[i]; + } +} + +/* * console_open * * open a port as a termios console. - * */ - rtems_device_driver console_open( rtems_device_major_number major, rtems_device_minor_number minor, @@ -65,17 +139,17 @@ rtems_device_driver console_open( * Open the port as a termios console driver. */ - cptr = &Console_Port_Tbl[minor]; + 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; if (cptr->pDeviceFlow != NULL) { - Callbacks.stopRemoteTx = cptr->pDeviceFlow->deviceStopRemoteTx; + Callbacks.stopRemoteTx = cptr->pDeviceFlow->deviceStopRemoteTx; Callbacks.startRemoteTx = cptr->pDeviceFlow->deviceStartRemoteTx; } else { - Callbacks.stopRemoteTx = NULL; + Callbacks.stopRemoteTx = NULL; Callbacks.startRemoteTx = NULL; } Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts; @@ -85,7 +159,7 @@ rtems_device_driver console_open( * Console_Port_Tbl[minor].ulHysteresis); */ - status = rtems_termios_open ( major, minor, arg, &Callbacks ); + status = rtems_termios_open( major, minor, arg, &Callbacks ); Console_Port_Data[minor].termios_data = args->iop->data1; /* Get tty pointur from the Console_Port_Data */ @@ -103,37 +177,35 @@ rtems_device_driver console_open( /* * If it's the first open, modified, if need, the port parameters */ - if (minor!=Console_Port_Minor) { + if ( minor != Console_Port_Minor ) { /* - * If this is not the console we do not want ECHO and - * so forth + * 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); + 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); + cptr->pDeviceFlow && + cptr->pDeviceFlow->deviceStartRemoteTx) { + cptr->pDeviceFlow->deviceStartRemoteTx(minor); } return status; } -/*PAGE - * +/* * console_close * * This routine closes a port that has been opened as console. */ - rtems_device_driver console_close( rtems_device_major_number major, rtems_device_minor_number minor, @@ -142,8 +214,11 @@ rtems_device_driver console_close( { rtems_libio_open_close_args_t *args = arg; struct rtems_termios_tty *current_tty; + console_tbl *cptr; + + cptr = Console_Port_Tbl[minor]; - /* Get tty pointeur from the Console_Port_Data */ + /* Get tty pointer from the Console_Port_Data */ current_tty = Console_Port_Data[minor].termios_data; /* Get the tty refcount to determine if we need to do deviceStopRemoteTx. @@ -151,111 +226,93 @@ rtems_device_driver console_close( */ if ( (current_tty->refcount == 1) ) { 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); + cptr->pDeviceFlow && + cptr->pDeviceFlow->deviceStopRemoteTx) { + cptr->pDeviceFlow->deviceStopRemoteTx(minor); } } return rtems_termios_close (arg); } -/*PAGE - * - * console_read - * - * This routine uses the termios driver to read a character. - */ - -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read (arg); -} - -/*PAGE - * - * console_write - * - * this routine uses the termios driver to write a character. - */ - -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write (arg); -} - -/*PAGE - * - * console_control - * - * this routine uses the termios driver to process io - */ - -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, + rtems_device_minor_number minor_arg, void *arg ) { - rtems_status_code sc = RTEMS_SUCCESSFUL; - bool first = true; + rtems_status_code status; + rtems_device_minor_number minor; + console_tbl *port; + + /* + * If we have no devices which were registered earlier then we + * must still initialize pointers and set Console_Port_Data. + */ + if ( ! Console_Port_Tbl ) { + console_initialize_pointers(); + Console_Port_Data = calloc( Console_Port_Count, sizeof( console_data ) ); + if ( Console_Port_Data == NULL ) { + printk( "Unable to allocate data table for console devices\n" ); + rtems_fatal_error_occurred( 0xdead0003 ); + } + } + + /* + * console_initialize has been invoked so it is now too late to + * register devices. + */ + console_initialized = true; + /* + * Initialize the termio interface, our table of pointers to device + * information structures, and determine if the user has explicitly + * specified which device is to be used for the console. + */ rtems_termios_initialize(); + bsp_console_select(); - for (minor = 0; minor < Console_Port_Count; ++minor) { - const console_tbl *device = &Console_Port_Tbl [minor]; - - if ( - (device->deviceProbe == NULL || device->deviceProbe(minor)) - && device->pDeviceFns->deviceProbe(minor) - ) { - device->pDeviceFns->deviceInitialize(minor); - if (first) { - first = false; - Console_Port_Minor = minor; - sc = rtems_io_register_name(CONSOLE_DEVICE_NAME, major, minor); - if (sc != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(sc); - } + /* + * Iterate over all of the console devices we know about + * and initialize them. + */ + for (minor=0 ; minor < Console_Port_Count ; minor++) { + /* + * First perform the configuration dependent probe, then the + * device dependent probe + */ + port = Console_Port_Tbl[minor]; + + if ( (!port->deviceProbe || port->deviceProbe(minor)) && + port->pDeviceFns->deviceProbe(minor)) { + + status = rtems_io_register_name( port->sDeviceName, major, minor ); + if (status != RTEMS_SUCCESSFUL) { + printk( "Unable to register /dev/console\n" ); + rtems_fatal_error_occurred(status); } - if (device->sDeviceName != NULL) { - sc = rtems_io_register_name(device->sDeviceName, major, minor); - if (sc != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(sc); + + if (minor == Console_Port_Minor) { + if (RTEMS_DEBUG) + printk( "Register %s as the CONSOLE\n", port->sDeviceName ); + status = rtems_io_register_name( "dev/console", major, minor ); + if (status != RTEMS_SUCCESSFUL) { + printk( "Unable to register /dev/console\n" ); + rtems_fatal_error_occurred(status); } } - } - } - if (first) { - /* - * Failed to find a working device - */ - rtems_fatal_error_occurred(RTEMS_IO_ERROR); + /* + * Initialize the hardware device. + */ + port->pDeviceFns->deviceInitialize(minor); + + } } return RTEMS_SUCCESSFUL; diff --git a/c/src/lib/libbsp/shared/console_control.c b/c/src/lib/libbsp/shared/console_control.c new file mode 100644 index 0000000000..77d4b57da9 --- /dev/null +++ b/c/src/lib/libbsp/shared/console_control.c @@ -0,0 +1,46 @@ +/** + * @file + * + * @ingroup Console + * + * @brief Generic libchip console io_ctl extension + */ + + +/* + * This file is an extension of the generic console driver + * shell used by all console drivers using libchip. + * + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "console_private.h" + +/* + * console_control + * + * this routine uses the termios driver to process io + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl (arg); +} diff --git a/c/src/lib/libbsp/shared/console_private.h b/c/src/lib/libbsp/shared/console_private.h new file mode 100644 index 0000000000..f614d7e5e3 --- /dev/null +++ b/c/src/lib/libbsp/shared/console_private.h @@ -0,0 +1,92 @@ +/** + * @file + * + * @ingroup Console + * + * @brief Extension of the generic libchip console driver shell + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _PC386_CONSOLE_PRIVATE_h +#define _PC386_CONSOLE_PRIVATE_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern rtems_device_minor_number Console_Port_Minor; +extern rtems_device_minor_number BSPPrintkPort; + +/** + * @brief bsp_console_select + * + * This function selects the port to be used as console + * + */ +void bsp_console_select(void); + +/** + * @brief bsp_com_outch + * + * This function puts a character out of the console port. + * + * @param[in] ch specifies the character to write + */ +extern void bsp_com_outch(char ch); + +/** + * @brief bsp_com_inch + * + * This function gets a character from the console + * port. + * + * @return This method returns the character that + * was retrieved from the console port. + */ +extern int bsp_com_inch(void); + +/** + * @brief + * + * This function + * + * @return This method returns + */ +int vt_ioctl( unsigned int cmd, unsigned long arg); + +/** + * @brief console_register_devices + * + * This function expands the console table to include previous + * ports and the array of new ports specified. + * + * @param[in] new_ports specifies an array of new ports to register + * @param[in] number_of_ports specifies the number of elements + * in the new_ports array + * + */ +void console_register_devices( + console_tbl *new_ports, + size_t number_of_ports +); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/shared/console_read.c b/c/src/lib/libbsp/shared/console_read.c new file mode 100644 index 0000000000..506ed1bf6c --- /dev/null +++ b/c/src/lib/libbsp/shared/console_read.c @@ -0,0 +1,45 @@ +/** + * @file + * + * @ingroup Console + * + * @brief Generic libchip console read extension + */ + +/* + * This file is an extension of the generic console driver + * shell used by all console drivers using libchip. + * + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "console_private.h" + +/* + * console_read + * + * This routine uses the termios driver to read a character. + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_read (arg); +} diff --git a/c/src/lib/libbsp/shared/console_select.c b/c/src/lib/libbsp/shared/console_select.c new file mode 100644 index 0000000000..caab940c2d --- /dev/null +++ b/c/src/lib/libbsp/shared/console_select.c @@ -0,0 +1,102 @@ +/** + * @file + * + * @ingroup Console + * + * @brief Generic libchip console select + */ + +/* + * This file contains a routine to select the + * console based upon a number of criteria. + * + * COPYRIGHT (c) 2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "console_private.h" + +/* + * Method to return true if the device associated with the + * minor number probs available. + */ +static bool bsp_Is_Available( rtems_device_minor_number minor ) +{ + console_tbl *cptr = Console_Port_Tbl[minor]; + + /* + * First perform the configuration dependent probe, then the + * device dependent probe + */ + if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) && + cptr->pDeviceFns->deviceProbe(minor)) { + return true; + } + return false; +} + +/* + * Method to return the first available device. + */ +static rtems_device_minor_number bsp_First_Available_Device( void ) +{ + rtems_device_minor_number minor; + + for (minor=0; minor < Console_Port_Count ; minor++) { + console_tbl *cptr = Console_Port_Tbl[minor]; + + /* + * First perform the configuration dependent probe, then the + * device dependent probe + */ + + if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) && + cptr->pDeviceFns->deviceProbe(minor)) { + return minor; + } + } + + /* + * Error No devices were found. We will want to bail here. + */ + rtems_fatal_error_occurred(RTEMS_IO_ERROR); +} + +void bsp_console_select(void) +{ + + /* + * Reset Console_Port_Minor and + * BSPPrintkPort here if desired. + * + * This default version allows the bsp to set these + * values at creation and will not touch them again + * unless the selected port number is not available. + */ + + /* + * If the device that was selected isn't available then + * let the user know and select the first available device. + */ + if ( !bsp_Is_Available( Console_Port_Minor ) ) { + printk( + "Error finding %s setting console to first available\n", + Console_Port_Tbl[Console_Port_Minor]->sDeviceName + ); + Console_Port_Minor = bsp_First_Available_Device(); + } +} diff --git a/c/src/lib/libbsp/shared/console_write.c b/c/src/lib/libbsp/shared/console_write.c new file mode 100644 index 0000000000..d51fd0cc70 --- /dev/null +++ b/c/src/lib/libbsp/shared/console_write.c @@ -0,0 +1,45 @@ +/** + * @file + * + * @ingroup Console + * + * @brief Generic libchip console write extension + */ + +/* + * This file is an extension of the generic console driver + * shell used by all console drivers using libchip. + * + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "console_private.h" + +/* + * console_write + * + * this routine uses the termios driver to write a character. + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_write (arg); +} -- cgit v1.2.3