Browse Source

[tty] change driver of tty to device and code cleanup. (#7444)

Bernard Xiong 2 years ago
parent
commit
8ad70ca231

+ 27 - 55
components/drivers/tty/console.c

@@ -20,7 +20,7 @@
 #endif /* RT_TTY_DEBUG */
 #include <rtdbg.h>
 
-static struct tty_struct console_driver;
+static struct tty_struct console_dev;
 
 static void console_rx_notify(struct rt_device *dev)
 {
@@ -35,7 +35,7 @@ static void console_rx_notify(struct rt_device *dev)
 
     while (1)
     {
-        len = rt_device_read(console->driver, -1, &ch, 1);
+        len = rt_device_read(console->io_dev, -1, &ch, 1);
         if (len == 0)
         {
             break;
@@ -56,7 +56,7 @@ static void console_rx_notify(struct rt_device *dev)
 
 struct tty_struct *console_tty_get(void)
 {
-    return &console_driver;
+    return &console_dev;
 }
 
 static void iodev_close(struct tty_struct *console)
@@ -67,8 +67,8 @@ static void iodev_close(struct tty_struct *console)
     rx_notify.dev = RT_NULL;
 
     /* clear notify */
-    rt_device_control(console->driver, RT_DEVICE_CTRL_NOTIFY_SET, &rx_notify);
-    rt_device_close(console->driver);
+    rt_device_control(console->io_dev, RT_DEVICE_CTRL_NOTIFY_SET, &rx_notify);
+    rt_device_close(console->io_dev);
 }
 
 static rt_err_t iodev_open(struct tty_struct *console)
@@ -77,9 +77,9 @@ static rt_err_t iodev_open(struct tty_struct *console)
     struct rt_device_notify rx_notify;
     rt_uint16_t oflags = 0;
 
-    rt_device_control(console->driver, RT_DEVICE_CTRL_CONSOLE_OFLAG, &oflags);
+    rt_device_control(console->io_dev, RT_DEVICE_CTRL_CONSOLE_OFLAG, &oflags);
 
-    ret = rt_device_open(console->driver, oflags);
+    ret = rt_device_open(console->io_dev, oflags);
     if (ret != RT_EOK)
     {
         return -RT_ERROR;
@@ -87,7 +87,7 @@ static rt_err_t iodev_open(struct tty_struct *console)
 
     rx_notify.notify = console_rx_notify;
     rx_notify.dev = (struct rt_device *)console;
-    rt_device_control(console->driver, RT_DEVICE_CTRL_NOTIFY_SET, &rx_notify);
+    rt_device_control(console->io_dev, RT_DEVICE_CTRL_NOTIFY_SET, &rx_notify);
     return RT_EOK;
 }
 
@@ -97,8 +97,9 @@ struct rt_device *console_get_iodev(void)
     struct rt_device *iodev = RT_NULL;
 
     level = rt_hw_interrupt_disable();
-    iodev = console_driver.driver;
+    iodev = console_dev.io_dev;
     rt_hw_interrupt_enable(level);
+
     return iodev;
 }
 
@@ -110,14 +111,13 @@ struct rt_device *console_set_iodev(struct rt_device *iodev)
 
     RT_ASSERT(iodev != RT_NULL);
 
-    console = &console_driver;
+    console = &console_dev;
 
     level = rt_hw_interrupt_disable();
 
     RT_ASSERT(console->init_flag >= TTY_INIT_FLAG_REGED);
 
-    io_before = console->driver;
-
+    io_before = console->io_dev;
     if (iodev == io_before)
     {
         goto exit;
@@ -129,8 +129,7 @@ struct rt_device *console_set_iodev(struct rt_device *iodev)
         iodev_close(console);
     }
 
-    console->driver = iodev;
-
+    console->io_dev = iodev;
     if (console->init_flag >= TTY_INIT_FLAG_INITED)
     {
         rt_err_t ret;
@@ -218,7 +217,7 @@ static rt_ssize_t rt_console_write(struct rt_device *dev,
     RT_ASSERT(console != RT_NULL);
     RT_ASSERT(console->init_flag == TTY_INIT_FLAG_INITED);
 
-    len = rt_device_write((struct rt_device *)console->driver, -1, buffer, size);
+    len = rt_device_write((struct rt_device *)console->io_dev, -1, buffer, size);
 
     return len;
 }
@@ -232,7 +231,7 @@ static rt_err_t  rt_console_control(rt_device_t dev, int cmd, void *args)
     RT_ASSERT(console != RT_NULL);
     RT_ASSERT(console->init_flag == TTY_INIT_FLAG_INITED);
 
-    len = rt_device_control((struct rt_device *)console->driver, cmd, args);
+    len = rt_device_control((struct rt_device *)console->io_dev, cmd, args);
 
     return len;
 }
@@ -248,23 +247,24 @@ const static struct rt_device_ops console_ops =
     rt_console_control,
 };
 #endif
+
 /*
  * console register
  */
- static struct dfs_file_ops con_fops;
+static struct dfs_file_ops con_fops;
 rt_err_t console_register(const char *name, struct rt_device *iodev)
 {
-    rt_base_t level = 0;
     rt_err_t ret = RT_EOK;
     struct rt_device *device = RT_NULL;
-    struct tty_struct *console = &console_driver;
+    struct tty_struct *console = &console_dev;
 
-    level = rt_hw_interrupt_disable();
-    RT_ASSERT(console->init_flag == TTY_INIT_FLAG_NONE);
     RT_ASSERT(iodev != RT_NULL);
+    RT_ASSERT(console->init_flag == TTY_INIT_FLAG_NONE);
 
-    device = &(console->parent);
+    tty_init(console, TTY_DRIVER_TYPE_CONSOLE, SERIAL_TYPE_NORMAL, iodev);
+    console_ldata_init(console);
 
+    device = &(console->parent);
     device->type        = RT_Device_Class_Char;
 
 #ifdef RT_USING_DEVICE_OPS
@@ -278,48 +278,20 @@ rt_err_t console_register(const char *name, struct rt_device *iodev)
     device->control     = rt_console_control;
 #endif
 
-
     /* register a character device */
     ret = rt_device_register(device, name, 0);
     if (ret != RT_EOK)
     {
         LOG_E("console driver register fail\n");
-        goto exit;
     }
-
+    else
+    {
 #ifdef RT_USING_POSIX_DEVIO
-    /* set fops */
-    console_set_fops(&con_fops);
-    device->fops = &con_fops;
+        /* set fops */
+        memcpy(&con_fops, tty_get_fops(), sizeof(struct dfs_file_ops));
+        device->fops = &con_fops;
 #endif
-    console->type = TTY_DRIVER_TYPE_CONSOLE;
-    console->subtype = SERIAL_TYPE_NORMAL;
-    console->driver = iodev;
-    console->head = rt_calloc(1, sizeof(struct tty_node));
-    if (!console->head)
-    {
-        return -RT_ENOMEM;
     }
-    tty_initstack(console->head);
-
-    rt_mutex_init(&console->lock, "ttylock", RT_IPC_FLAG_PRIO);
-    console->pgrp = -1;
-    console->session = -1;
-    console->foreground = RT_NULL;
-    rt_wqueue_init(&console->wait_queue);
 
-    tty_ldisc_init(console);
-
-extern struct termios tty_std_termios;
-    console->init_termios = tty_std_termios;
-    console->init_termios.c_cflag =
-        B9600 | CS8 | CREAD | HUPCL; /* is normally B9600 default... */
-    console->init_termios.__c_ispeed = 9600;
-    console->init_termios.__c_ospeed = 9600;
-
-    console_ldata_init(console);
-    console->init_flag = TTY_INIT_FLAG_REGED;
-exit:
-    rt_hw_interrupt_enable(level);
     return ret;
 }

+ 3 - 190
components/drivers/tty/include/tty.h

@@ -160,7 +160,7 @@ struct tty_struct
 
     struct tty_ldisc *ldisc;
     void *disc_data;
-    struct rt_device *driver;
+    struct rt_device *io_dev;
 
     struct rt_wqueue wait_queue;
 
@@ -208,28 +208,6 @@ enum
 #define TTY_PTY_LOCK 16
 #define TTY_NO_WRITE_SPLIT 17
 
-/*
- * These bits are used in the flags field of the tty structure.
- *
- * So that interrupts won't be able to mess up the queues,
- * copy_to_cooked must be atomic with respect to itself, as must
- * tty->write.  Thus, you must use the inline functions set_bit() and
- * clear_bit() to make things atomic.
- */
-#define TTY_THROTTLED 0
-#define TTY_IO_ERROR 1
-#define TTY_OTHER_CLOSED 2
-#define TTY_EXCLUSIVE 3
-#define TTY_DEBUG 4
-#define TTY_DO_WRITE_WAKEUP 5
-#define TTY_PUSH 6
-#define TTY_CLOSING 7
-#define TTY_DONT_FLIP 8
-#define TTY_HW_COOK_OUT 14
-#define TTY_HW_COOK_IN 15
-#define TTY_PTY_LOCK 16
-#define TTY_NO_WRITE_SPLIT 17
-
 #define NR_LDISCS       30
 
 /* line disciplines */
@@ -270,14 +248,6 @@ enum
 #define TIOCPKT_NOSTOP      16
 #define TIOCPKT_DOSTOP      32
 
-/* tty driver types */
-#define TTY_DRIVER_TYPE_SYSTEM      0x0001
-#define TTY_DRIVER_TYPE_CONSOLE     0x0002
-#define TTY_DRIVER_TYPE_SERIAL      0x0003
-#define TTY_DRIVER_TYPE_PTY     0x0004
-#define TTY_DRIVER_TYPE_SCC     0x0005  /* scc driver */
-#define TTY_DRIVER_TYPE_SYSCONS     0x0006
-
 /* pty subtypes */
 #define PTY_TYPE_MASTER         0x0001
 #define PTY_TYPE_SLAVE          0x0002
@@ -295,8 +265,6 @@ enum
         typeof(b) _b = b;\
         _a < _b ? _a : _b; })
 
