TTY 驱动程序和 TTY 操作

分配

驱动程序需要做的第一件事是分配一个 struct tty_driver。这通过 tty_alloc_driver()(或 __tty_alloc_driver())来完成。接下来,新分配的结构填充了信息。请参阅本文档末尾的 TTY 驱动程序参考,了解实际需要填充的内容。

分配例程需要驱动程序最多可以处理的设备数量和标志。标志是那些以 TTY_DRIVER_ 开头的标志,如下面的 TTY 驱动程序标志中列出和描述的。

当驱动程序即将被释放时,会调用 tty_driver_kref_put()。它将递减引用计数,如果达到零,则驱动程序将被释放。

作为参考,这里详细解释了分配和释放函数

tty_alloc_driver

tty_alloc_driver (lines, flags)

分配 tty 驱动程序

参数

lines

此驱动程序最多可以处理的行数

flags

enum tty_driver_flag 中的一些,将在 driver->flags 中设置

返回值

struct tty_driver 或 PTR 编码的错误(使用 IS_ERR() 及其同类)。

struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, unsigned long flags)

分配 tty 驱动程序

参数

unsigned int lines

此驱动程序最多可以处理的行数

struct module *owner

负责此驱动程序的模块

unsigned long flags

enum tty_driver_flag 中的一些,将在 driver->flags 中设置

描述

不应直接调用此函数,而应使用 tty_alloc_driver()

返回值

struct tty_driver 或 PTR 编码的错误(使用 IS_ERR() 及其同类)。

void tty_driver_kref_put(struct tty_driver *driver)

释放对 tty 驱动程序的引用

参数

struct tty_driver *driver

要释放其引用的驱动程序

描述

最后的 put 将销毁并释放驱动程序。

TTY 驱动程序标志

以下是 tty_alloc_driver()(或 __tty_alloc_driver())接受的标志的文档

enum tty_driver_flag
  • TTY 驱动程序标志

常量

TTY_DRIVER_INSTALLED

此驱动程序是否已成功安装。这是一个 tty 内部标志。请勿触摸。

TTY_DRIVER_RESET_TERMIOS

请求 tty 层在最后一个进程关闭设备时重置 termios 设置。特别是用于 PTY。

TTY_DRIVER_REAL_RAW

指示如果为此 tty 设置了此标志,则驱动程序将保证不设置任何特殊字符处理标志

(IGNBRK || (!BRKINT && !PARMRK)) && (IGNPAR || !INPCK)

也就是说,如果没有理由让驱动程序将奇偶校验和中断字符的通知发送到线路驱动程序,它就不会这样做。如果设置了此标志,则线路驱动程序可以针对此情况进行优化。(请注意,如果上述情况为真,也承诺不发出溢出信号。)

TTY_DRIVER_DYNAMIC_DEV

当在系统中找到设备时,需要通过调用 tty_register_device() 注册各个 tty 设备,并通过调用 tty_unregister_device() 注销,以便设备在 sysfs 中正确显示。如果未设置,则所有 tty_driver.num 条目将在调用 tty_register_driver() 时由 tty 核心在 sysfs 中创建。这供具有 tty 设备(可以在主 tty 驱动程序已向 tty 核心注册时出现和消失)的驱动程序使用。

TTY_DRIVER_DEVPTS_MEM

不要使用标准数组(tty_driver.ttystty_driver.termios),而是使用通过 devpts 文件系统键控的动态内存。这仅适用于 PTY 驱动程序。

TTY_DRIVER_HARDWARE_BREAK

硬件处理中断信号。将请求的超时传递给 tty_operations.break_ctl,而不是使用简单的开/关接口。

TTY_DRIVER_DYNAMIC_ALLOC

不要为此驱动程序分配每行所需的结构(tty_driver.ports),因为它会浪费内存。驱动程序将负责。这仅适用于 PTY 驱动程序。

TTY_DRIVER_UNNUMBERED_NODE

不要创建编号的 /dev 节点。例如,创建 /dev/ttyprintk 而不是 /dev/ttyprintk0。仅当分配单个 tty 设备的驱动程序时适用。

