diff options
Diffstat (limited to 'include/linux/tty.h')
| -rw-r--r-- | include/linux/tty.h | 732 |
1 files changed, 273 insertions, 459 deletions
diff --git a/include/linux/tty.h b/include/linux/tty.h index 01ac30efd6a6..0a46e4054dec 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LINUX_TTY_H #define _LINUX_TTY_H @@ -7,10 +8,12 @@ #include <linux/workqueue.h> #include <linux/tty_driver.h> #include <linux/tty_ldisc.h> +#include <linux/tty_port.h> #include <linux/mutex.h> #include <linux/tty_flags.h> #include <uapi/linux/tty.h> - +#include <linux/rwsem.h> +#include <linux/llist.h> /* @@ -28,48 +31,6 @@ */ #define __DISABLED_CHAR '\0' -struct tty_buffer { - struct tty_buffer *next; - char *char_buf_ptr; - unsigned char *flag_buf_ptr; - int used; - int size; - int commit; - int read; - /* Data points here */ - unsigned long data[0]; -}; - -/* - * We default to dicing tty buffer allocations to this many characters - * in order to avoid multiple page allocations. We know the size of - * tty_buffer itself but it must also be taken into account that the - * the buffer is 256 byte aligned. See tty_buffer_find for the allocation - * logic this must match - */ - -#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) - - -struct tty_bufhead { - struct work_struct work; - spinlock_t lock; - struct tty_buffer *head; /* Queue head */ - struct tty_buffer *tail; /* Active buffer */ - struct tty_buffer *free; /* Free queue head */ - int memory_used; /* Buffer space used excluding - free queue */ -}; -/* - * When a break, frame error, or parity error happens, these codes are - * stuffed into the flags buffer. - */ -#define TTY_NORMAL 0 -#define TTY_BREAK 1 -#define TTY_FRAME 2 -#define TTY_PARITY 3 -#define TTY_OVERRUN 4 - #define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR]) #define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT]) #define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE]) @@ -134,6 +95,7 @@ struct tty_bufhead { #define C_CLOCAL(tty) _C_FLAG((tty), CLOCAL) #define C_CIBAUD(tty) _C_FLAG((tty), CIBAUD) #define C_CRTSCTS(tty) _C_FLAG((tty), CRTSCTS) +#define C_CMSPAR(tty) _C_FLAG((tty), CMSPAR) #define L_ISIG(tty) _L_FLAG((tty), ISIG) #define L_ICANON(tty) _L_FLAG((tty), ICANON) @@ -154,130 +116,131 @@ struct tty_bufhead { struct device; struct signal_struct; +struct tty_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. +/** + * struct tty_struct - state associated with a tty while open * - * 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; - -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); - void (*drop)(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_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 long iflags; /* TTYP_ internal flags */ -#define TTYP_FLUSHING 1 /* Flushing to ldisc in progress */ -#define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */ - 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 */ -}; - -/* - * 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 + * @kref: reference counting by tty_kref_get() and tty_kref_put(), reaching zero + * frees the structure + * @dev: class device or %NULL (e.g. ptys, serdev) + * @driver: &struct tty_driver operating this tty + * @ops: &struct tty_operations of @driver for this tty (open, close, etc.) + * @index: index of this tty (e.g. to construct @name like tty12) + * @ldisc_sem: protects line discipline changes (@ldisc) -- lock tty not pty + * @ldisc: the current line discipline for this tty (n_tty by default) + * @atomic_write_lock: protects against concurrent writers, i.e. locks + * @write_cnt, @write_buf and similar + * @legacy_mutex: leftover from history (BKL -> BTM -> @legacy_mutex), + * protecting several operations on this tty + * @throttle_mutex: protects against concurrent tty_throttle_safe() and + * tty_unthrottle_safe() (but not tty_unthrottle()) + * @termios_rwsem: protects @termios and @termios_locked + * @winsize_mutex: protects @winsize + * @termios: termios for the current tty, copied from/to @driver.termios + * @termios_locked: locked termios (by %TIOCGLCKTRMIOS and %TIOCSLCKTRMIOS + * ioctls) + * @name: name of the tty constructed by tty_line_name() (e.g. ttyS3) + * @flags: bitwise OR of %TTY_THROTTLED, %TTY_IO_ERROR, ... + * @count: count of open processes, reaching zero cancels all the work for + * this tty and drops a @kref too (but does not free this tty) + * @winsize: size of the terminal "window" (cf. @winsize_mutex) + * @flow: flow settings grouped together + * @flow.lock: lock for @flow members + * @flow.stopped: tty stopped/started by stop_tty()/start_tty() + * @flow.tco_stopped: tty stopped/started by %TCOOFF/%TCOON ioctls (it has + * precedence over @flow.stopped) + * @ctrl: control settings grouped together + * @ctrl.lock: lock for @ctrl members + * @ctrl.pgrp: process group of this tty (setpgrp(2)) + * @ctrl.session: session of this tty (setsid(2)). Writes are protected by both + * @ctrl.lock and @legacy_mutex, readers must use at least one of + * them. + * @ctrl.pktstatus: packet mode status (bitwise OR of %TIOCPKT_ constants) + * @ctrl.packet: packet mode enabled + * @hw_stopped: not controlled by the tty layer, under @driver's control for CTS + * handling + * @receive_room: bytes permitted to feed to @ldisc without any being lost + * @flow_change: controls behavior of throttling, see tty_throttle_safe() and + * tty_unthrottle_safe() + * @link: link to another pty (master -> slave and vice versa) + * @fasync: state for %O_ASYNC (for %SIGIO); managed by fasync_helper() + * @write_wait: concurrent writers are waiting in this queue until they are + * allowed to write + * @read_wait: readers wait for data in this queue + * @hangup_work: normally a work to perform a hangup (do_tty_hangup()); while + * freeing the tty, (re)used to release_one_tty() + * @disc_data: pointer to @ldisc's private data (e.g. to &struct n_tty_data) + * @driver_data: pointer to @driver's private data (e.g. &struct uart_state) + * @files_lock: protects @tty_files list + * @tty_files: list of (re)openers of this tty (i.e. linked &struct + * tty_file_private) + * @closing: when set during close, n_tty processes only START & STOP chars + * @write_buf: temporary buffer used during tty_write() to copy user data to + * @write_cnt: count of bytes written in tty_write() to @write_buf + * @SAK_work: if the tty has a pending do_SAK, it is queued here + * @port: persistent storage for this device (i.e. &struct tty_port) + * + * All of the state associated with a tty while the tty is open. Persistent + * storage for tty devices is referenced here as @port and is documented in + * &struct tty_port. */ - -struct tty_operations; - struct tty_struct { - int magic; struct kref kref; + int index; struct device *dev; struct tty_driver *driver; + struct tty_port *port; const struct tty_operations *ops; - int index; - /* Protects ldisc changes: Lock tty not pty */ - struct mutex ldisc_mutex; struct tty_ldisc *ldisc; + struct ld_semaphore ldisc_sem; struct mutex atomic_write_lock; struct mutex legacy_mutex; - struct mutex termios_mutex; - spinlock_t ctrl_lock; - /* Termios values are protected by the termios mutex */ + struct mutex throttle_mutex; + struct rw_semaphore termios_rwsem; + struct mutex winsize_mutex; 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; /* termios 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 */ + unsigned int receive_room; + struct winsize winsize; + + struct { + spinlock_t lock; + bool stopped; + bool tco_stopped; + } flow; + + struct { + struct pid *pgrp; + struct pid *session; + spinlock_t lock; + unsigned char pktstatus; + bool packet; + } ctrl; + + bool hw_stopped; + bool closing; 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; + spinlock_t files_lock; + int write_cnt; + u8 *write_buf; -#define N_TTY_BUF_SIZE 4096 + struct list_head tty_files; - 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; -}; +} __randomize_layout; /* Each of a tty's open files has private_data pointing to tty_file_private */ struct tty_file_private { @@ -286,65 +249,107 @@ struct tty_file_private { struct list_head list; }; -/* tty magic number */ -#define TTY_MAGIC 0x5401 - -/* - * These bits are used in the flags field of the tty structure. +/** + * enum tty_struct_flags - TTY Struct Flags + * + * These bits are used in the :c:member:`tty_struct.flags` field. * * So that interrupts won't be able to mess up the queues, * copy_to_cooked must be atomic with respect to itself, as must * tty->write. Thus, you must use the inline functions set_bit() and * clear_bit() to make things atomic. + * + * @TTY_THROTTLED: + * Driver input is throttled. The ldisc should call + * :c:member:`tty_driver.unthrottle()` in order to resume reception when + * it is ready to process more data (at threshold min). + * + * @TTY_IO_ERROR: + * If set, causes all subsequent userspace read/write calls on the tty to + * fail, returning -%EIO. (May be no ldisc too.) + * + * @TTY_OTHER_CLOSED: + * Device is a pty and the other side has closed. + * + * @TTY_EXCLUSIVE: + * Exclusive open mode (a single opener). + * + * @TTY_DO_WRITE_WAKEUP: + * If set, causes the driver to call the + * :c:member:`tty_ldisc_ops.write_wakeup()` method in order to resume + * transmission when it can accept more data to transmit. + * + * @TTY_LDISC_OPEN: + * Indicates that a line discipline is open. For debugging purposes only. + * + * @TTY_PTY_LOCK: + * A flag private to pty code to implement %TIOCSPTLCK/%TIOCGPTLCK logic. + * + * @TTY_NO_WRITE_SPLIT: + * Prevent driver from splitting up writes into smaller chunks (preserve + * write boundaries to driver). + * + * @TTY_HUPPED: + * The TTY was hung up. This is set post :c:member:`tty_driver.hangup()`. + * + * @TTY_HUPPING: + * The TTY is in the process of hanging up to abort potential readers. + * + * @TTY_LDISC_CHANGING: + * Line discipline for this TTY is being changed. I/O should not block + * when this is set. Use tty_io_nonblock() to check. + * + * @TTY_LDISC_HALTED: + * Line discipline for this TTY was stopped. No work should be queued to + * this ldisc. */ -#define TTY_THROTTLED 0 /* Call unthrottle() at threshold min */ -#define TTY_IO_ERROR 1 /* Cause an I/O error (may be no ldisc too) */ -#define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */ -#define TTY_EXCLUSIVE 3 /* Exclusive open mode */ -#define TTY_DEBUG 4 /* Debugging */ -#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ -#define TTY_PUSH 6 /* n_tty private */ -#define TTY_CLOSING 7 /* ->close() in progress */ -#define TTY_LDISC 9 /* Line discipline attached */ -#define TTY_LDISC_CHANGING 10 /* Line discipline changing */ -#define TTY_LDISC_OPEN 11 /* Line discipline is open */ -#define TTY_PTY_LOCK 16 /* pty private */ -#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ -#define TTY_HUPPED 18 /* Post driver->hangup() */ -#define TTY_HUPPING 21 /* ->hangup() in progress */ -#define TTY_LDISC_HALTED 22 /* Line discipline is halted */ - -#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) - -/* Values for tty->flow_change */ -#define TTY_THROTTLE_SAFE 1 -#define TTY_UNTHROTTLE_SAFE 2 - -static inline void __tty_set_flow_change(struct tty_struct *tty, int val) +enum tty_struct_flags { + TTY_THROTTLED, + TTY_IO_ERROR, + TTY_OTHER_CLOSED, + TTY_EXCLUSIVE, + TTY_DO_WRITE_WAKEUP, + TTY_LDISC_OPEN, + TTY_PTY_LOCK, + TTY_NO_WRITE_SPLIT, + TTY_HUPPED, + TTY_HUPPING, + TTY_LDISC_CHANGING, + TTY_LDISC_HALTED, +}; + +static inline bool tty_io_nonblock(struct tty_struct *tty, struct file *file) { - tty->flow_change = val; + return file->f_flags & O_NONBLOCK || + test_bit(TTY_LDISC_CHANGING, &tty->flags); } -static inline void tty_set_flow_change(struct tty_struct *tty, int val) +static inline bool tty_io_error(struct tty_struct *tty) { - tty->flow_change = val; - smp_mb(); + return test_bit(TTY_IO_ERROR, &tty->flags); +} + +static inline bool tty_throttled(struct tty_struct *tty) +{ + return test_bit(TTY_THROTTLED, &tty->flags); } #ifdef CONFIG_TTY -extern void console_init(void); -extern void tty_kref_put(struct tty_struct *tty); -extern struct pid *tty_get_pgrp(struct tty_struct *tty); -extern void tty_vhangup_self(void); -extern void disassociate_ctty(int priv); -extern dev_t tty_devnum(struct tty_struct *tty); -extern void proc_clear_tty(struct task_struct *p); -extern struct tty_struct *get_current_tty(void); +void tty_kref_put(struct tty_struct *tty); +struct pid *tty_get_pgrp(struct tty_struct *tty); +void tty_vhangup_self(void); +void disassociate_ctty(int priv); +dev_t tty_devnum(struct tty_struct *tty); +void proc_clear_tty(struct task_struct *p); +struct tty_struct *get_current_tty(void); /* tty_io.c */ -extern int __init tty_init(void); +int __init tty_init(void); +const char *tty_name(const struct tty_struct *tty); +struct tty_struct *tty_kopen_exclusive(dev_t device); +struct tty_struct *tty_kopen_shared(dev_t device); +void tty_kclose(struct tty_struct *tty); +int tty_dev_name_to_number(const char *name, dev_t *number); #else -static inline void console_init(void) -{ } static inline void tty_kref_put(struct tty_struct *tty) { } static inline struct pid *tty_get_pgrp(struct tty_struct *tty) @@ -362,25 +367,31 @@ static inline struct tty_struct *get_current_tty(void) /* tty_io.c */ static inline int __init tty_init(void) { return 0; } +static inline const char *tty_name(const struct tty_struct *tty) +{ return "(none)"; } +static inline struct tty_struct *tty_kopen_exclusive(dev_t device) +{ return ERR_PTR(-ENODEV); } +static inline void tty_kclose(struct tty_struct *tty) +{ } +static inline int tty_dev_name_to_number(const char *name, dev_t *number) +{ return -ENOTSUPP; } #endif -extern void tty_write_flush(struct tty_struct *); - extern struct ktermios tty_std_termios; -extern int vcs_init(void); +int vcs_init(void); -extern struct class *tty_class; +extern const struct class tty_class; /** - * tty_kref_get - get a tty reference - * @tty: tty device + * tty_kref_get - get a tty reference + * @tty: tty device + * + * Returns: a new reference to a tty object * - * Return a new reference to a tty object. The caller must hold - * sufficient locks/counts to ensure that their existing reference cannot - * go away + * Locking: The caller must hold sufficient locks/counts to ensure that their + * existing reference cannot go away. */ - static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) { if (tty) @@ -388,310 +399,113 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) return tty; } -extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, - const char *routine); -extern char *tty_name(struct tty_struct *tty, char *buf); -extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); -extern int tty_check_change(struct tty_struct *tty); -extern void stop_tty(struct tty_struct *tty); -extern void start_tty(struct tty_struct *tty); -extern int tty_register_driver(struct tty_driver *driver); -extern int tty_unregister_driver(struct tty_driver *driver); -extern struct device *tty_register_device(struct tty_driver *driver, - unsigned index, struct device *dev); -extern struct device *tty_register_device_attr(struct tty_driver *driver, - unsigned index, struct device *device, - void *drvdata, - const struct attribute_group **attr_grp); -extern void tty_unregister_device(struct tty_driver *driver, unsigned index); -extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, - int buflen); -extern void tty_write_message(struct tty_struct *tty, char *msg); -extern int tty_put_char(struct tty_struct *tty, unsigned char c); -extern int tty_chars_in_buffer(struct tty_struct *tty); -extern int tty_write_room(struct tty_struct *tty); -extern void tty_driver_flush_buffer(struct tty_struct *tty); -extern void tty_throttle(struct tty_struct *tty); -extern void tty_unthrottle(struct tty_struct *tty); -extern int tty_throttle_safe(struct tty_struct *tty); -extern int tty_unthrottle_safe(struct tty_struct *tty); -extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); -extern void tty_driver_remove_tty(struct tty_driver *driver, - struct tty_struct *tty); -extern void tty_free_termios(struct tty_struct *tty); -extern int is_current_pgrp_orphaned(void); -extern int is_ignored(int sig); -extern int tty_signal(int sig, struct tty_struct *tty); -extern void tty_hangup(struct tty_struct *tty); -extern void tty_vhangup(struct tty_struct *tty); -extern void tty_vhangup_locked(struct tty_struct *tty); -extern void tty_unhangup(struct file *filp); -extern int tty_hung_up_p(struct file *filp); -extern void do_SAK(struct tty_struct *tty); -extern void __do_SAK(struct tty_struct *tty); -extern void no_tty(void); -extern void tty_flush_to_ldisc(struct tty_struct *tty); -extern void tty_buffer_free_all(struct tty_port *port); -extern void tty_buffer_flush(struct tty_struct *tty); -extern void tty_buffer_init(struct tty_port *port); -extern speed_t tty_termios_baud_rate(struct ktermios *termios); -extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); -extern void tty_termios_encode_baud_rate(struct ktermios *termios, - speed_t ibaud, speed_t obaud); -extern void tty_encode_baud_rate(struct tty_struct *tty, - speed_t ibaud, speed_t obaud); +const char *tty_driver_name(const struct tty_struct *tty); +void tty_wait_until_sent(struct tty_struct *tty, long timeout); +void stop_tty(struct tty_struct *tty); +void start_tty(struct tty_struct *tty); +void tty_write_message(struct tty_struct *tty, char *msg); +int tty_send_xchar(struct tty_struct *tty, u8 ch); +int tty_put_char(struct tty_struct *tty, u8 c); +unsigned int tty_chars_in_buffer(struct tty_struct *tty); +unsigned int tty_write_room(struct tty_struct *tty); +void tty_driver_flush_buffer(struct tty_struct *tty); +void tty_unthrottle(struct tty_struct *tty); +bool tty_throttle_safe(struct tty_struct *tty); +bool tty_unthrottle_safe(struct tty_struct *tty); +int tty_do_resize(struct tty_struct *tty, struct winsize *ws); +int tty_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount); +int tty_get_tiocm(struct tty_struct *tty); +int is_current_pgrp_orphaned(void); +void tty_hangup(struct tty_struct *tty); +void tty_vhangup(struct tty_struct *tty); +int tty_hung_up_p(struct file *filp); +void do_SAK(struct tty_struct *tty); +void __do_SAK(struct tty_struct *tty); +void no_tty(void); +speed_t tty_termios_baud_rate(const struct ktermios *termios); +void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, + speed_t obaud); +void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, + speed_t obaud); /** - * tty_get_baud_rate - get tty bit rates - * @tty: tty to query + * tty_get_baud_rate - get tty bit rates + * @tty: tty to query * - * Returns the baud rate as an integer for this terminal. The - * termios lock must be held by the caller and the terminal bit - * flags may be updated. + * Returns: the baud rate as an integer for this terminal * - * Locking: none + * Locking: The termios lock must be held by the caller. */ -static inline speed_t tty_get_baud_rate(struct tty_struct *tty) +static inline speed_t tty_get_baud_rate(const struct tty_struct *tty) { return tty_termios_baud_rate(&tty->termios); } -extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); -extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b); -extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); - -extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); -extern void tty_ldisc_deref(struct tty_ldisc *); -extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); -extern void tty_ldisc_hangup(struct tty_struct *tty); -extern const struct file_operations tty_ldiscs_proc_fops; - -extern void tty_wakeup(struct tty_struct *tty); -extern void tty_ldisc_flush(struct tty_struct *tty); - -extern long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); -extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg); -extern void tty_default_fops(struct file_operations *fops); -extern struct tty_struct *alloc_tty_struct(void); -extern int tty_alloc_file(struct file *file); -extern void tty_add_file(struct tty_struct *tty, struct file *file); -extern void tty_free_file(struct file *file); -extern void free_tty_struct(struct tty_struct *tty); -extern void initialize_tty_struct(struct tty_struct *tty, - struct tty_driver *driver, int idx); -extern void deinitialize_tty_struct(struct tty_struct *tty); -extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); -extern int tty_release(struct inode *inode, struct file *filp); -extern int tty_init_termios(struct tty_struct *tty); -extern int tty_standard_install(struct tty_driver *driver, - struct tty_struct *tty); +unsigned char tty_get_char_size(unsigned int cflag); +unsigned char tty_get_frame_size(unsigned int cflag); -extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty); -extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty); +void tty_termios_copy_hw(struct ktermios *new, const struct ktermios *old); +bool tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b); +int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); -extern struct mutex tty_mutex; -extern spinlock_t tty_files_lock; - -extern void tty_write_unlock(struct tty_struct *tty); -extern int tty_write_lock(struct tty_struct *tty, int ndelay); -#define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock)) - -extern void tty_port_init(struct tty_port *port); -extern void tty_port_link_device(struct tty_port *port, - struct tty_driver *driver, unsigned index); -extern struct device *tty_port_register_device(struct tty_port *port, - struct tty_driver *driver, unsigned index, - struct device *device); -extern 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); -extern int tty_port_alloc_xmit_buf(struct tty_port *port); -extern void tty_port_free_xmit_buf(struct tty_port *port); -extern void tty_port_destroy(struct tty_port *port); -extern void tty_port_put(struct tty_port *port); - -static inline struct tty_port *tty_port_get(struct tty_port *port) -{ - if (port) - kref_get(&port->kref); - return port; -} - -/* If the cts flow control is enabled, return true. */ -static inline bool tty_port_cts_enabled(struct tty_port *port) -{ - return port->flags & ASYNC_CTS_FLOW; -} - -extern struct tty_struct *tty_port_tty_get(struct tty_port *port); -extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); -extern int tty_port_carrier_raised(struct tty_port *port); -extern void tty_port_raise_dtr_rts(struct tty_port *port); -extern void tty_port_lower_dtr_rts(struct tty_port *port); -extern void tty_port_hangup(struct tty_port *port); -extern void tty_port_tty_hangup(struct tty_port *port, bool check_clocal); -extern void tty_port_tty_wakeup(struct tty_port *port); -extern int tty_port_block_til_ready(struct tty_port *port, - struct tty_struct *tty, struct file *filp); -extern int tty_port_close_start(struct tty_port *port, - struct tty_struct *tty, struct file *filp); -extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty); -extern void tty_port_close(struct tty_port *port, - struct tty_struct *tty, struct file *filp); -extern int tty_port_install(struct tty_port *port, struct tty_driver *driver, - struct tty_struct *tty); -extern int tty_port_open(struct tty_port *port, - struct tty_struct *tty, struct file *filp); -static inline int tty_port_users(struct tty_port *port) -{ - return port->count + port->blocked_open; -} +void tty_wakeup(struct tty_struct *tty); -extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); -extern int tty_unregister_ldisc(int disc); -extern int tty_set_ldisc(struct tty_struct *tty, int ldisc); -extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); -extern void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty); -extern void tty_ldisc_init(struct tty_struct *tty); -extern void tty_ldisc_deinit(struct tty_struct *tty); -extern void tty_ldisc_begin(void); +int tty_mode_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); +int tty_perform_flush(struct tty_struct *tty, unsigned long arg); +struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); +void tty_release_struct(struct tty_struct *tty, int idx); +void tty_init_termios(struct tty_struct *tty); +void tty_save_termios(struct tty_struct *tty); +int tty_standard_install(struct tty_driver *driver, + struct tty_struct *tty); +extern struct mutex tty_mutex; /* n_tty.c */ -extern struct tty_ldisc_ops tty_ldisc_N_TTY; -extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops); +void n_tty_inherit_ops(struct tty_ldisc_ops *ops); +#ifdef CONFIG_TTY +void __init n_tty_init(void); +#else +static inline void n_tty_init(void) { } +#endif /* tty_audit.c */ #ifdef CONFIG_AUDIT -extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, - size_t size, unsigned icanon); -extern void tty_audit_exit(void); -extern void tty_audit_fork(struct signal_struct *sig); -extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); -extern void tty_audit_push(struct tty_struct *tty); -extern int tty_audit_push_current(void); +void tty_audit_exit(void); +void tty_audit_fork(struct signal_struct *sig); +int tty_audit_push(void); #else -static inline void tty_audit_add_data(struct tty_struct *tty, - unsigned char *data, size_t size, unsigned icanon) -{ -} -static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch) -{ -} static inline void tty_audit_exit(void) { } static inline void tty_audit_fork(struct signal_struct *sig) { } -static inline void tty_audit_push(struct tty_struct *tty) -{ -} -static inline int tty_audit_push_current(void) +static inline int tty_audit_push(void) { return 0; } #endif /* tty_ioctl.c */ -extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); -extern long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); - -/* serial.c */ - -extern void serial_console_init(void); - -/* pcxx.c */ - -extern int pcxe_open(struct tty_struct *tty, struct file *filp); +int n_tty_ioctl_helper(struct tty_struct *tty, unsigned int cmd, + unsigned long arg); /* vt.c */ -extern int vt_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); +int vt_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); -extern long vt_compat_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); +long vt_compat_ioctl(struct tty_struct *tty, unsigned int cmd, + unsigned long arg); /* tty_mutex.c */ /* functions for preparation of BKL removal */ -extern void __lockfunc tty_lock(struct tty_struct *tty); -extern void __lockfunc tty_unlock(struct tty_struct *tty); -extern void __lockfunc tty_lock_pair(struct tty_struct *tty, - struct tty_struct *tty2); -extern void __lockfunc tty_unlock_pair(struct tty_struct *tty, - struct tty_struct *tty2); - -/* - * this shall be called only from where BTM is held (like close) - * - * We need this to ensure nobody waits for us to finish while we are waiting. - * Without this we were encountering system stalls. - * - * This should be indeed removed with BTM removal later. - * - * Locking: BTM required. Nobody is allowed to hold port->mutex. - */ -static inline void tty_wait_until_sent_from_close(struct tty_struct *tty, - long timeout) -{ - tty_unlock(tty); /* tty->ops->close holds the BTM, drop it while waiting */ - tty_wait_until_sent(tty, timeout); - tty_lock(tty); -} - -/* - * wait_event_interruptible_tty -- wait for a condition with the tty lock held - * - * The condition we are waiting for might take a long time to - * become true, or might depend on another thread taking the - * BTM. In either case, we need to drop the BTM to guarantee - * forward progress. This is a leftover from the conversion - * from the BKL and should eventually get removed as the BTM - * falls out of use. - * - * Do not use in new code. - */ -#define wait_event_interruptible_tty(tty, wq, condition) \ -({ \ - int __ret = 0; \ - if (!(condition)) { \ - __wait_event_interruptible_tty(tty, wq, condition, __ret); \ - } \ - __ret; \ -}) - -#define __wait_event_interruptible_tty(tty, wq, condition, ret) \ -do { \ - DEFINE_WAIT(__wait); \ - \ - for (;;) { \ - prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ - if (condition) \ - break; \ - if (!signal_pending(current)) { \ - tty_unlock(tty); \ - schedule(); \ - tty_lock(tty); \ - continue; \ - } \ - ret = -ERESTARTSYS; \ - break; \ - } \ - finish_wait(&wq, &__wait); \ -} while (0) - -#ifdef CONFIG_PROC_FS -extern void proc_tty_register_driver(struct tty_driver *); -extern void proc_tty_unregister_driver(struct tty_driver *); -#else -static inline void proc_tty_register_driver(struct tty_driver *d) {} -static inline void proc_tty_unregister_driver(struct tty_driver *d) {} -#endif +void tty_lock(struct tty_struct *tty); +int tty_lock_interruptible(struct tty_struct *tty); +void tty_unlock(struct tty_struct *tty); +void tty_lock_slave(struct tty_struct *tty); +void tty_unlock_slave(struct tty_struct *tty); +void tty_set_lock_subclass(struct tty_struct *tty); #endif |