-void tty_set_fops(struct dfs_file_ops *fops);
-void console_set_fops(struct dfs_file_ops *fops);
 void mutex_lock(rt_mutex_t mutex);
 void mutex_unlock(rt_mutex_t mutex);
 int __tty_check_change(struct tty_struct *tty, int sig);
@@ -324,167 +292,12 @@ rt_inline void tty_wakeup_check(struct tty_struct *tty)
     rt_wqueue_wakeup(wq, (void*)POLLIN);
 }
 
-rt_inline int set_bit(int nr,int *addr)
-{
-    int mask, retval, level;
-
-    addr += nr >> 5;
-    mask = 1 << (nr & 0x1f);
-    level = rt_hw_interrupt_disable();
-    retval = (mask & *addr) != 0;
-    *addr |= mask;
-    rt_hw_interrupt_enable(level);
-    return retval;
-}
-
-rt_inline int clear_bit(int nr, int *addr)
-{
-    int mask, retval, level;
-
-    addr += nr >> 5;
-    mask = 1 << (nr & 0x1f);
-    level = rt_hw_interrupt_disable();
-    retval = (mask & *addr) != 0;
-    *addr &= ~mask;
-    rt_hw_interrupt_enable(level);
-    return retval;
-}
-
-rt_inline int test_bit(int nr, int *addr)
-{
-    int mask;
-
-    addr += nr >> 5;
-    mask = 1 << (nr & 0x1f);
-    return ((mask & *addr) != 0);
-}
-
-rt_inline int test_and_clear_bit(int nr, volatile void *addr)
-{
-    int mask, retval, level;
-    volatile unsigned int *a = addr;
-
-    a += nr >> 5;
-    mask = 1 << (nr & 0x1f);
-    level = rt_hw_interrupt_disable();
-    retval = (mask & *a) != 0;
-    *a &= ~mask;
-    rt_hw_interrupt_enable(level);
-
-    return retval;
-}
-
-rt_inline unsigned long __ffs(unsigned long word)
-{
-    int num = 0;
-
-#if BITS_PER_LONG == 64
-    if ((word & 0xffffffff) == 0)
-    {
-        num += 32;
-        word >>= 32;
-    }
-#endif
-    if ((word & 0xffff) == 0)
-    {
-        num += 16;
-        word >>= 16;
-    }
-    if ((word & 0xff) == 0)
-    {
-        num += 8;
-        word >>= 8;
-    }
-    if ((word & 0xf) == 0)
-    {
-        num += 4;
-        word >>= 4;
-    }
-    if ((word & 0x3) == 0)
-    {
-        num += 2;
-        word >>= 2;
-    }
-    if ((word & 0x1) == 0)
-    {
-        num += 1;
-    }
-
-    return num;
-}
-#define BITS_PER_LONG       32
-#define BITOP_WORD(nr)      ((nr) / BITS_PER_LONG)
-
-/*
- * Find the next set bit in a memory region.
- */
-rt_inline unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
-                unsigned long offset)
-{
-    const unsigned long *p = addr + BITOP_WORD(offset);
-    unsigned long result = offset & ~(BITS_PER_LONG-1);
-    unsigned long tmp;
-
-    if (offset >= size)
-    {
-        return size;
-    }
-
-    size -= result;
-    offset %= BITS_PER_LONG;
-    if (offset)
-    {
-        tmp = *(p++);
-        tmp &= (~0UL << offset);
-        if (size < BITS_PER_LONG)
-        {
-            goto found_first;
-        }
-
-        if (tmp)
-        {
-            goto found_middle;
-        }
-
-        size -= BITS_PER_LONG;
-        result += BITS_PER_LONG;
-    }
-
-    while (size & ~(BITS_PER_LONG-1))
-    {
-        if ((tmp = *(p++)))
-        {
-            goto found_middle;
-        }
-
-        result += BITS_PER_LONG;
-        size -= BITS_PER_LONG;
-    }
-
-    if (!size)
-    {
-        return result;
-    }
-
-    tmp = *p;
-
-found_first:
-    tmp &= (~0UL >> (BITS_PER_LONG - size));
-    if (tmp == 0UL)     /* Are any bits set? */
-    {
-        return result + size;   /* Nope. */
-    }
-
-found_middle:
-    return result + __ffs(tmp);
-}
+int tty_init(struct tty_struct *tty, int type, int subtype, struct rt_device *iodev);
+const struct dfs_file_ops *tty_get_fops(void);
 