描述

这些是传递给 tty_alloc_driver() 的标志。


注册

分配并填写 struct tty_driver 后,可以使用 tty_register_driver() 注册。建议在 tty_alloc_driver() 的标志中传递 TTY_DRIVER_DYNAMIC_DEV。如果未传递,则所有设备也会在 tty_register_driver() 期间注册,并且可以为这些驱动程序跳过以下注册设备段落。但是,注册设备中的 struct tty_port 部分仍然相关。

int tty_register_driver(struct tty_driver *driver)

注册 tty 驱动程序

参数

struct tty_driver *driver

要注册的驱动程序

描述

由 tty 驱动程序调用以注册自身。

void tty_unregister_driver(struct tty_driver *driver)

注销 tty 驱动程序

参数

struct tty_driver *driver

要注销的驱动程序

描述

由 tty 驱动程序调用以注销自身。

注册设备

每个 TTY 设备都应由 struct tty_port 支持。通常,TTY 驱动程序将 tty_port 嵌入到设备的私有结构中。有关处理 tty_port 的更多详细信息,请参见 TTY 端口。还建议驱动程序通过 tty_port_get() 和 tty_port_put() 使用 tty_port 的引用计数。最后的 put 应该释放 tty_port,包括设备的私有结构。

除非 TTY_DRIVER_DYNAMIC_DEV 作为标志传递给 tty_alloc_driver(),否则 TTY 驱动程序应注册在系统中发现的每个设备(后者是首选)。这通过 tty_register_device()tty_register_device_attr() 执行,如果驱动程序想要通过 struct attribute_group 公开一些信息。它们都注册 index 的设备,并且在返回时,可以打开该设备。稍后在 将设备链接到端口中也描述了首选的 tty_port 变体。驱动程序可以管理空闲索引并选择正确的索引。TTY 层仅拒绝注册比传递给 tty_alloc_driver() 更多的设备。

当设备打开时,TTY 层分配 struct tty_struct 并开始从 tty_driver.ops 调用操作,请参见 TTY 操作参考

注册例程的文档如下

struct device *tty_register_device(struct tty_driver *driver, unsigned index, struct device *device)

注册 tty 设备

参数

struct tty_driver *driver

描述 tty 设备的 tty 驱动程序

unsigned index

此 tty 设备在 tty 驱动程序中的索引

struct device *device

与此 tty 设备关联的 struct device。此字段是可选的,如果此 tty 设备没有已知的 struct device,则可以安全地将其设置为 NULL。

描述

如果 tty 驱动程序的标志设置了 TTY_DRIVER_DYNAMIC_DEV 位,则需要进行此调用以注册单个 tty 设备。如果未设置该位,则 tty 驱动程序不应调用此函数。

锁定:??

返回值

指向此 tty 设备的 struct device 的指针(或出错时为 ERR_PTR(-EFOO))。

struct device *tty_register_device_attr(struct tty_driver *driver, unsigned index, struct device *device, void *drvdata, const struct attribute_group **attr_grp)

注册 tty 设备

参数

struct tty_driver *driver

描述 tty 设备的 tty 驱动程序

unsigned index

此 tty 设备在 tty 驱动程序中的索引

struct device *device

与此 tty 设备关联的 struct device。此字段是可选的,如果此 tty 设备没有已知的 struct device,则可以安全地将其设置为 NULL

void *drvdata

要设置为设备驱动程序的数据。

const struct attribute_group **attr_grp

要在设备上设置的属性组。

描述

如果 tty 驱动程序的标志设置了 TTY_DRIVER_DYNAMIC_DEV 位,则需要进行此调用以注册单个 tty 设备。如果未设置该位,则 tty 驱动程序不应调用此函数。

锁定:??

返回值

指向此 tty 设备的 struct device 的指针(或出错时为 ERR_PTR(-EFOO))。

void tty_unregister_device(struct tty_driver *driver, unsigned index)

注销 tty 设备

