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() 中等待打开的 procs 数量

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

关闭端口时等待的jiffies延迟

closing_wait

关闭之前发送输出的jiffies延迟

drain_delay

如果不需要纯粹的基于时间的drain,则设置为零,否则设置为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() 在端口互斥锁下调用,使用端口互斥锁进行序列化。应该打开设备。

FIXME:从长远来看,将tty参数移出此参数对控制台来说是好事。

destruct

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