-/*create by tty_ioctl.c*/
 int n_tty_ioctl_extend(struct tty_struct *tty, int cmd, void *arg);
 
-/*create by n_tty.c*/
 void console_ldata_init(struct tty_struct *tty);
 int n_tty_receive_buf(struct tty_struct *tty, char *cp, int count);
-void n_tty_init(void);
 
 #endif /*__TTY_H__*/

+ 185 - 35
components/drivers/tty/n_tty.c

@@ -50,19 +50,6 @@
 #define ECHO_BLOCK      256
 #define ECHO_DISCARD_WATERMARK  RT_TTY_BUF - (ECHO_BLOCK + 32)
 
-rt_inline void tty_sigaddset(lwp_sigset_t *set, int _sig)
-{
-    unsigned long sig = _sig - 1;
-
-    if (_LWP_NSIG_WORDS == 1)
-    {
-        set->sig[0] |= 1UL << sig;
-    }
-    else
-    {
-        set->sig[sig / _LWP_NSIG_BPW] |= 1UL << (sig % _LWP_NSIG_BPW);
-    }
-}
 
 struct n_tty_data
 {
@@ -99,27 +86,197 @@ struct n_tty_data
     rt_mutex_t output_lock;
 };
 
-static inline size_t read_cnt(struct n_tty_data *ldata)
+rt_inline int set_bit(int nr,int *addr)
+{
+    int mask, retval, level;
+
+    addr += nr >> 5;
+    mask = 1 << (nr & 0x1f);
+    level = rt_hw_interrupt_disable();
+    retval = (mask & *addr) != 0;
+    *addr |= mask;
+    rt_hw_interrupt_enable(level);
+    return retval;
+}
+
+rt_inline int clear_bit(int nr, int *addr)
+{
+    int mask, retval, level;
+
+    addr += nr >> 5;
+    mask = 1 << (nr & 0x1f);
+    level = rt_hw_interrupt_disable();
+    retval = (mask & *addr) != 0;
+    *addr &= ~mask;
+    rt_hw_interrupt_enable(level);
+    return retval;
+}
+
+rt_inline int test_bit(int nr, int *addr)
+{
+    int mask;
+
+    addr += nr >> 5;
+    mask = 1 << (nr & 0x1f);
+    return ((mask & *addr) != 0);
+}
+
+rt_inline int test_and_clear_bit(int nr, volatile void *addr)
+{
+    int mask, retval, level;
+    volatile unsigned int *a = addr;
+
+    a += nr >> 5;
+    mask = 1 << (nr & 0x1f);
+    level = rt_hw_interrupt_disable();
+    retval = (mask & *a) != 0;
+    *a &= ~mask;
+    rt_hw_interrupt_enable(level);
+
+    return retval;
+}
+
+rt_inline unsigned long __ffs(unsigned long word)
+{
+    int num = 0;
+
+#if BITS_PER_LONG == 64
+    if ((word & 0xffffffff) == 0)
+    {
+        num += 32;
+        word >>= 32;
+    }
+#endif
+    if ((word & 0xffff) == 0)
+    {
+        num += 16;
+        word >>= 16;
+    }
+    if ((word & 0xff) == 0)
+    {
+        num += 8;
+        word >>= 8;
+    }
+    if ((word & 0xf) == 0)
+    {
+        num += 4;
+        word >>= 4;
+    }
+    if ((word & 0x3) == 0)
+    {
+        num += 2;
+        word >>= 2;
+    }
+    if ((word & 0x1) == 0)
+    {
+        num += 1;
+    }
+
+    return num;
+}
+
+#define BITS_PER_LONG       32
+#define BITOP_WORD(nr)      ((nr) / BITS_PER_LONG)
+
+/*
+ * Find the next set bit in a memory region.
+ */
+rt_inline unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
+                unsigned long offset)
+{
+    const unsigned long *p = addr + BITOP_WORD(offset);
+    unsigned long result = offset & ~(BITS_PER_LONG-1);
+    unsigned long tmp;
+
+    if (offset >= size)
+    {
+        return size;
+    }
+
+    size -= result;
+    offset %= BITS_PER_LONG;
+    if (offset)
+    {
+        tmp = *(p++);
+        tmp &= (~0UL << offset);
+        if (size < BITS_PER_LONG)
+        {
+            goto found_first;
+        }
+
+        if (tmp)
+        {
+            goto found_middle;
+        }
+
+        size -= BITS_PER_LONG;
+        result += BITS_PER_LONG;
+    }
+
+    while (size & ~(BITS_PER_LONG-1))
+    {
+        if ((tmp = *(p++)))
+        {
+            goto found_middle;
+        }
+
+        result += BITS_PER_LONG;
+        size -= BITS_PER_LONG;
+    }
+
+    if (!size)
+    {
+        return result;
+    }
+
+    tmp = *p;
+
+found_first:
+    tmp &= (~0UL >> (BITS_PER_LONG - size));
+    if (tmp == 0UL)     /* Are any bits set? */
+    {
+        return result + size;   /* Nope. */
+    }
+
+found_middle:
+    return result + __ffs(tmp);
+}
+
+rt_inline void tty_sigaddset(lwp_sigset_t *set, int _sig)
+{
+    unsigned long sig = _sig - 1;
+
+    if (_LWP_NSIG_WORDS == 1)
+    {
+        set->sig[0] |= 1UL << sig;
+    }
+    else
+    {
+        set->sig[sig / _LWP_NSIG_BPW] |= 1UL << (sig % _LWP_NSIG_BPW);
+    }
+}
+
+rt_inline size_t read_cnt(struct n_tty_data *ldata)
 {
     return ldata->read_head - ldata->read_tail;
 }
 