参数

struct tty_driver *driver

描述 tty 设备的 tty 驱动程序

unsigned index

此 tty 设备在 tty 驱动程序中的索引

描述

如果通过调用 tty_register_device() 注册了 tty 设备,则当 tty 设备消失时,必须调用此函数。

锁定:??


将设备链接到端口

如前所述,每个 TTY 设备都应分配一个 struct tty_port。至少在 tty_driver.ops.install() 时 TTY 层必须知道它。有一些帮助程序可以链接两者。理想情况下,驱动程序使用 tty_port_register_device()tty_port_register_device_attr() 而不是注册时的 tty_register_device()tty_register_device_attr()。这样,驱动程序无需稍后担心链接。

如果这不可能,驱动程序仍然可以通过 tty_port_link_device() 在实际注册之前将 tty_port 链接到特定索引。如果仍然不合适,可以从 tty_driver.ops.install 挂钩中使用 tty_port_install() 作为最后的手段。最后一个主要用于内存设备(如 PTY),其中 tty_ports 是按需分配的。

链接例程在此处记录

链接 tty 和 tty_port

参数

struct tty_port *port

设备的 tty_port

struct tty_driver *driver

此设备的 tty_driver

unsigned index

tty 的索引

描述

向 tty 层提供从 tty(由 index 指定)到 tty_port (port) 的链接。仅当驱动程序中未使用 tty_port_register_device()tty_port_install() 中的任何一个时才使用此方法。如果使用,则必须在 tty_register_driver() 之前调用此方法。

struct device *tty_port_register_device(struct tty_port *port, struct tty_driver *driver, unsigned index, struct device *device)

注册 tty 设备

参数

struct tty_port *port

设备的 tty_port

struct tty_driver *driver

此设备的 tty_driver

unsigned index

tty 的索引

struct device *device

如果存在父设备,否则为 NULL

描述

tty_register_device() 相同,只是提供的 port 链接到由 index 指定的特定 tty。使用此方法或 tty_port_install()(或两者)。将 tty_port_link_device() 作为最后的手段调用。

struct device *tty_port_register_device_attr(struct tty_port *port, struct tty_driver *driver, unsigned index, struct device *device, void *drvdata, const struct attribute_group **attr_grp)

注册 tty 设备

参数

struct tty_port *port

设备的 tty_port

struct tty_driver *driver

此设备的 tty_driver

unsigned index

tty 的索引

struct device *device

如果存在父设备,否则为 NULL

void *drvdata

要设置为设备驱动程序的数据。

const struct attribute_group **attr_grp

要在设备上设置的属性组。

描述

tty_register_device_attr() 相同,只是提供的 port 链接到由 index 指定的特定 tty。使用此方法或 tty_port_install()(或两者)。将 tty_port_link_device() 作为最后的手段调用。


TTY 驱动程序参考

本文档记录了 struct tty_driver 的所有成员。必需成员在末尾注明。接下来将介绍 struct tty_operations

struct tty_driver
  • TTY 设备的驱动程序

定义:

struct tty_driver {
    struct kref kref;
    struct cdev **cdevs;
    struct module   *owner;
    const char      *driver_name;
    const char      *name;
    int name_base;
    int major;
    int minor_start;
    unsigned int    num;
    enum tty_driver_type type;
    enum tty_driver_subtype subtype;
    struct ktermios init_termios;
    unsigned long   flags;
    struct proc_dir_entry *proc_entry;
    struct tty_driver *other;
    struct tty_struct **ttys;
    struct tty_port **ports;
    struct ktermios **termios;
    void *driver_state;
    const struct tty_operations *ops;
    struct list_head tty_drivers;
};

成员

kref

引用计数。计数归零会释放所有内部结构和驱动程序。

cdevs

已分配/注册的字符 /dev 设备

owner

拥有此驱动程序的模块。正在使用的驱动程序无法使用 rmmod 命令移除。由 tty_alloc_driver() 自动设置。

driver_name

驱动程序在 /proc/tty 中使用的名称

name

