1#include <linux/tty.h> 2#include <linux/module.h> 3#include <linux/kallsyms.h> 4#include <linux/semaphore.h> 5#include <linux/sched.h> 6 7/* 8 * Nested tty locks are necessary for releasing pty pairs. 9 * The stable lock order is master pty first, then slave pty. 10 */ 11 12/* Legacy tty mutex glue */ 13 14enum { 15 TTY_MUTEX_NORMAL, 16 TTY_MUTEX_SLAVE, 17}; 18 19/* 20 * Getting the big tty mutex. 21 */ 22 23void __lockfunc tty_lock(struct tty_struct *tty) 24{ 25 if (tty->magic != TTY_MAGIC) { 26 pr_err("L Bad %p\n", tty); 27 WARN_ON(1); 28 return; 29 } 30 tty_kref_get(tty); 31 mutex_lock(&tty->legacy_mutex); 32} 33EXPORT_SYMBOL(tty_lock); 34 35int tty_lock_interruptible(struct tty_struct *tty) 36{ 37 int ret; 38 39 if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty)) 40 return -EIO; 41 tty_kref_get(tty); 42 ret = mutex_lock_interruptible(&tty->legacy_mutex); 43 if (ret) 44 tty_kref_put(tty); 45 return ret; 46} 47 48void __lockfunc tty_unlock(struct tty_struct *tty) 49{ 50 if (tty->magic != TTY_MAGIC) { 51 pr_err("U Bad %p\n", tty); 52 WARN_ON(1); 53 return; 54 } 55 mutex_unlock(&tty->legacy_mutex); 56 tty_kref_put(tty); 57} 58EXPORT_SYMBOL(tty_unlock); 59 60void __lockfunc tty_lock_slave(struct tty_struct *tty) 61{ 62 if (tty && tty != tty->link) 63 tty_lock(tty); 64} 65 66void __lockfunc tty_unlock_slave(struct tty_struct *tty) 67{ 68 if (tty && tty != tty->link) 69 tty_unlock(tty); 70} 71 72void tty_set_lock_subclass(struct tty_struct *tty) 73{ 74 lockdep_set_subclass(&tty->legacy_mutex, TTY_MUTEX_SLAVE); 75} 76