-static inline char read_buf(struct n_tty_data *ldata, size_t i)
+rt_inline char read_buf(struct n_tty_data *ldata, size_t i)
 {
     return ldata->read_buf[i & (RT_TTY_BUF - 1)];
 }
 
-static inline char *read_buf_addr(struct n_tty_data *ldata, size_t i)
+rt_inline char *read_buf_addr(struct n_tty_data *ldata, size_t i)
 {
     return &ldata->read_buf[i & (RT_TTY_BUF - 1)];
 }
 
-static inline unsigned char echo_buf(struct n_tty_data *ldata, size_t i)
+rt_inline unsigned char echo_buf(struct n_tty_data *ldata, size_t i)
 {
     return ldata->echo_buf[i & (RT_TTY_BUF - 1)];
 }
 
-static inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i)
+rt_inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i)
 {
     return &ldata->echo_buf[i & (RT_TTY_BUF - 1)];
 }
@@ -134,8 +291,7 @@ static inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i)
  *  n_tty_receive_buf()/producer path:
  *      caller holds non-exclusive termios_rwsem
  */
-
-static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
+rt_inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
 {
     *read_buf_addr(ldata, ldata->read_head) = c;
     ldata->read_head++;
@@ -173,7 +329,7 @@ static void reset_buffer_flags(struct n_tty_data *ldata)
  *  Add a character or operation byte to the echo buffer.
  */
 
-static inline void add_echo_byte(unsigned char c, struct n_tty_data *ldata)
+rt_inline void add_echo_byte(unsigned char c, struct n_tty_data *ldata)
 {
     *echo_buf_addr(ldata, ldata->echo_head++) = c;
 }
@@ -298,7 +454,7 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
  *  @ldata: n_tty data
  */
 
-static inline void finish_erasing(struct n_tty_data *ldata)
+rt_inline void finish_erasing(struct n_tty_data *ldata)
 {
     if (ldata->erasing)
     {
@@ -316,7 +472,7 @@ static inline void finish_erasing(struct n_tty_data *ldata)
  *  of the character when printing
  */
 
-static inline int is_utf8_continuation(unsigned char c)
+rt_inline int is_utf8_continuation(unsigned char c)
 {
     return (c & 0xc0) == 0x80;
 }
@@ -329,7 +485,7 @@ static inline int is_utf8_continuation(unsigned char c)
  *  character and the terminal is in unicode mode.
  */
 
-static inline int is_continuation(unsigned char c, struct tty_struct *tty)
+rt_inline int is_continuation(unsigned char c, struct tty_struct *tty)
 {
     return I_IUTF8(tty) && is_utf8_continuation(c);
 }
@@ -1148,7 +1304,7 @@ static int n_tty_open(struct dfs_file *fd)
     return ret;
 }
 
-static inline int input_available_p(struct tty_struct *tty, int poll)
+rt_inline int input_available_p(struct tty_struct *tty, int poll)
 {
     struct n_tty_data *ldata = tty->disc_data;
     int amt = poll && !TIME_CHAR(tty) && MIN_CHAR(tty) ? MIN_CHAR(tty) : 1;
@@ -1570,7 +1726,7 @@ handle_newline:
     return 0;
 }
 
-static inline void n_tty_receive_char_inline(struct tty_struct *tty, unsigned char c)
+rt_inline void n_tty_receive_char_inline(struct tty_struct *tty, unsigned char c)
 {
     struct n_tty_data *ldata = tty->disc_data;
 
@@ -1695,7 +1851,7 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, char *cp, int cou
     }
 }
 
-static inline void n_tty_receive_char_fast(struct tty_struct *tty, unsigned char c)
+rt_inline void n_tty_receive_char_fast(struct tty_struct *tty, unsigned char c)
 {
     struct n_tty_data *ldata = tty->disc_data;
 
@@ -2018,19 +2174,18 @@ static int n_tty_poll(struct dfs_file *fd, struct rt_pollreq *req)
     lwp = (struct rt_lwp *)(rt_thread_self()->lwp);
     wq = wait_queue_get(lwp, tty);
     rt_poll_add(wq, req);
-    level = rt_hw_interrupt_disable();
 
+    level = rt_hw_interrupt_disable();
     if (input_available_p(tty, 1))
     {
         mask |= POLLIN;
     }
-
     rt_hw_interrupt_enable(level);
 
     return mask;
 }
 
-static struct tty_ldisc_ops n_tty_ops = {
+struct tty_ldisc_ops n_tty_ops = {
     "n_tty",
     0,
     n_tty_open,
@@ -2046,8 +2201,3 @@ static struct tty_ldisc_ops n_tty_ops = {
     n_tty_receive_buf,
     0,
 };
-
-void n_tty_init(void)
-{
-    tty_register_ldisc(N_TTY, &n_tty_ops);
-}

+ 66 - 112
components/drivers/tty/pty.c

@@ -20,21 +20,21 @@
 #include <rtdbg.h>
 
 #define PTY_PTS_SIZE 10
-static struct tty_struct ptm_driver;
-static struct tty_struct pts_drivers[PTY_PTS_SIZE];
+static struct tty_struct ptm_dev;
+static struct tty_struct pts_devs[PTY_PTS_SIZE];
 static int pts_index = 0;
 
-static int pts_register(struct tty_struct *ptm_drv, struct tty_struct *pts_drv, int pts_index);
+static int pts_register(struct tty_struct *ptmx, struct tty_struct *pts, int pts_index);
 
 /* check free pts device */
 static struct tty_struct *find_freepts(void)
 {
     for(int i = 0; i < PTY_PTS_SIZE; i++)
     {
-        if (pts_drivers[i].init_flag == TTY_INIT_FLAG_NONE)
+        if (pts_devs[i].init_flag == TTY_INIT_FLAG_NONE)
         {
-            pts_drivers[i].init_flag = TTY_INIT_FLAG_ALLOCED;
-            return &pts_drivers[i];
+            pts_devs[i].init_flag = TTY_INIT_FLAG_ALLOCED;
+            return &pts_devs[i];
         }
     }
     return RT_NULL;
@@ -73,16 +73,18 @@ static int pty_get_index(struct tty_struct *tty, int *arg)
  */
 static rt_err_t pty_device_init(struct rt_device *dev)
 {
+    rt_ubase_t level = 0;
     rt_err_t result = RT_EOK;
-    int level = 0;
     struct tty_struct *tty = RT_NULL;
-    RT_ASSERT(dev != RT_NULL);
 
+    RT_ASSERT(dev != RT_NULL);
     tty = (struct tty_struct *)dev;
+
     level = rt_hw_interrupt_disable();
     RT_ASSERT(tty->init_flag == TTY_INIT_FLAG_REGED);
     tty->init_flag = TTY_INIT_FLAG_INITED;
     rt_hw_interrupt_enable(level);
+
     return result;
 }
 
@@ -138,8 +140,8 @@ static rt_ssize_t pty_device_write(struct rt_device *dev,
         const void       *buffer,
         rt_size_t         size)
 {
-    rt_base_t level = 0;
     rt_size_t len = 0;
+    rt_base_t level = 0;
     struct tty_struct *tty = RT_NULL;
     struct tty_struct *to = RT_NULL;
 
@@ -147,8 +149,8 @@ static rt_ssize_t pty_device_write(struct rt_device *dev,
     RT_ASSERT(tty != RT_NULL);
     RT_ASSERT(tty->init_flag == TTY_INIT_FLAG_INITED);
     to = tty->other_struct;
-    level = rt_hw_interrupt_disable();
 
+    level = rt_hw_interrupt_disable();
     if (to->ldisc->ops->receive_buf)
     {
         len = to->ldisc->ops->receive_buf(to, (char *)buffer, size);
@@ -179,7 +181,7 @@ static int ptmx_open(struct dfs_file *fd)
 {
     int ret = 0;
     struct tty_struct *tty = RT_NULL;
-    struct tty_struct *pts_drv = RT_NULL;
+    struct tty_struct *pts = RT_NULL;
     struct tty_ldisc *ld = RT_NULL;
     struct rt_lwp *lwp = RT_NULL;
     struct rt_wqueue *wq = RT_NULL;
@@ -187,24 +189,25 @@ static int ptmx_open(struct dfs_file *fd)
     tty = (struct tty_struct *)fd->vnode->data;
     RT_ASSERT(tty != RT_NULL);
 
-    pts_drv = find_freepts();
-    if (pts_drv == RT_NULL)
+    pts = find_freepts();
+    if (pts == RT_NULL)
     {
-        LOG_E("free pts driver find fail\n");
+        LOG_E("No free PTS device found.\n");
         return -1;
     }
-    ret = pts_register(tty, pts_drv, pts_index);
+    ret = pts_register(tty, pts, pts_index);
     if (ret < 0)
     {
         LOG_E("pts register fail\n");
-        rt_free(pts_drv);
+        rt_free(pts);
         return -1;
     }
     pts_index++;
-    lwp = (struct rt_lwp *)(rt_thread_self()->lwp);
+    lwp = lwp_self();
     wq = wait_queue_get(lwp, tty);
-    pts_drv->wait_queue = *wq;
-    tty->other_struct = pts_drv;
+    pts->wait_queue = *wq;
+    tty->other_struct = pts;
+
     ld = tty->ldisc;
     if (ld->ops->open)
     {
@@ -230,94 +233,73 @@ const static struct rt_device_ops pty_device_ops =
     pty_device_control,
 };
 #endif /* RT_USING_DEVICE_OPS */
+
 static struct dfs_file_ops pts_fops;
 static struct dfs_file_ops ptmx_fops;
-static int pts_register(struct tty_struct *ptm_drv, struct tty_struct *pts_drv, int pts_index)
+static int pts_register(struct tty_struct *ptmx, struct tty_struct *pts, int pts_index)
 {
+    char name[20];
     rt_err_t ret = RT_EOK;
-    rt_base_t level = 0;
     struct rt_device *device = RT_NULL;
-    char name[20];
 
-    RT_ASSERT(ptm_drv!=RT_NULL);
-    level = rt_hw_interrupt_disable();
+    RT_ASSERT(ptmx!=RT_NULL);
 
-    if (pts_drv->init_flag != TTY_INIT_FLAG_ALLOCED)
+    if (pts->init_flag != TTY_INIT_FLAG_ALLOCED)
     {
         LOG_E("pts%d has been registered\n", pts_index);
         ret = (-RT_EBUSY);
-        goto _exit;
     }
+    else
+    {
+        tty_init(pts, TTY_DRIVER_TYPE_PTY, PTY_TYPE_SLAVE, NULL);
+        pts->index = pts_index;
+        pts->pts_lock = 1;
+        pts->other_struct = ptmx;
 
-    device = &pts_drv->parent;
-    device->type    = RT_Device_Class_Char;
+        device = &pts->parent;
+        device->type    = RT_Device_Class_Char;
 #ifdef RT_USING_DEVICE_OPS
-    device->ops     = &pty_device_ops;
+        device->ops     = &pty_device_ops;
 #else
-    device->init    = pty_device_init;
-    device->open    = pty_device_open;
-    device->close   = pty_device_close;
-    device->read    = pty_device_read;
-    device->write   = pty_device_write;
-    device->control = pty_device_control;
+        device->init    = pty_device_init;
+        device->open    = pty_device_open;
+        device->close   = pty_device_close;
+        device->read    = pty_device_read;
+        device->write   = pty_device_write;
+        device->control = pty_device_control;
 #endif /* RT_USING_DEVICE_OPS */
 
-    rt_snprintf(name, sizeof(name), "pts%d", pts_index);
-    ret = rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
-    if (ret != RT_EOK)
-    {
-        LOG_E("pts%d register failed\n", pts_index);
-        ret = -RT_EIO;
-        goto _exit;
-    }
-
+        rt_snprintf(name, sizeof(name), "pts%d", pts_index);
+        ret = rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
+        if (ret != RT_EOK)
+        {
+            LOG_E("pts%d register failed\n", pts_index);
+            ret = -RT_EIO;
+        }
+        else
+        {
 #ifdef RT_USING_POSIX_DEVIO
-    /* set fops */
-    tty_set_fops(&pts_fops);
-    device->fops = &pts_fops;
+            /* set fops */
+            memcpy(&pts_fops, tty_get_fops(), sizeof(struct dfs_file_ops));
+            device->fops = &pts_fops;
 #endif
-
-    pts_drv->type = TTY_DRIVER_TYPE_PTY;
-    pts_drv->subtype = PTY_TYPE_SLAVE;
-
-    pts_drv->pgrp = -1;
-    pts_drv->session = -1;
-    pts_drv->foreground = RT_NULL;
-    pts_drv->index = pts_index;
-    pts_drv->pts_lock = 1;
-    rt_wqueue_init(&pts_drv->wait_queue);
-
-    tty_ldisc_init(pts_drv);
-
-extern struct termios tty_std_termios;
-    pts_drv->init_termios = tty_std_termios;
-    pts_drv->init_termios.c_cflag = B38400 | CS8 | CREAD;
-    pts_drv->init_termios.c_lflag |= ECHO | ICANON;
-    pts_drv->init_termios.c_oflag |= ONLCR;
-    pts_drv->init_termios.__c_ispeed = 38400;
-    pts_drv->init_termios.__c_ospeed = 38400;
-
-    pts_drv->other_struct = ptm_drv;
-
-    pts_drv->init_flag = TTY_INIT_FLAG_REGED;
-_exit:
-    rt_hw_interrupt_enable(level);
+        }
+    }
 
     return ret;
 }
 
 static int ptmx_register(void)
 {
-    rt_base_t level = 0;
     rt_err_t ret = RT_EOK;
     struct rt_device *device = RT_NULL;
-    struct tty_struct *ptm_drv = &ptm_driver;
+    struct tty_struct *ptmx = &ptm_dev;
 
-    level = rt_hw_interrupt_disable();
-    RT_ASSERT(ptm_drv->init_flag == TTY_INIT_FLAG_NONE);
+    RT_ASSERT(ptmx->init_flag == TTY_INIT_FLAG_NONE);
 
-    device = &(ptm_drv->parent);
+    tty_init(ptmx, TTY_DRIVER_TYPE_PTY, PTY_TYPE_MASTER, NULL);
 
+    device = &(ptmx->parent);
     device->type = RT_Device_Class_Char;
 
 #ifdef RT_USING_DEVICE_OPS
@@ -336,44 +318,16 @@ static int ptmx_register(void)
     {
         LOG_E("ptmx register fail\n");
         ret = -RT_EIO;
-        goto _exit;
     }
-
+    else
+    {
 #ifdef RT_USING_POSIX_DEVIO
-    /* set fops */
-    tty_set_fops(&ptmx_fops);
-    ptmx_fops.open = ptmx_open;
-    device->fops = &ptmx_fops;
+        /* set fops */
+        memcpy(&ptmx_fops, tty_get_fops(), sizeof(struct dfs_file_ops));
+        ptmx_fops.open = ptmx_open;
+        device->fops = &ptmx_fops;
 #endif
-
-    ptm_drv->type = TTY_DRIVER_TYPE_PTY;
-    ptm_drv->subtype = PTY_TYPE_MASTER;
-    ptm_drv->head = rt_calloc(1, sizeof(struct tty_node));
-    if (!ptm_drv->head)
-    {
-        return -RT_ENOMEM;
     }
-    tty_initstack(ptm_drv->head);
-
-    ptm_drv->pgrp = -1;
-    ptm_drv->session = -1;
-    ptm_drv->foreground = RT_NULL;
-    rt_wqueue_init(&ptm_drv->wait_queue);
-
-    tty_ldisc_init(ptm_drv);
-
-extern struct termios tty_std_termios;
-    ptm_drv->init_termios.c_iflag = 0;
-    ptm_drv->init_termios.c_oflag = 0;
-    ptm_drv->init_termios.c_cflag = B38400 | CS8 | CREAD;
-    ptm_drv->init_termios.c_lflag = 0;
-    ptm_drv->init_termios.__c_ispeed = 38400;
-    ptm_drv->init_termios.__c_ospeed = 38400;
-
-    ptm_drv->init_flag = TTY_INIT_FLAG_REGED;
-
-_exit:
-    rt_hw_interrupt_enable(level);
 
     return ret;
 }

+ 39 - 23
components/drivers/tty/tty.c

@@ -27,7 +27,7 @@
 #endif /* RT_TTY_DEBUG */
 #include <rtdbg.h>
 
-struct termios tty_std_termios = {  /* for the benefit of tty drivers  */
+const struct termios tty_std_termios = {  /* for the benefit of tty drivers  */
     .c_iflag = IMAXBEL | IUCLC | INLCR | ICRNL | IGNPAR,
     .c_oflag = OPOST,
     .c_cflag = B38400 | CS8 | CREAD | HUPCL,
@@ -219,6 +219,7 @@ static int tty_open(struct dfs_file *fd)
 
     tty = (struct tty_struct *)fd->vnode->data;
     RT_ASSERT(tty != RT_NULL);
+
     ld = tty->ldisc;
     if (ld->ops->open)
     {
@@ -322,11 +323,13 @@ static int tty_ioctl(struct dfs_file *fd, int cmd, void *args)
     {
         real_tty = tty;
     }
+
     switch (cmd)
     {
     case TIOCSCTTY:
         return tiocsctty(real_tty, 1);
     }
+
     ld = tty->ldisc;
     if (ld->ops->ioctl)
     {
@@ -343,8 +346,9 @@ static int tty_read(struct dfs_file *fd, void *buf, size_t count)
 
     tty = (struct tty_struct *)fd->vnode->data;
     RT_ASSERT(tty != RT_NULL);
+
     ld = tty->ldisc;
-    if (ld->ops->read)
+    if (ld && ld->ops->read)
     {
         ret = ld->ops->read(fd, buf, count);
     }
@@ -359,11 +363,13 @@ static int tty_write(struct dfs_file *fd, const void *buf, size_t count)
 
     tty = (struct tty_struct *)fd->vnode->data;
     RT_ASSERT(tty != RT_NULL);
+
     ld = tty->ldisc;
-    if (ld->ops->write)
+    if (ld && ld->ops->write)
     {
         ret = ld->ops->write(fd, buf, count);
     }
+
     return ret;
 }
 
@@ -395,30 +401,40 @@ static const struct dfs_file_ops tty_fops =
     RT_NULL, /* getdents */
     tty_poll,
 };
-static const struct dfs_file_ops console_fops =
-{
-    tty_open,
-    tty_close,
-    tty_ioctl,
-    tty_read,
-    tty_write,
-    RT_NULL, /* flush */
-    RT_NULL, /* lseek */
-    RT_NULL, /* getdents */
-    tty_poll,
-};
 
-void console_init()
+const struct dfs_file_ops *tty_get_fops(void)
 {
-    n_tty_init();
+    return &tty_fops;
 }
 
-void tty_set_fops(struct dfs_file_ops *fops)
+int tty_init(struct tty_struct *tty, int type, int subtype, struct rt_device *iodev)
 {
-    *fops = tty_fops;
-}
+    if (tty)
+    {
+        struct tty_node *node = NULL;
 
-void console_set_fops(struct dfs_file_ops *fops)
-{
-    *fops = console_fops;
+        node = rt_calloc(1, sizeof(struct tty_node));
+        if (node)
+        {
+            tty->type = type;
+            tty->subtype = subtype;
+            tty->io_dev = iodev;
+
+            tty->head = node;
+            tty_initstack(tty->head);
+
+            tty->pgrp = -1;
+            tty->session = -1;
+            tty->foreground = RT_NULL;
+
+            rt_mutex_init(&tty->lock, "ttyLock", RT_IPC_FLAG_PRIO);
+            rt_wqueue_init(&tty->wait_queue);
+
+            tty_ldisc_init(tty);
+            tty->init_termios = tty_std_termios;
+            tty->init_flag = TTY_INIT_FLAG_REGED;
+        }
+    }
+
+    return 0;
 }

+ 21 - 23
components/drivers/tty/tty_ldisc.c

@@ -9,7 +9,10 @@
 #endif /* RT_TTY_DEBUG */
 #include <rtdbg.h>
 
-static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
+extern struct tty_ldisc_ops n_tty_ops;
+static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS] = {
+    &n_tty_ops, /* N_TTY = 0 */
+};
 
 static struct tty_ldisc_ops *get_ldops(int disc)
 {
@@ -33,6 +36,7 @@ static void put_ldops(struct tty_ldisc_ops *ldops)
     ldops->refcount--;
     rt_hw_interrupt_enable(level);
 }
+
 static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
 {
     struct tty_ldisc *ld = RT_NULL;
@@ -70,13 +74,11 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
  */
 static void tty_ldisc_put(struct tty_ldisc *ld)
 {
-    if (ld == RT_NULL)
+    if (ld)
     {
-        return;
+        put_ldops(ld->ops);
+        rt_free(ld);
     }
-
-    put_ldops(ld->ops);
-    rt_free(ld);
 }
 
 /**
@@ -87,10 +89,9 @@ static void tty_ldisc_put(struct tty_ldisc *ld)
  *  A helper close method. Also a convenient debugging and check
  *  point.
  */
-
 static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
 {
-    if (ld->ops->close)
+    if (ld && ld->ops->close)
     {
         ld->ops->close(tty);
     }
@@ -104,18 +105,16 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
  */
 void tty_ldisc_kill(struct tty_struct *tty)
 {
-    if (!tty->ldisc)
+    if (tty && tty->ldisc)
     {
-        return;
+        /*
+        * Now kill off the ldisc
+        */
+        tty_ldisc_close(tty, tty->ldisc);
+        tty_ldisc_put(tty->ldisc);
+        /* Force an oops if we mess this up */
+        tty->ldisc = NULL;
     }
-
-    /*
-     * Now kill off the ldisc
-     */
-    tty_ldisc_close(tty, tty->ldisc);
-    tty_ldisc_put(tty->ldisc);
-    /* Force an oops if we mess this up */
-    tty->ldisc = NULL;
 }
 
 int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
@@ -154,7 +153,6 @@ void tty_ldisc_release(struct tty_struct *tty)
      * Shutdown this line discipline. As this is the final close,
      * it does not race with the set_ldisc code path.
      */
-
     level = rt_hw_interrupt_disable();
     tty_ldisc_kill(tty);
     if (o_tty)
@@ -162,7 +160,6 @@ void tty_ldisc_release(struct tty_struct *tty)
         tty_ldisc_kill(o_tty);
     }
     rt_hw_interrupt_enable(level);
-
 }
 
 /**
@@ -175,7 +172,8 @@ void tty_ldisc_release(struct tty_struct *tty)
 
 void tty_ldisc_init(struct tty_struct *tty)
 {
-    struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
-    RT_ASSERT(ld != RT_NULL);
-    tty->ldisc = ld;
+    if (tty)
+    {
+        tty->ldisc = tty_ldisc_get(tty, N_TTY);
+    }
 }

+ 1 - 2
src/kservice.c

@@ -1370,8 +1370,7 @@ rt_device_t rt_console_set_device(const char *name)
 {
 #ifdef RT_USING_SMART
     rt_device_t new_iodev = RT_NULL, old_iodev = RT_NULL;
-extern void console_init();
-    console_init(); /*add line discipline*/
+
     /* find new console device */
     new_iodev = rt_device_find(name);
     if (new_iodev != RT_NULL)