用于构造 /dev 节点名称

name_base

用作构造 /dev 节点名称的数字基数

major

主 /dev 设备号(自动分配为零)

minor_start

第一个次 /dev 设备号

num

已分配的设备数量

type

TTY 驱动程序的类型 (enum tty_driver_type)

subtype

TTY 驱动程序的子类型 (enum tty_driver_subtype)

init_termios

最初为每个 TTY 设置的 termios(例如 tty_std_termios

flags

TTY 驱动程序标志 (TTY_DRIVER_)

proc_entry

proc fs 条目,内部使用

other

链接的 TTY 的驱动程序;仅用于 PTY 驱动程序

ttys

活动 struct tty_struct 数组,由 tty_standard_install() 设置

ports

struct tty_port 数组;可以在初始化期间通过 tty_port_link_device() 和类似函数设置

termios

用于存储每次 TTY 关闭时的 termios,以便下次打开时使用

driver_state

指向驱动程序的任意数据的指针

ops

TTY 的驱动程序挂钩。使用 tty_set_operations() 设置它们。尽可能在其中使用 struct tty_port 辅助函数。

tty_drivers

内部用于链接 tty_drivers

描述

处理 struct tty_driver 的常用方法是通过 tty_alloc_driver() 分配它,设置所有必要的成员,并通过 tty_register_driver() 注册它。最后,通过调用 tty_unregister_driver(),然后调用 tty_driver_kref_put() 来关闭驱动程序。

在调用 tty_register_driver() 之前需要设置的字段包括 driver_namenametypesubtypeinit_termiosops


TTY 操作参考

注册 TTY 后,TTY 层可以调用这些驱动程序挂钩

struct tty_operations
  • 驱动程序和 tty 之间的接口

定义:

struct tty_operations {
    struct tty_struct * (*lookup)(struct tty_driver *driver, struct file *filp, int idx);
    int (*install)(struct tty_driver *driver, struct tty_struct *tty);
    void (*remove)(struct tty_driver *driver, struct tty_struct *tty);
    int (*open)(struct tty_struct * tty, struct file * filp);
    void (*close)(struct tty_struct * tty, struct file * filp);
    void (*shutdown)(struct tty_struct *tty);
    void (*cleanup)(struct tty_struct *tty);
    ssize_t (*write)(struct tty_struct *tty, const u8 *buf, size_t count);
    int (*put_char)(struct tty_struct *tty, u8 ch);
    void (*flush_chars)(struct tty_struct *tty);
    unsigned int (*write_room)(struct tty_struct *tty);
    unsigned int (*chars_in_buffer)(struct tty_struct *tty);
    int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg);
    long (*compat_ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg);
    void (*set_termios)(struct tty_struct *tty, const struct ktermios *old);
    void (*throttle)(struct tty_struct * tty);
    void (*unthrottle)(struct tty_struct * tty);
    void (*stop)(struct tty_struct *tty);
    void (*start)(struct tty_struct *tty);
    void (*hangup)(struct tty_struct *tty);
    int (*break_ctl)(struct tty_struct *tty, int state);
    void (*flush_buffer)(struct tty_struct *tty);
    int (*ldisc_ok)(struct tty_struct *tty, int ldisc);
    void (*set_ldisc)(struct tty_struct *tty);
    void (*wait_until_sent)(struct tty_struct *tty, int timeout);
    void (*send_xchar)(struct tty_struct *tty, u8 ch);
    int (*tiocmget)(struct tty_struct *tty);
    int (*tiocmset)(struct tty_struct *tty, unsigned int set, unsigned int clear);
    int (*resize)(struct tty_struct *tty, struct winsize *ws);
    int (*get_icount)(struct tty_struct *tty, struct serial_icounter_struct *icount);
    int (*get_serial)(struct tty_struct *tty, struct serial_struct *p);
    int (*set_serial)(struct tty_struct *tty, struct serial_struct *p);
    void (*show_fdinfo)(struct tty_struct *tty, struct seq_file *m);
#ifdef CONFIG_CONSOLE_POLL;
    int (*poll_init)(struct tty_driver *driver, int line, char *options);
    int (*poll_get_char)(struct tty_driver *driver, int line);
    void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
#endif;
    int (*proc_show)(struct seq_file *m, void *driver);
};

