diff options
Diffstat (limited to 'include/linux/tty.h')
| -rw-r--r-- | include/linux/tty.h | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/include/linux/tty.h b/include/linux/tty.h index 01ac30efd6a6..64f864651d86 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
| 11 | #include <linux/tty_flags.h> | 11 | #include <linux/tty_flags.h> |
| 12 | #include <uapi/linux/tty.h> | 12 | #include <uapi/linux/tty.h> |
| 13 | #include <linux/rwsem.h> | ||
| 14 | #include <linux/llist.h> | ||
| 13 | 15 | ||
| 14 | 16 | ||
| 15 | 17 | ||
| @@ -29,9 +31,10 @@ | |||
| 29 | #define __DISABLED_CHAR '\0' | 31 | #define __DISABLED_CHAR '\0' |
| 30 | 32 | ||
| 31 | struct tty_buffer { | 33 | struct tty_buffer { |
| 32 | struct tty_buffer *next; | 34 | union { |
| 33 | char *char_buf_ptr; | 35 | struct tty_buffer *next; |
| 34 | unsigned char *flag_buf_ptr; | 36 | struct llist_node free; |
| 37 | }; | ||
| 35 | int used; | 38 | int used; |
| 36 | int size; | 39 | int size; |
| 37 | int commit; | 40 | int commit; |
| @@ -40,25 +43,25 @@ struct tty_buffer { | |||
| 40 | unsigned long data[0]; | 43 | unsigned long data[0]; |
| 41 | }; | 44 | }; |
| 42 | 45 | ||
| 43 | /* | 46 | static inline unsigned char *char_buf_ptr(struct tty_buffer *b, int ofs) |
| 44 | * We default to dicing tty buffer allocations to this many characters | 47 | { |
| 45 | * in order to avoid multiple page allocations. We know the size of | 48 | return ((unsigned char *)b->data) + ofs; |
| 46 | * tty_buffer itself but it must also be taken into account that the | 49 | } |
| 47 | * the buffer is 256 byte aligned. See tty_buffer_find for the allocation | ||
| 48 | * logic this must match | ||
| 49 | */ | ||
| 50 | |||
| 51 | #define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) | ||
| 52 | 50 | ||
| 51 | static inline char *flag_buf_ptr(struct tty_buffer *b, int ofs) | ||
| 52 | { | ||
| 53 | return (char *)char_buf_ptr(b, ofs) + b->size; | ||
| 54 | } | ||
| 53 | 55 | ||
| 54 | struct tty_bufhead { | 56 | struct tty_bufhead { |
| 55 | struct work_struct work; | ||
| 56 | spinlock_t lock; | ||
| 57 | struct tty_buffer *head; /* Queue head */ | 57 | struct tty_buffer *head; /* Queue head */ |
| 58 | struct work_struct work; | ||
| 59 | struct mutex lock; | ||
| 60 | atomic_t priority; | ||
| 61 | struct tty_buffer sentinel; | ||
| 62 | struct llist_head free; /* Free queue head */ | ||
| 63 | atomic_t memory_used; /* In-use buffers excluding free list */ | ||
| 58 | struct tty_buffer *tail; /* Active buffer */ | 64 | struct tty_buffer *tail; /* Active buffer */ |
| 59 | struct tty_buffer *free; /* Free queue head */ | ||
| 60 | int memory_used; /* Buffer space used excluding | ||
| 61 | free queue */ | ||
| 62 | }; | 65 | }; |
| 63 | /* | 66 | /* |
| 64 | * When a break, frame error, or parity error happens, these codes are | 67 | * When a break, frame error, or parity error happens, these codes are |
| @@ -199,9 +202,6 @@ struct tty_port { | |||
| 199 | wait_queue_head_t close_wait; /* Close waiters */ | 202 | wait_queue_head_t close_wait; /* Close waiters */ |
| 200 | wait_queue_head_t delta_msr_wait; /* Modem status change */ | 203 | wait_queue_head_t delta_msr_wait; /* Modem status change */ |
| 201 | unsigned long flags; /* TTY flags ASY_*/ | 204 | unsigned long flags; /* TTY flags ASY_*/ |
| 202 | unsigned long iflags; /* TTYP_ internal flags */ | ||
| 203 | #define TTYP_FLUSHING 1 /* Flushing to ldisc in progress */ | ||
| 204 | #define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */ | ||
| 205 | unsigned char console:1, /* port is a console */ | 205 | unsigned char console:1, /* port is a console */ |
| 206 | low_latency:1; /* direct buffer flush */ | 206 | low_latency:1; /* direct buffer flush */ |
| 207 | struct mutex mutex; /* Locking */ | 207 | struct mutex mutex; /* Locking */ |
| @@ -238,14 +238,16 @@ struct tty_struct { | |||
| 238 | int index; | 238 | int index; |
| 239 | 239 | ||
| 240 | /* Protects ldisc changes: Lock tty not pty */ | 240 | /* Protects ldisc changes: Lock tty not pty */ |
| 241 | struct mutex ldisc_mutex; | 241 | struct ld_semaphore ldisc_sem; |
| 242 | struct tty_ldisc *ldisc; | 242 | struct tty_ldisc *ldisc; |
| 243 | 243 | ||
| 244 | struct mutex atomic_write_lock; | 244 | struct mutex atomic_write_lock; |
| 245 | struct mutex legacy_mutex; | 245 | struct mutex legacy_mutex; |
| 246 | struct mutex termios_mutex; | 246 | struct mutex throttle_mutex; |
| 247 | struct rw_semaphore termios_rwsem; | ||
| 248 | struct mutex winsize_mutex; | ||
| 247 | spinlock_t ctrl_lock; | 249 | spinlock_t ctrl_lock; |
| 248 | /* Termios values are protected by the termios mutex */ | 250 | /* Termios values are protected by the termios rwsem */ |
| 249 | struct ktermios termios, termios_locked; | 251 | struct ktermios termios, termios_locked; |
| 250 | struct termiox *termiox; /* May be NULL for unsupported */ | 252 | struct termiox *termiox; /* May be NULL for unsupported */ |
| 251 | char name[64]; | 253 | char name[64]; |
| @@ -253,7 +255,7 @@ struct tty_struct { | |||
| 253 | struct pid *session; | 255 | struct pid *session; |
| 254 | unsigned long flags; | 256 | unsigned long flags; |
| 255 | int count; | 257 | int count; |
| 256 | struct winsize winsize; /* termios mutex */ | 258 | struct winsize winsize; /* winsize_mutex */ |
| 257 | unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1; | 259 | unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1; |
| 258 | unsigned char ctrl_status; /* ctrl_lock */ | 260 | unsigned char ctrl_status; /* ctrl_lock */ |
| 259 | unsigned int receive_room; /* Bytes free for queue */ | 261 | unsigned int receive_room; /* Bytes free for queue */ |
| @@ -303,10 +305,7 @@ struct tty_file_private { | |||
| 303 | #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ | 305 | #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ |
| 304 | #define TTY_DEBUG 4 /* Debugging */ | 306 | #define TTY_DEBUG 4 /* Debugging */ |
| 305 | #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ | 307 | #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ |
| 306 | #define TTY_PUSH 6 /* n_tty private */ | ||
| 307 | #define TTY_CLOSING 7 /* ->close() in progress */ | 308 | #define TTY_CLOSING 7 /* ->close() in progress */ |
| 308 | #define TTY_LDISC 9 /* Line discipline attached */ | ||
| 309 | #define TTY_LDISC_CHANGING 10 /* Line discipline changing */ | ||
| 310 | #define TTY_LDISC_OPEN 11 /* Line discipline is open */ | 309 | #define TTY_LDISC_OPEN 11 /* Line discipline is open */ |
| 311 | #define TTY_PTY_LOCK 16 /* pty private */ | 310 | #define TTY_PTY_LOCK 16 /* pty private */ |
| 312 | #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ | 311 | #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ |
| @@ -559,6 +558,19 @@ extern void tty_ldisc_init(struct tty_struct *tty); | |||
| 559 | extern void tty_ldisc_deinit(struct tty_struct *tty); | 558 | extern void tty_ldisc_deinit(struct tty_struct *tty); |
| 560 | extern void tty_ldisc_begin(void); | 559 | extern void tty_ldisc_begin(void); |
| 561 | 560 | ||
| 561 | static inline int tty_ldisc_receive_buf(struct tty_ldisc *ld, unsigned char *p, | ||
| 562 | char *f, int count) | ||
| 563 | { | ||
| 564 | if (ld->ops->receive_buf2) | ||
| 565 | count = ld->ops->receive_buf2(ld->tty, p, f, count); | ||
| 566 | else { | ||
| 567 | count = min_t(int, count, ld->tty->receive_room); | ||
| 568 | if (count) | ||
| 569 | ld->ops->receive_buf(ld->tty, p, f, count); | ||
| 570 | } | ||
| 571 | return count; | ||
| 572 | } | ||
| 573 | |||
| 562 | 574 | ||
| 563 | /* n_tty.c */ | 575 | /* n_tty.c */ |
| 564 | extern struct tty_ldisc_ops tty_ldisc_N_TTY; | 576 | extern struct tty_ldisc_ops tty_ldisc_N_TTY; |
