现在的位置: 首页 > 综合 > 正文

tty驱动程序之线路规程open函数调用路径

2013年02月20日 ⁄ 综合 ⁄ 共 2208字 ⁄ 字号 评论关闭

    在看tty_io.c文件中的tty_open()函数时,发现有这么一行代码:

if (tty->ops->open)

      retval = tty->ops->open(tty, filp);

else

      return -ENODEV;

   这说明,在打开tty设备时,tty内核层的open()函数调用了tty驱动层的open()函数。那么,线路规程层的open()函数又是在哪里调用的呢?

   其实线路规程层的open()函数也是在tty内核层的open()函数中被调用,而且还是在tty驱动层open()函数调用之前被调用。

   tty内核层open()函数中调用了函数tty_init_dev,代码如下:

tty = tty_init_dev(driver, index, 0);

   tty_init_dev()是个很重要的函数,做了很多事情。

   整理一下,调用路径如下:

   用户层open -> tty_open -> tty_init_cdev -> tty_ldisc_setup -> tty_ldisc_open -> 线路规程层open函数。

   综上所述,tty内核层的open函数调用了tty线路规程层的open函数和tty驱动层的open函数。

   下面我们列举一个tty线路规程层的open函数:

STATIC int32 ps_tty_open(struct tty_struct *tty)
{
    int32 err = 0;
    struct ps_core_s *ps_core_d == NULL;

    ps_get_core_reference(&ps_core_d);
    if (unlikely(NULL == ps_core_d))
    {
        return -EINVAL;
    }

    ps_core_d->tty = tty;
    tty->disc_data = ps_core_d;

    /* don't do an wakeup for now */
    clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);

    /* mem already allocated */
    tty->receive_room = 65536;
    /* Flush any pending characters in the driver and discipline. */
    tty_ldisc_flush(tty);
    tty_driver_flush_buffer(tty);
    /* signal to octty that installation of N_HW_BFG ldisc is complete   */
    ps_tty_complete(ps_core_d->pm_data);
    ps_change_baud_rate_complete(ps_core_d->pm_data);
    return err;
}

STATIC void ps_tty_close(struct tty_struct *tty)
{
    struct  ps_core_s *ps_core_d = NULL;
    if ((NULL == tty)||(NULL == tty->disc_data))
    {
        return;
    }
    ps_core_d = tty->disc_data;
    /* Flush any pending characters in the driver and discipline. */
    tty_ldisc_flush(tty);
    tty_driver_flush_buffer(tty);
    ps_core_d->tty = NULL;
    /* signal to complate that N_HW_BFG ldisc is un-installed */
    ps_tty_complete(ps_core_d->pm_data);
    ps_kfree_skb(ps_core_d, TX_HIGH_QUEUE);
    ps_kfree_skb(ps_core_d, TX_LOW_QUEUE);
}

 

 

 

 

 

 

 

 

 

 

    PS_PRINT_FUNCTION_NAME;
    if ((NULL == tty)||(NULL == tty->disc_data))
    {
        PS_PRINT_ERR("tty or tty->disc_data is NULL");
        return;
    }
    ps_core_d = tty->disc_data;
    /* Flush any pending characters in the driver and discipline. */
    tty_ldisc_flush(tty);
    tty_driver_flush_buffer(tty);
    ps_core_d->tty = NULL;
    /* signal to complate that N_HW_BFG ldisc is un-installed */
    ps_tty_complete(ps_core_d->pm_data);
    ps_kfree_skb(ps_core_d, TX_HIGH_QUEUE);
    ps_kfree_skb(ps_core_d, TX_LOW_QUEUE);
    PS_PRINT_INFO("%s: have done!!!", __func__);
}

抱歉!评论已关闭.