uboot/common/stdio.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <config.h>
  25#include <common.h>
  26#include <stdarg.h>
  27#include <malloc.h>
  28#include <stdio_dev.h>
  29#include <serial.h>
  30#ifdef CONFIG_LOGBUFFER
  31#include <logbuff.h>
  32#endif
  33#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
  34#include <i2c.h>
  35#endif
  36
  37DECLARE_GLOBAL_DATA_PTR;
  38
  39static struct stdio_dev devs;
  40struct stdio_dev *stdio_devices[] = { NULL, NULL, NULL };
  41char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
  42
  43#if defined(CONFIG_SPLASH_SCREEN) && !defined(CONFIG_SYS_DEVICE_NULLDEV)
  44#define CONFIG_SYS_DEVICE_NULLDEV       1
  45#endif
  46
  47
  48#ifdef CONFIG_SYS_DEVICE_NULLDEV
  49void nulldev_putc(const char c)
  50{
  51        /* nulldev is empty! */
  52}
  53
  54void nulldev_puts(const char *s)
  55{
  56        /* nulldev is empty! */
  57}
  58
  59int nulldev_input(void)
  60{
  61        /* nulldev is empty! */
  62        return 0;
  63}
  64#endif
  65
  66/**************************************************************************
  67 * SYSTEM DRIVERS
  68 **************************************************************************
  69 */
  70
  71static void drv_system_init (void)
  72{
  73        struct stdio_dev dev;
  74
  75        memset (&dev, 0, sizeof (dev));
  76
  77        strcpy (dev.name, "serial");
  78        dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
  79#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
  80        dev.putc = serial_buffered_putc;
  81        dev.puts = serial_buffered_puts;
  82        dev.getc = serial_buffered_getc;
  83        dev.tstc = serial_buffered_tstc;
  84#else
  85        dev.putc = serial_putc;
  86        dev.puts = serial_puts;
  87        dev.getc = serial_getc;
  88        dev.tstc = serial_tstc;
  89#endif
  90
  91        stdio_register (&dev);
  92
  93#ifdef CONFIG_SYS_DEVICE_NULLDEV
  94        memset (&dev, 0, sizeof (dev));
  95
  96        strcpy (dev.name, "nulldev");
  97        dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
  98        dev.putc = nulldev_putc;
  99        dev.puts = nulldev_puts;
 100        dev.getc = nulldev_input;
 101        dev.tstc = nulldev_input;
 102
 103        stdio_register (&dev);
 104#endif
 105}
 106
 107/**************************************************************************
 108 * DEVICES
 109 **************************************************************************
 110 */
 111struct list_head* stdio_get_list(void)
 112{
 113        return &(devs.list);
 114}
 115
 116struct stdio_dev* stdio_get_by_name(char* name)
 117{
 118        struct list_head *pos;
 119        struct stdio_dev *dev;
 120
 121        if(!name)
 122                return NULL;
 123
 124        list_for_each(pos, &(devs.list)) {
 125                dev = list_entry(pos, struct stdio_dev, list);
 126                if(strcmp(dev->name, name) == 0)
 127                        return dev;
 128        }
 129
 130        return NULL;
 131}
 132
 133struct stdio_dev* stdio_clone(struct stdio_dev *dev)
 134{
 135        struct stdio_dev *_dev;
 136
 137        if(!dev)
 138                return NULL;
 139
 140        _dev = calloc(1, sizeof(struct stdio_dev));
 141
 142        if(!_dev)
 143                return NULL;
 144
 145        memcpy(_dev, dev, sizeof(struct stdio_dev));
 146        strncpy(_dev->name, dev->name, 16);
 147
 148        return _dev;
 149}
 150
 151int stdio_register (struct stdio_dev * dev)
 152{
 153        struct stdio_dev *_dev;
 154
 155        _dev = stdio_clone(dev);
 156        if(!_dev)
 157                return -1;
 158        list_add_tail(&(_dev->list), &(devs.list));
 159        return 0;
 160}
 161
 162/* deregister the device "devname".
 163 * returns 0 if success, -1 if device is assigned and 1 if devname not found
 164 */
 165#ifdef  CONFIG_SYS_STDIO_DEREGISTER
 166int stdio_deregister(char *devname)
 167{
 168        int l;
 169        struct list_head *pos;
 170        struct stdio_dev *dev;
 171        char temp_names[3][8];
 172
 173        dev = stdio_get_by_name(devname);
 174
 175        if(!dev) /* device not found */
 176                return -1;
 177        /* get stdio devices (ListRemoveItem changes the dev list) */
 178        for (l=0 ; l< MAX_FILES; l++) {
 179                if (stdio_devices[l] == dev) {
 180                        /* Device is assigned -> report error */
 181                        return -1;
 182                }
 183                memcpy (&temp_names[l][0],
 184                        stdio_devices[l]->name,
 185                        sizeof(stdio_devices[l]->name));
 186        }
 187
 188        list_del(&(dev->list));
 189
 190        /* reassign Device list */
 191        list_for_each(pos, &(devs.list)) {
 192                dev = list_entry(pos, struct stdio_dev, list);
 193                for (l=0 ; l< MAX_FILES; l++) {
 194                        if(strcmp(dev->name, temp_names[l]) == 0)
 195                                stdio_devices[l] = dev;
 196                }
 197        }
 198        return 0;
 199}
 200#endif  /* CONFIG_SYS_STDIO_DEREGISTER */
 201
 202int stdio_init (void)
 203{
 204#if !defined(CONFIG_RELOC_FIXUP_WORKS)
 205        /* already relocated for current ARM implementation */
 206        ulong relocation_offset = gd->reloc_off;
 207        int i;
 208
 209        /* relocate device name pointers */
 210        for (i = 0; i < (sizeof (stdio_names) / sizeof (char *)); ++i) {
 211                stdio_names[i] = (char *) (((ulong) stdio_names[i]) +
 212                                                relocation_offset);
 213        }
 214#endif /* !CONFIG_RELOC_FIXUP_WORKS */
 215
 216        /* Initialize the list */
 217        INIT_LIST_HEAD(&(devs.list));
 218
 219#ifdef CONFIG_ARM_DCC_MULTI
 220        drv_arm_dcc_init ();
 221#endif
 222#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
 223        i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 224#endif
 225#ifdef CONFIG_LCD
 226        drv_lcd_init ();
 227#endif
 228#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
 229        drv_video_init ();
 230#endif
 231#ifdef CONFIG_KEYBOARD
 232        drv_keyboard_init ();
 233#endif
 234#ifdef CONFIG_LOGBUFFER
 235        drv_logbuff_init ();
 236#endif
 237        drv_system_init ();
 238#ifdef CONFIG_SERIAL_MULTI
 239        serial_stdio_init ();
 240#endif
 241#ifdef CONFIG_USB_TTY
 242        drv_usbtty_init ();
 243#endif
 244#ifdef CONFIG_NETCONSOLE
 245        drv_nc_init ();
 246#endif
 247#ifdef CONFIG_JTAG_CONSOLE
 248        drv_jtag_console_init ();
 249#endif
 250
 251        return (0);
 252}
 253