TTY 端口

建议 TTY 驱动程序尽可能使用 struct tty_port 助手。如果驱动程序实现了 tty_port.ops.activate()tty_port.ops.shutdown(),则它们可以在各自的 tty_struct.ops 钩子中使用 tty_port_open()tty_port_close()tty_port_hangup()

参考和详细信息包含在底部的 TTY 端口参考TTY 端口操作参考部分。

TTY 端口功能

初始化 & 销毁

void tty_port_init(struct tty_port *port)

初始化 tty_port

参数

struct tty_port *port

要初始化的 tty_port

描述

初始化 struct tty_port 的状态。当使用此函数初始化端口时,必须通过 tty_port_destroy() 销毁该端口。可以间接使用 tty_port 引用计数(tty_port_put()),或者在不使用引用计数时直接销毁。

void tty_port_destroy(struct tty_port *port)

销毁已初始化的端口

参数

struct tty_port *port

要销毁的 tty 端口

描述

当使用 tty_port_init() 初始化端口时,必须通过此函数销毁该端口。可以间接使用 tty_port 引用计数(tty_port_put()),或者在不使用引用计数时直接销毁。

void tty_port_put(struct tty_port *port)

释放对 tty_port 的引用

参数

struct tty_port *port

要释放引用的端口(可以为 NULL)

描述

最后的 put 将使用 port->ops->destruct() 钩子销毁并释放 port,或者如果未提供,则使用 kfree()

打开/关闭/挂起助手

void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)

用于关闭设备的内部助手

参数

struct tty_port *port

要关闭的 tty 端口

struct tty_struct *tty

关联的 tty

描述

它被 tty_port_hangup()tty_port_close() 使用。它的任务是关闭已初始化的设备(请注意控制台保持功能)。它降低 DTR/RTS(如果 tty 设置了 HUPCL)并调用 port->ops->shutdown()

void tty_port_hangup(struct tty_port *port)

挂起助手

参数

struct tty_port *port

tty 端口

描述

执行端口级别的 tty 挂起标志和计数更改。释放 tty 引用。

调用者持有 tty 锁。

int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty, struct file *filp)

tty 打开的等待逻辑

参数

struct tty_port *port

正在打开的 tty 端口

struct tty_struct *tty

正在绑定的 tty 设备

struct file *filp

打开者的文件指针,或者为 NULL

描述

实现打开 tty 设备时的核心 POSIX/SuS tty 行为。处理以下情况:

  • 挂断(之前和期间)

  • 非阻塞打开

  • rts/dtr/dcd

  • 信号

  • 端口标志和计数

如果传入的 port 可以进行载波检测,则必须实现 port->ops->carrier_raised 方法;如果支持这些线的软件管理,则必须实现 port->ops->dtr_rts 方法。请注意,dtr/rts 的拉高是在每次迭代中完成的,因为挂断可能在等待期间之前已经将其拉低。

调用者持有 tty 锁。

注意

在阻塞时可能会释放并重新获取 tty 锁,因此 ttyport 的状态可能已经改变(例如,可能已被挂断)。

int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)

tty->ops->close 的辅助函数,第 1/2 部分

参数

struct tty_port *port

设备的 tty_port

struct tty_struct *tty

正在关闭的 tty

struct file *filp

传入的文件指针

描述

递减并检查打开计数。如果这是最后一次关闭,则刷新端口。这意味着,从设备上的输出缓冲区中删除数据并等待发送逻辑完成。其余的关闭处理在 tty_port_close_end() 中执行。

锁定:调用者持有 tty 锁。

返回

如果这是最后一次关闭,则返回 1,否则返回 0

void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)

tty->ops->close 的辅助函数,第 2/2 部分

参数

struct tty_port *port

设备的 tty_port

struct tty_struct *tty

正在关闭的 tty

描述

这是第一部分的延续:tty_port_close_start()。应在关闭设备后调用此函数。它会刷新线路规程中的数据,并将关闭延迟 port->close_delay

锁定:调用者持有 tty 锁。