成员

lookup

struct tty_struct *()(struct tty_driver *self, struct file *, int idx)

返回与 idx 对应的 tty 设备,如果没有当前正在使用的设备,则返回 NULL,如果出现错误,则返回 ERR_PTR 值。在 tty_mutex 下调用(目前!)。

可选方法。默认行为是使用 self->ttys 数组。

install

int ()(struct tty_driver *self, struct tty_struct *tty)

将新的 tty 安装到 self 的内部表中。与 lookupremove 方法结合使用。

可选方法。默认行为是使用 self->ttys 数组。

remove

void ()(struct tty_driver *self, struct tty_struct *tty)

self 的内部表中移除已关闭的 tty。与 lookupremove 方法结合使用。

可选方法。默认行为是使用 self->ttys 数组。

open

int ()(struct tty_struct *tty, struct file *)

当打开特定的 tty 设备时,将调用此例程。此例程是必需的;如果未填写此例程,则尝试打开将失败并显示 ENODEV

必需方法。在持有 tty 锁的情况下调用。可能会睡眠。

close

void ()(struct tty_struct *tty, struct file *)

当关闭特定的 tty 设备时,将调用此例程。从此调用返回时,驱动程序不得再进行任何类型的 ldisc 调用。

备注:即使相应的 open() 失败,也会调用。

必需方法。在持有 tty 锁的情况下调用。可能会睡眠。

shutdown

void ()(struct tty_struct *tty)

当最后一次关闭特定的 tty 设备时,将在 tty 锁下调用此例程。它在释放 tty 资源之前执行,因此可以在另一个函数持有 tty kref 时执行。

cleanup

void ()(struct tty_struct *tty)

当最后一次关闭特定的 tty 设备时,将异步调用此例程,以释放资源。对于可能会睡眠的例程,这实际上是关闭的第二部分。

write

ssize_t ()(struct tty_struct *tty, const u8 *buf, size_t count)

内核调用此例程,以将一系列 (count) 字符 (buf) 写入 tty 设备。字符可能来自用户空间或内核空间。此例程将返回实际接受写入的字符数。

在特殊情况下可能会并行发生。因为这包括紧急情况路径,所以驱动程序通常不应尝试在此处进行巧妙的锁定。

可选:对于可写设备是必需的。可能不会睡眠。

put_char

int ()(struct tty_struct *tty, u8 ch)

内核调用此例程以将单个字符 ch 写入 tty 设备。如果内核使用此例程,则在将字符填充到驱动程序中后,必须调用 flush_chars() 例程(如果已定义)。如果队列中没有空间,则忽略该字符。

可选:如果未提供,内核将使用 write 方法。请勿直接调用此函数,请调用 tty_put_char()

flush_chars

void ()(struct tty_struct *tty)

在使用 put_char() 将一系列字符写入 tty 设备后,内核将调用此例程。

可选。请勿直接调用此函数,请调用 tty_driver_flush_chars()。

write_room

unsigned int ()(struct tty_struct *tty)

此例程返回 tty 驱动程序将接受排队写入的字符数。此数字会随着输出缓冲区清空或输出流控制生效而发生变化。

ldisc 负责对 write_room/write 调用的多线程进行智能处理

如果提供了 write 方法,则为必需方法,否则不需要。请勿直接调用此函数,请调用 tty_write_room()

chars_in_buffer

unsigned int ()(struct tty_struct *tty)

此例程返回设备专用输出队列中的字符数。用于 tty_wait_until_sent() 和 poll() 实现。

可选:如果未提供,则假定设备上没有队列。请勿直接调用此函数,请调用 tty_chars_in_buffer()

ioctl

int ()(struct tty_struct *tty, unsigned int cmd, unsigned long arg)

