/* This file contains the TTY driver for the serial ports. The driver * is layered so that different UART hardware can be used. It is implemented * using the Driver Manager. * * This driver uses the termios pseudo driver. * * COPYRIGHT (c) 2010. * Cobham Gaisler AB. * * 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. */ #include #include #include #include #include #ifdef RTEMS_DRVMGR_STARTUP /* Note that it is not possible to use the interrupt mode of the driver * together with the "old" APBUART and -u to GRMON. However the new * APBUART core (from 1.0.17-b2710) has the GRMON debug bit and can * handle interrupts. */ int console_initialized = 0; rtems_device_major_number console_major = 0; #define FLAG_SYSCON 0x01 struct console_priv { unsigned char flags; /* 0x1=SystemConsole */ unsigned char minor; struct console_dev *dev; }; #define CONSOLE_MAX BSP_NUMBER_OF_TERMIOS_PORTS struct console_priv cons[CONSOLE_MAX] = {{0,0},}; /* Register Console to TERMIOS layer and initialize it */ static void console_dev_init(struct console_priv *con, int minor) { char name[16], *fsname; rtems_status_code status; if (!con->dev->fsname) { strcpy(name, "/dev/console_a"); /* Special console name and MINOR for SYSTEM CONSOLE */ if (minor == 0) name[12] = '\0'; /* /dev/console */ name[13] += minor; /* when minor=0, this has no effect... */ fsname = name; } else { fsname = con->dev->fsname; } status = rtems_io_register_name(fsname, console_major, minor); if ((minor == 0) && (status != RTEMS_SUCCESSFUL)) rtems_fatal_error_occurred(status); } void console_dev_register(struct console_dev *dev) { int i, minor = 0; struct console_priv *con = NULL; if ((dev->flags & CONSOLE_FLAG_SYSCON) && !cons[0].dev) { con = &cons[0]; con->flags = FLAG_SYSCON; } else { for (i=1; iflags = 0; minor = i; break; } } } if (con == NULL) { /* Not enough console structures */ return; } /* Assign Console */ con->dev = dev; con->minor = minor; /* Console layer is already initialized, that means that we can * register termios interface directly. */ if (console_initialized) console_dev_init(con, minor); } #if 0 void console_dev_unregister(struct console_dev *dev) { } #endif rtems_device_driver console_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg) { int i; console_major = major; rtems_termios_initialize(); /* Register all Console a file system device node */ for (i=0; i= CONSOLE_MAX) || !cons[minor].dev) return RTEMS_INVALID_NUMBER; status = rtems_termios_open( major, (int)cons[minor].dev, arg, cons[minor].dev->callbacks); /* Inherit UART hardware parameters from bootloader on system console */ if ((status == RTEMS_SUCCESSFUL) && (cons[minor].flags & FLAG_SYSCON) && (cons[minor].dev->ops.get_uart_attrs != NULL)) { if (tcgetattr(STDIN_FILENO, &term) >= 0) { cons[minor].dev->ops.get_uart_attrs(cons[minor].dev, &term); term.c_oflag |= ONLCR; tcsetattr(STDIN_FILENO, TCSANOW, &term); } } return status; } rtems_device_driver console_close( rtems_device_major_number major, rtems_device_minor_number minor, void *arg) { 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); } #endif