void tty_port_close(struct tty_port *port, struct tty_struct *tty, struct file *filp)

通用 tty->ops->close 处理程序

参数

struct tty_port *port

设备的 tty_port

struct tty_struct *tty

正在关闭的 tty

struct file *filp

传入的文件指针

描述

它是在驱动程序的 tty->ops->close 中使用的通用辅助函数。它封装了 tty_port_close_start()tty_port_shutdown()tty_port_close_end() 的序列。后两个函数仅在这是最后一次关闭时调用。有关详细信息,请参阅各个函数。

锁定:调用者持有 tty 锁

int tty_port_install(struct tty_port *port, struct tty_driver *driver, struct tty_struct *tty)

通用 tty->ops->install 处理程序

参数

struct tty_port *port

设备的 tty_port

struct tty_driver *driver

此设备的 tty_driver

struct tty_struct *tty

要安装的 tty

描述

它与 tty_standard_install() 相同,只是提供的 port 链接到由 tty 指定的特定 tty。使用此函数或 tty_port_register_device()(或两者)。最后才调用 tty_port_link_device()

int tty_port_open(struct tty_port *port, struct tty_struct *tty, struct file *filp)

通用 tty->ops->open 处理程序

参数

struct tty_port *port

设备的 tty_port

struct tty_struct *tty

要打开的 tty

struct file *filp

传入的文件指针

描述

它是在驱动程序的 tty->ops->open 中使用的通用辅助函数。如果设备尚未激活,它会使用 port->ops->activate 激活设备。并使用 tty_port_block_til_ready() 等待设备准备就绪(例如,拉高 DTR/CTS 并等待载波)。

请注意,当 port->ops->activate 返回错误时,不会调用 port->ops->shutdown(相反,会调用 tty->ops->close)。

锁定:调用者持有 tty 锁。

注意

可能会释放并重新获取 tty 锁(在 tty_port_block_til_ready() 中),因此 ttyport 的状态可能已经改变(例如,现在可能已挂断)。

TTY 引用计数

struct tty_struct *tty_port_tty_get(struct tty_port *port)

获取 tty 引用

参数

struct tty_port *port

tty 端口

描述

返回一个受引用计数保护的 tty 实例,如果端口未与 tty 关联(例如,由于关闭或挂断),则返回 NULL

void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)

设置端口的 tty

参数

struct tty_port *port

tty 端口

struct tty_struct *tty

tty

描述

关联端口和 tty 对。管理任何内部引用计数。传递 NULL 以取消关联端口。

TTY 辅助函数

void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)

辅助挂断 tty

参数

struct tty_port *port

tty 端口

bool check_clocal

只挂起未设置 CLOCAL 的 tty 吗?

void tty_port_tty_wakeup(struct tty_port *port)

唤醒 tty 的辅助函数

参数

struct tty_port *port

tty 端口

调制解调器信号

bool tty_port_carrier_raised(struct tty_port *port)

载波检测检查

参数

struct tty_port *port

tty 端口

描述

载波检测逻辑的包装器。目前,它用于隐藏一些内部细节。最终,这将完全成为 tty 端口的内部功能。

void tty_port_raise_dtr_rts(struct tty_port *port)

拉高 DTR/RTS

参数

struct tty_port *port

tty 端口

描述

DTR/RTS 拉高逻辑的包装器。目前,它用于隐藏一些内部细节。最终,这将完全成为 tty 端口的内部功能。

void tty_port_lower_dtr_rts(struct tty_port *port)

拉低 DTR/RTS

参数

struct tty_port *port

tty 端口

描述

DTR/RTS 拉高逻辑的包装器。目前,它用于隐藏一些内部细节。最终,这将完全成为 tty 端口的内部功能。


TTY 端口引用

struct tty_port
  • 端口级别信息

定义:

struct tty_port {
    struct tty_bufhead      buf;
    struct tty_struct       *tty;
    struct tty_struct       *itty;
    const struct tty_port_operations *ops;
    const struct tty_port_client_operations *client_ops;
    spinlock_t lock;
    int blocked_open;
    int count;
    wait_queue_head_t open_wait;
    wait_queue_head_t delta_msr_wait;
    unsigned long           flags;
    unsigned long           iflags;
    unsigned char           console:1;
    struct mutex            mutex;
    struct mutex            buf_mutex;
    u8 *xmit_buf;
    u8 *xmit_fifo;
    unsigned int            close_delay;
    unsigned int            closing_wait;
    int drain_delay;
    struct kref             kref;
    void *client_data;
};

成员

buf

此端口的缓冲区,在内部锁定

tty

指向 struct tty_struct 的后向指针,仅当 tty 打开时才有效。使用 tty_port_tty_get() 获取它(并使用 tty_kref_put() 释放)。

itty

指向 struct tty_struct 的内部后向指针。请避免使用它。从长远来看,应该消除它。

ops

tty 端口操作(例如激活、关闭),请参阅 struct tty_port_operations

client_ops

tty 端口客户端操作(例如 receive_buf、write_wakeup)。默认情况下,使用 tty_port_default_client_ops。

lock

保护 tty 的锁

blocked_open

tty_port_block_til_ready() 中等待打开的进程数

count

使用计数

open_wait

打开等待者队列(例如,等待载波)

delta_msr_wait

调制解调器状态更改队列(等待 MSR 更改)

flags

用户 TTY 标志 (ASYNC_)

iflags

内部标志 (TTY_PORT_)

console

设置后,端口为控制台

mutex

用于打开、关闭和其他端口操作的锁定

buf_mutex

xmit_buf 分配锁

xmit_buf

某些驱动程序使用的可选 xmit 缓冲区

xmit_fifo

某些驱动程序使用的可选 xmit 缓冲区

close_delay

关闭端口时等待的节拍延迟

closing_wait

关闭前发送输出的节拍延迟

drain_delay

如果不需要基于纯时间的耗尽,则设置为零;否则设置为 fifo 的大小

kref

引用计数器。如果非 NULL,则达到零时调用 ops->destruct();否则释放端口。

client_data

指向私有数据的指针,用于 client_ops

描述

每个设备都保留其自己的端口级别信息。引入 struct tty_port 作为此类信息的通用结构。由于每个 TTY 设备都应具有一个支持 tty_port 结构,因此每个驱动程序都可以使用这些成员。

tty 端口的生命周期与 tty 不同,因此必须分开保存。此外,请注意,tty -> port 映射在 tty 对象的生命周期内有效,但在许多情况下,port -> tty 映射仅在挂起之前有效,因此请勿使用错误的路径。

tty 端口应由 tty_port_init() 初始化,并通过 tty_port_destroy()(不使用引用计数)或 tty_port_put()(引用计数)关闭。

围绕 struct tty_port 也有很多辅助函数。要列出最重要的几个:tty_port_open()tty_port_close()(或者如果需要,可以单独使用 tty_port_close_start()tty_port_close_end())和 tty_port_hangup()。这些函数根据需要调用 ops->activate()ops->shutdown()


TTY 端口操作引用

struct tty_port_operations
  • tty_port 上的操作

定义:

struct tty_port_operations {
    bool (*carrier_raised)(struct tty_port *port);
    void (*dtr_rts)(struct tty_port *port, bool active);
    void (*shutdown)(struct tty_port *port);
    int (*activate)(struct tty_port *port, struct tty_struct *tty);
    void (*destruct)(struct tty_port *port);
};

成员

carrier_raised

如果 port 上的载波被拉高,则返回 true

dtr_rts

如果 active 为 true,则拉高 DTR 线,否则拉低 DTR 线

shutdown

当最后一个关闭完成或挂起结束(仅当端口已初始化)时调用。请勿用于释放资源。仅关闭设备。在端口互斥锁下调用,以与 activateshutdown 串行化。

activate

tty_port_open() 中的端口互斥锁下调用,使用端口互斥锁进行序列化。应打开设备。

注意:从长远来看,从这里获取 tty 参数out 对于控制台来说会很好。

destruct

在端口的最后一次 put 时调用。释放资源,可能包括端口本身。