此例程允许 tty 驱动程序实现特定于设备的 ioctl。如果驱动程序无法识别传入的 ioctl 号 cmd,则应返回 ENOIOCTLCMD

可选。

compat_ioctl

long ()(struct tty_struct *tty, unsigned int cmd, unsigned long arg)

在 64 位系统上实现 32 位进程的 ioctl 处理。

可选。

set_termios

void ()(struct tty_struct *tty, const struct ktermios *old)

当设备的 termios 设置发生更改时,此例程允许通知 tty 驱动程序。新设置位于 tty->termios 中。先前的设置在 old 参数中传递。

API 定义为驱动程序应返回所选的实际模式。这意味着驱动程序负责修改 tty->termios 中的任何无法满足的位,以指示正在使用的实际模式。

可选。在 tty->termios_rwsem 下调用。可能会睡眠。

throttle

void ()(struct tty_struct *tty)

此例程通知 tty 驱动程序,线路规程的输入缓冲区已接近填满,它应以某种方式发出信号,指示不应再向 tty 发送字符。

包括 unthrottle() 的序列化是 ldisc 层的工作。

可选:始终通过 tty_throttle_safe() 调用。在 tty->termios_rwsem 下调用。

unthrottle

void ()(struct tty_struct *tty)

此例程通知 tty 驱动程序,它应发出信号,指示现在可以向 tty 发送字符,而不必担心线路规程的输入缓冲区溢出。

可选。始终通过 tty_unthrottle() 调用。在 tty->termios_rwsem 下调用。

stop

void ()(struct tty_struct *tty)

此例程通知 tty 驱动程序,它应停止向 tty 设备输出字符。

在持有 tty->flow.lock 的情况下调用。与 start() 方法序列化。

可选。始终通过 stop_tty() 调用。

start

void ()(struct tty_struct *tty)

此例程通知 tty 驱动程序,它已恢复向 tty 设备发送字符。

在持有 tty->flow.lock 的情况下调用。与 stop() 方法序列化。

可选。始终通过 start_tty() 调用。

hangup

void ()(struct tty_struct *tty)

此例程通知 tty 驱动程序,它应挂断 tty 设备。

可选。在持有 tty 锁的情况下调用。

break_ctl

int ()(struct tty_struct *tty, int state)

此可选例程请求 tty 驱动程序打开或关闭 RS-232 端口上的 BREAK 状态。如果 state 为 -1,则应打开 BREAK 状态;如果 state 为 0,则应关闭 BREAK 状态。

如果实现了此例程,则高级 tty 驱动程序将处理以下 ioctl:TCSBRKTCSBRKPTIOCSBRKTIOCCBRK

如果驱动程序在 tty_alloc_driver() 中设置 TTY_DRIVER_HARDWARE_BREAK,则该接口也将使用实际时间调用,并且硬件应自行完成延迟工作。0 和 -1 仍用于开/关。

可选:TCSBRK/BRKP/等处理必需。可能会睡眠。

flush_buffer

void ()(struct tty_struct *tty)

此例程放弃设备专用输出缓冲区。在关闭、挂断时调用,以实现 TCOFLUSH ioctl 和类似操作。

可选:如果未提供,则假定设备上没有队列。请勿直接调用此函数,请调用 tty_driver_flush_buffer()

ldisc_ok

int ()(struct tty_struct *tty, int ldisc)

此例程允许 tty 驱动程序决定是否可以处理特定的 ldisc

可选。在 tty->ldisc_semtty->termios_rwsem 下调用。

set_ldisc

void ()(struct tty_struct *tty)

当设备的线路规程正在更改时,此例程允许通知 tty 驱动程序。此时,该规程尚不可用。

可选。在 tty->ldisc_semtty->termios_rwsem 下调用。

wait_until_sent

void ()(struct tty_struct *tty, int timeout)

此例程等待设备写出其发射器 FIFO 中的所有字符。或者直到达到 timeout(以 jiffies 为单位)。

可选:如果未提供,则假定设备没有 FIFO。通常可以通过 tty_wait_until_sent() 调用。可能会睡眠。

