linux tty driver 相关结构体
没有特殊声明均出自 include/linux/tty.h
struct tty_port_operations
/*
* Port level information. Each device keeps its own port level information
* so provide a common structure for those ports wanting to use common support
* routines.
*
* The tty port has a different lifetime to the tty so must be kept apart.
* In addition be careful as tty -> port mappings are valid for the life
* of the tty object but in many cases port -> tty mappings are valid only
* until a hangup so don't use the wrong path.
*/
struct tty_port_operations {
/* Return 1 if the carrier is raised */
int (*carrier_raised)(struct tty_port *port);
/* Control the DTR line */
void (*dtr_rts)(struct tty_port *port, int raise);
/* Called when the last close completes or a hangup finishes
IFF the port was initialized. Do not use to free resources. Called
under the port mutex to serialize against activate/shutdowns */
void (*shutdown)(struct tty_port *port);
/* Called under the port mutex from tty_port_open, serialized using
the port mutex */
/* FIXME: long term getting the tty argument *out* of this would be
good for consoles */
int (*activate)(struct tty_port *port, struct tty_struct *tty);
/* Called on the final put of a port */
void (*destruct)(struct tty_port *port);
};
struct tty_port
struct tty_port {
struct tty_bufhead buf; /* Locked internally */
struct tty_struct *tty; /* Back pointer */
struct tty_struct *itty; /* internal back ptr */
const struct tty_port_operations *ops; /* Port operations */
spinlock_t lock; /* Lock protecting tty field */
int blocked_open; /* Waiting to open */
int count; /* Usage count */
wait_queue_head_t open_wait; /* Open waiters */
wait_queue_head_t close_wait; /* Close waiters */
wait_queue_head_t delta_msr_wait; /* Modem status change */
unsigned long flags; /* TTY flags ASY_*/
unsigned char console:1, /* port is a console */
low_latency:1; /* direct buffer flush */
struct mutex mutex; /* Locking */
struct mutex buf_mutex; /* Buffer alloc lock */
unsigned char *xmit_buf; /* Optional buffer */
unsigned int close_delay; /* Close port delay */
unsigned int closing_wait; /* Delay for output */
int drain_delay; /* Set to zero if no pure time
based drain is needed else
set to size of fifo */
struct kref kref; /* Ref counter */
};
struct tty_struct
/*
* Where all of the state associated with a tty is kept while the tty
* is open. Since the termios state should be kept even if the tty
* has been closed --- for things like the baud rate, etc --- it is
* not stored here, but rather a pointer to the real state is stored
* here. Possible the winsize structure should have the same
* treatment, but (1) the default 80x24 is usually right and (2) it's
* most often used by a windowing system, which will set the correct
* size each time the window is created or resized anyway.
* - TYT, 9/14/92
*/
struct tty_struct {
int magic;
struct kref kref;
struct device *dev;
struct tty_driver *driver;
const struct tty_operations *ops;
int index;
/* Protects ldisc changes: Lock tty not pty */
struct ld_semaphore ldisc_sem;
struct tty_ldisc *ldisc;
struct mutex atomic_write_lock;
struct mutex legacy_mutex;
struct mutex throttle_mutex;
struct rw_semaphore termios_rwsem;
struct mutex winsize_mutex;
spinlock_t ctrl_lock;
/* Termios values are protected by the termios rwsem */
struct ktermios termios, termios_locked;
struct termiox *termiox; /* May be NULL for unsupported */
char name[64];
struct pid *pgrp; /* Protected by ctrl lock */
struct pid *session;
unsigned long flags;
int count;
struct winsize winsize; /* winsize_mutex */
unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1;
unsigned char ctrl_status; /* ctrl_lock */
unsigned int receive_room; /* Bytes free for queue */
int flow_change;
struct tty_struct *link;
struct fasync_struct *fasync;
int alt_speed; /* For magic substitution of 38400 bps */
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
struct work_struct hangup_work;
void *disc_data;
void *driver_data;
struct list_head tty_files;
#define N_TTY_BUF_SIZE 4096
unsigned char closing:1;
unsigned char *write_buf;
int write_cnt;
/* If the tty has a pending do_SAK, queue it here - akpm */
struct work_struct SAK_work;
struct tty_port *port;
};
/*
* This structure defines the interface between the low-level tty
* driver and the tty routines. The following routines can be
* defined; unless noted otherwise, they are optional, and can be
* filled in with a null pointer.
*
* struct tty_struct * (*lookup)(struct tty_driver *self, int idx)
*
* Return the tty device corresponding to idx, NULL if there is not
* one currently in use and an ERR_PTR value on error. Called under
* tty_mutex (for now!)
*
* Optional method. Default behaviour is to use the ttys array
*
* int (*install)(struct tty_driver *self, struct tty_struct *tty)
*
* Install a new tty into the tty driver internal tables. Used in
* conjunction with lookup and remove methods.
*
* Optional method. Default behaviour is to use the ttys array
*
* void (*remove)(struct tty_driver *self, struct tty_struct *tty)
*
* Remove a closed tty from the tty driver internal tables. Used in
* conjunction with lookup and remove methods.
*
* Optional method. Default behaviour is to use the ttys array
*
* int (*open)(struct tty_struct * tty, struct file * filp);
*
* This routine is called when a particular tty device is opened.
* This routine is mandatory; if this routine is not filled in,
* the attempted open will fail with ENODEV.
*
* Required method.
*
* void (*close)(struct tty_struct * tty, struct file * filp);
*
* This routine is called when a particular tty device is closed.
* Note: called even if the corresponding open() failed.
*
* Required method.
*
* void (*shutdown)(struct tty_struct * tty);
*
* This routine is called under the tty lock when a particular tty device
* is closed for the last time. It executes before the tty resources
* are freed so may execute while another function holds a tty kref.
*
* void (*cleanup)(struct tty_struct * tty);
*
* This routine is called asynchronously when a particular tty device
* is closed for the last time freeing up the resources. This is
* actually the second part of shutdown for routines that might sleep.
*
*
* int (*write)(struct tty_struct * tty,
* const unsigned char *buf, int count);
*
* This routine is called by the kernel to write a series of
* characters to the tty device. The characters may come from
* user space or kernel space. This routine will return the
* number of characters actually accepted for writing.
*
* Optional: Required for writable devices.
*
* int (*put_char)(struct tty_struct *tty, unsigned char ch);
*
* This routine is called by the kernel to write a single
* character to the tty device. If the kernel uses this routine,
* it must call the flush_chars() routine (if defined) when it is
* done stuffing characters into the driver. If there is no room
* in the queue, the character is ignored.
*
* Optional: Kernel will use the write method if not provided.
*
* Note: Do not call this function directly, call tty_put_char
*
* void (*flush_chars)(struct tty_struct *tty);
*
* This routine is called by the kernel after it has written a
* series of characters to the tty device using put_char().
*
* Optional:
*
* Note: Do not call this function directly, call tty_driver_flush_chars
*
* int (*write_room)(struct tty_struct *tty);
*
* This routine returns the numbers of characters the tty driver
* will accept for queuing to be written. This number is subject
* to change as output buffers get emptied, or if the output flow
* control is acted.
*
* Required if write method is provided else not needed.
*
* Note: Do not call this function directly, call tty_write_room
*
* int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg);
*
* This routine allows the tty driver to implement
* device-specific ioctls. If the ioctl number passed in cmd
* is not recognized by the driver, it should return ENOIOCTLCMD.
*
* Optional
*
* long (*compat_ioctl)(struct tty_struct *tty,,
* unsigned int cmd, unsigned long arg);
*
* implement ioctl processing for 32 bit process on 64 bit system
*
* Optional
*
* void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
*
* This routine allows the tty driver to be notified when
* device's termios settings have changed.
*
* Optional: Called under the termios lock
*
*
* void (*set_ldisc)(struct tty_struct *tty);
*
* This routine allows the tty driver to be notified when the
* device's termios settings have changed.
*
* Optional: Called under BKL (currently)
*
* void (*throttle)(struct tty_struct * tty);
*
* This routine notifies the tty driver that input buffers for
* the line discipline are close to full, and it should somehow
* signal that no more characters should be sent to the tty.
*
* Optional: Always invoke via tty_throttle(), called under the
* termios lock.
*
* void (*unthrottle)(struct tty_struct * tty);
*
* This routine notifies the tty drivers that it should signals
* that characters can now be sent to the tty without fear of
* overrunning the input buffers of the line disciplines.
*
* Optional: Always invoke via tty_unthrottle(), called under the
* termios lock.
*
* void (*stop)(struct tty_struct *tty);
*
* This routine notifies the tty driver that it should stop
* outputting characters to the tty device.
*
* Optional:
*
* Note: Call stop_tty not this method.
*
* void (*start)(struct tty_struct *tty);
*
* This routine notifies the tty driver that it resume sending
* characters to the tty device.
*
* Optional:
*
* Note: Call start_tty not this method.
*
* void (*hangup)(struct tty_struct *tty);
*
* This routine notifies the tty driver that it should hang up the
* tty device.
*
* Optional:
*
* int (*break_ctl)(struct tty_struct *tty, int state);
*
* This optional routine requests the tty driver to turn on or
* off BREAK status on the RS-232 port. If state is -1,
* then the BREAK status should be turned on; if state is 0, then
* BREAK should be turned off.
*
* If this routine is implemented, the high-level tty driver will
* handle the following ioctls: TCSBRK, TCSBRKP, TIOCSBRK,
* TIOCCBRK.
*
* If the driver sets TTY_DRIVER_HARDWARE_BREAK then the interface
* will also be called with actual times and the hardware is expected
* to do the delay work itself. 0 and -1 are still used for on/off.
*
* Optional: Required for TCSBRK/BRKP/etc handling.
*
* void (*wait_until_sent)(struct tty_struct *tty, int timeout);
*
* This routine waits until the device has written out all of the
* characters in its transmitter FIFO.
*
* Optional: If not provided the device is assumed to have no FIFO
*
* Note: Usually correct to call tty_wait_until_sent
*
* void (*send_xchar)(struct tty_struct *tty, char ch);
*
* This routine is used to send a high-priority XON/XOFF
* character to the device.
*
* Optional: If not provided then the write method is called under
* the atomic write lock to keep it serialized with the ldisc.
*
* int (*resize)(struct tty_struct *tty, struct winsize *ws)
*
* Called when a termios request is issued which changes the
* requested terminal geometry.
*
* Optional: the default action is to update the termios structure
* without error. This is usually the correct behaviour. Drivers should
* not force errors here if they are not resizable objects (eg a serial
* line). See tty_do_resize() if you need to wrap the standard method
* in your own logic - the usual case.
*
* void (*set_termiox)(struct tty_struct *tty, struct termiox *new);
*
* Called when the device receives a termiox based ioctl. Passes down
* the requested data from user space. This method will not be invoked
* unless the tty also has a valid tty->termiox pointer.
*
* Optional: Called under the termios lock
*
* int (*get_icount)(struct tty_struct *tty, struct serial_icounter *icount);
*
* Called when the device receives a TIOCGICOUNT ioctl. Passed a kernel
* structure to complete. This method is optional and will only be called
* if provided (otherwise EINVAL will be returned).
*/
struct serial_struct
path: include/uapi/linux/serial.h
struct serial_struct {
int type;
int line;
unsigned int port;
int irq;
int flags;
int xmit_fifo_size;
int custom_divisor;
int baud_base;
unsigned short close_delay;
char io_type;
char reserved_char[1];
int hub6;
unsigned short closing_wait; /* time to wait before closing */
unsigned short closing_wait2; /* no longer used... */
unsigned char *iomem_base;
unsigned short iomem_reg_shift;
unsigned int port_high;
unsigned long iomap_base; /* cookie passed into ioremap */
};
struct async_icount
/*
* Counters of the input lines (CTS, DSR, RI, CD) interrupts
*/
struct async_icount {
__u32 cts, dsr, rng, dcd, tx, rx;
__u32 frame, parity, overrun, brk;
__u32 buf_overrun;
};
struct termios
struct termios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
};
struct ktermios
struct ktermios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
speed_t c_ispeed; /* input speed */
speed_t c_ospeed; /* output speed */
};
struct tty_operations
struct tty_operations {
struct tty_struct * (*lookup)(struct tty_driver *driver,
struct inode *inode, 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);
int (*write)(struct tty_struct * tty,
const unsigned char *buf, int count);
int (*put_char)(struct tty_struct *tty, unsigned char ch);
void (*flush_chars)(struct tty_struct *tty);
int (*write_room)(struct tty_struct *tty);
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, 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);
void (*set_ldisc)(struct tty_struct *tty);
void (*wait_until_sent)(struct tty_struct *tty, int timeout);
void (*send_xchar)(struct tty_struct *tty, char 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 (*set_termiox)(struct tty_struct *tty, struct termiox *tnew);
int (*get_icount)(struct tty_struct *tty,
struct serial_icounter_struct *icount);
#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
const struct file_operations *proc_fops;
};
struct tty_driver
struct tty_driver {
int magic; /* magic number for this structure */
struct kref kref; /* Reference management */
struct cdev *cdevs;
struct module *owner;
const char *driver_name;
const char *name;
int name_base; /* offset of printed name */
int major; /* major device number */
int minor_start; /* start of minor device number */
unsigned int num; /* number of devices allocated */
short type; /* type of tty driver */
short subtype; /* subtype of tty driver */
struct ktermios init_termios; /* Initial termios */
unsigned long flags; /* tty driver flags */
struct proc_dir_entry *proc_entry; /* /proc fs entry */
struct tty_driver *other; /* only used for the PTY driver */
/*
* Pointer to the tty data structures
*/
struct tty_struct **ttys;
struct tty_port **ports;
struct ktermios **termios;
void *driver_state;
/*
* Driver methods
*/
const struct tty_operations *ops;
struct list_head tty_drivers;
};
宏定义: c_cc c_iflag c_oflag c_cflag c_lflag
/* c_cc characters */ /* 控制字符 */
#define VINTR 0
#define VQUIT 1
#define VERASE 2
#define VKILL 3
#define VEOF 4
#define VTIME 5
#define VMIN 6
#define VSWTC 7
#define VSTART 8
#define VSTOP 9
#define VSUSP 10
#define VEOL 11
#define VREPRINT 12
#define VDISCARD 13
#define VWERASE 14
#define VLNEXT 15
#define VEOL2 16
/* c_iflag bits */ //输入模式标志
#define IGNBRK 0000001 // ignore break 忽略输入(命令行)中的break状态(ctrl + C)
#define BRKINT 0000002 // 如果没有设置,但是设置了 BRKINT,那么 BREAK 将使得输入和输出队列被刷新,如果终端是一个前台进程组的控制终 //端,这个进程组中所有进程将收到 SIGINT 信号。如果既未设置 IGNBRK 也未设置 BRKINT,BREAK 将视为与 NUL 字符
#define IGNPAR 0000004 // 忽略桢错误和奇偶校验错
#define PARMRK 0000010
#define INPCK 0000020 // 启用输入奇偶检测
#define ISTRIP 0000040 // 去掉第八位
#define INLCR 0000100 // 将输入中的 NL 翻译为 CR NL: new line
#define IGNCR 0000200 // 忽略输入中的回车
#define ICRNL 0000400 // 将输入中的回车翻译为新行 (除非设置了 IGNCR)(否则当输入信号有 CR 时不会终止输入)
#define IUCLC 0001000 //up character low character (不属于 POSIX) 将输入中的大写字母映射为小写字母
#define IXON 0002000 // :启用输出的 XON/XOFF 流控制
#define IXANY 0004000 // (不属于 POSIX.1;XSI) 允许任何字符来重新开始输出
#define IXOFF 0010000 // 启用输入的 XON/XOFF 流控制
#define IMAXBEL 0020000
#define IUTF8 0040000
/* c_oflag bits */ //输出模式标志
#define OPOST 0000001 // 启用具体实现自行定义的输出处理 /
#define OLCUC 0000002
#define ONLCR 0000004 // (XSI) 将输出中的新行符映射为回车-换行
#define OCRNL 0000010 // 将输出中的回车映射为新行符
#define ONOCR 0000020 // 不在第 0 列输出回车
#define ONLRET 0000040 // 不输出回车
#define OFILL 0000100 // 发送填充字符作为延时,而不是使用定时来延时
#define OFDEL 0000200 // (不属于 POSIX) 填充字符是 ASCII DEL (0177)。如果不设置,填充字符则是 ASCII NUL
#define NLDLY 0000400
#define NL0 0000000
#define NL1 0000400
#define CRDLY 0003000 // 回车延时掩码。取值为 CR0, CR1, CR2, 或 CR3 /
#define CR0 0000000
#define CR1 0001000
#define CR2 0002000
#define CR3 0003000
#define TABDLY 0014000 // 水平跳格延时掩码。取值为 TAB0, TAB1, TAB2, TAB3 (或 XTABS)。取值为 TAB3,即 XTABS,将扩展跳格为空格 ( //每个跳格符填充 8 个空格) /
#define TAB0 0000000
#define TAB1 0004000
#define TAB2 0010000
#define TAB3 0014000
#define XTABS 0014000
#define BSDLY 0020000
#define BS0 0000000
#define BS1 0020000
#define VTDLY 0040000 // 竖直跳格延时掩码。取值为 VT0 或 VT1 /
#define VT0 0000000
#define VT1 0040000
#define FFDLY 0100000
#define FF0 0000000
#define FF1 0100000
/* c_cflag bit meaning */ //控制模式标志
#define CBAUD 0010017 // (不属于 POSIX) 波特率掩码 (4+1 位) /
#define B0 0000000 /* hang up */
#define B50 0000001
#define B75 0000002
#define B110 0000003
#define B134 0000004
#define B150 0000005
#define B200 0000006
#define B300 0000007
#define B600 0000010
#define B1200 0000011
#define B1800 0000012
#define B2400 0000013
#define B4800 0000014
#define B9600 0000015
#define B19200 0000016
#define B38400 0000017
#define EXTA B19200
#define EXTB B38400
#define CSIZE 0000060 // 字符长度掩码(传送或接收字元时用的位数)。取值为 CS5(传送或接收字元时用5bits), CS6, CS7, 或 CS8 /
#define CS5 0000000 //CS : character size
#define CS6 0000020
#define CS7 0000040
#define CS8 0000060
#define CSTOPB 0000100 // 设置两个停止位,而不是一个 /
#define CREAD 0000200 // 打开接受者 /
#define PARENB 0000400 // 允许输出产生奇偶信息以及输入的奇偶校验 /
#define PARODD 0001000 // 输入和输出是奇校验 /
#define HUPCL 0002000 // 在最后一个进程关闭设备后,降低 modem 控制线 (挂断) /
#define CLOCAL 0004000 // 忽略 modem 控制线 /
#define CBAUDEX 0010000
#define BOTHER 0010000
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
#define B460800 0010004
#define B500000 0010005
#define B576000 0010006
#define B921600 0010007
#define B1000000 0010010
#define B1152000 0010011
#define B1500000 0010012
#define B2000000 0010013
#define B2500000 0010014
#define B3000000 0010015
#define B3500000 0010016
#define B4000000 0010017
#define CIBAUD 002003600000 /* input baud rate */
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */
#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
/* c_lflag bits */ //本地模式标志
#define ISIG 0000001
#define ICANON 0000002 // (正规模式)标志,它可以对所接收的字元在两种不同的终端设备模式之间来回切换 /
#define XCASE 0000004 // 当接受到字符 INTR, QUIT, SUSP, 或 DSUSP 时,产生相应的信号 /
#define ECHO 0000010 // 它可以让你阻止键入字元的回应 /
#define ECHOE 0000020 // 如果同时设置了 ICANON,字符 ERASE 擦除前一个输入字符,WERASE 擦除前一个词 /
#define ECHOK 0000040 // 如果同时设置了 ICANON,字符 KILL 删除当前行 /
#define ECHONL 0000100 // 如果同时设置了 ICANON,回显字符 NL,即使没有设置 ECHO /
#define NOFLSH 0000200 // 禁止在产生 SIGINT, SIGQUIT 和 SIGSUSP 信号时刷新输入和输出队列,即关闭queue中的flush /
#define TOSTOP 0000400 // 向试图写控制终端的后台进程组发送 SIGTTOU 信号(传送欲写入的信息到后台处理) /
#define ECHOCTL 0001000
#define ECHOPRT 0002000
#define ECHOKE 0004000
#define FLUSHO 0010000
#define PENDIN 0040000
#define IEXTEN 0100000 // 启用实现自定义的输入处理。这个标志必须与 ICANON 同时使用,才能解释特殊字符 EOL2,LNEXT,REPRINT 和 WER //ASE,IUCLC 标志才有效 /
#define EXTPROC 0200000