send_xchar

void ()(struct tty_struct *tty, u8 ch)

此例程用于将高优先级 XON/XOFF 字符 (ch) 发送到 tty 设备。

可选:如果未提供,则在 tty->atomic_write_lock 下调用 write 方法,以使其与 ldisc 序列化。

tiocmget

int ()(struct tty_struct *tty)

此例程用于从 tty 驱动程序获取调制解调器状态位。

可选:如果未提供,则从 TIOCMGET ioctl 返回 ENOTTY。请勿直接调用此函数,请调用 tty_tiocmget()

tiocmset

int ()(struct tty_struct *tty, unsigned int set, unsigned int clear)

此例程用于将调制解调器状态位设置为 tty 驱动程序。首先,应清除 clear 位,然后设置 set 位。

可选:如果未提供,则从 TIOCMSET ioctl 返回 ENOTTY。请勿直接调用此函数,请调用 tty_tiocmset()

resize

int ()(struct tty_struct *tty, struct winsize *ws)

当发出更改请求的终端几何形状为 ws 的 termios 请求时调用。

可选:默认操作是更新 termios 结构而不出错。这通常是正确的行为。如果驱动程序不是可调整大小的对象(例如,串行线路),则不应在此处强制错误。如果需要将标准方法包装在自己的逻辑中(通常情况下),请参阅 tty_do_resize()

get_icount

int ()(struct tty_struct *tty, struct serial_icounter *icount)

tty 设备收到 TIOCGICOUNT ioctl 时调用。传递一个内核结构 icount 以完成。

可选:仅在提供时调用,否则将返回 ENOTTY

get_serial

int ()(struct tty_struct *tty, struct serial_struct *p)

tty 设备收到 TIOCGSERIAL ioctl 时调用。传递一个内核结构 p (struct serial_struct) 以完成。

可选:仅在提供时调用,否则将返回 ENOTTY。请勿直接调用此函数,请调用 tty_tiocgserial()。

set_serial

int ()(struct tty_struct *tty, struct serial_struct *p)

tty 设备收到 TIOCSSERIAL ioctl 时调用。传递一个内核结构 p (struct serial_struct) 以设置值。

可选:仅在提供时调用,否则将返回 ENOTTY。请勿直接调用此函数,请调用 tty_tiocsserial()。

show_fdinfo

void ()(struct tty_struct *tty, struct seq_file *m)

tty 设备文件描述符收到来自 VFS 的 fdinfo 请求(以显示在 /proc/<pid>/fdinfo/ 中)时调用。应使用信息填充 m

可选:仅在提供时调用,否则不会将任何内容写入 m。请勿直接调用此函数,请调用 tty_show_fdinfo()。

poll_init

int ()(struct tty_driver *driver, int line, char *options)

kgdboc 支持(使用 kgdb、kdb 和内核调试器内部结构)。调用此例程以初始化 HW,以便稍后通过调用 poll_get_charpoll_put_char 来使用。

可选:仅在提供时调用,否则将跳过作为非轮询驱动程序。

poll_get_char

int ()(struct tty_driver *driver, int line)

kgdboc 支持(请参阅 poll_init)。driver 应从由 line 标识的 tty 读取字符并返回它。

可选:仅在提供 poll_init 时调用。

poll_put_char

void ()(struct tty_driver *driver, int line, char ch)

kgdboc 支持(请参阅 poll_init)。driver 应将字符 ch 写入由 line 标识的 tty。

可选:仅在提供 poll_init 时调用。

proc_show

int ()(struct seq_file *m, void *driver)

驱动程序 driver(强制转换为 struct tty_driver)可以在 /proc/tty/driver/<driver_name> 中显示其他信息。只需将信息填充到 m 中即可。

可选:仅在提供时调用,否则不会创建 /proc 条目。

描述

此结构定义了底层 tty 驱动程序和 tty 例程之间的接口。可以定义这些例程。除非另有说明,否则它们是可选的,并且可以用 NULL 指针填充。