aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 03:54:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:47 -0400
commitf34d7a5b7010b82fe97da95496b9971435530062 (patch)
tree87e2abec1e33ed4fe5e63ee2fd000bc2ad745e57 /drivers/char/tty_io.c
parent251b8dd7eee30fda089a1dc088abf4fc9a0dee9c (diff)
tty: The big operations rework
- Operations are now a shared const function block as with most other Linux objects - Introduce wrappers for some optional functions to get consistent behaviour - Wrap put_char which used to be patched by the tty layer - Document which functions are needed/optional - Make put_char report success/fail - Cache the driver->ops pointer in the tty as tty->ops - Remove various surplus lock calls we no longer need - Remove proc_write method as noted by Alexey Dobriyan - Introduce some missing sanity checks where certain driver/ldisc combinations would oops as they didn't check needed methods were present [akpm@linux-foundation.org: fix fs/compat_ioctl.c build] [akpm@linux-foundation.org: fix isicom] [akpm@linux-foundation.org: fix arch/ia64/hp/sim/simserial.c build] [akpm@linux-foundation.org: fix kgdb] Signed-off-by: Alan Cox <alan@redhat.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Cc: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c174
1 files changed, 72 insertions, 102 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index b1692afd797e..f69fb8d7a680 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1108,8 +1108,8 @@ restart:
1108 a reference to the old ldisc. If we ended up flipping back 1108 a reference to the old ldisc. If we ended up flipping back
1109 to the existing ldisc we have two references to it */ 1109 to the existing ldisc we have two references to it */
1110 1110
1111 if (tty->ldisc.num != o_ldisc.num && tty->driver->set_ldisc) 1111 if (tty->ldisc.num != o_ldisc.num && tty->ops->set_ldisc)
1112 tty->driver->set_ldisc(tty); 1112 tty->ops->set_ldisc(tty);
1113 1113
1114 tty_ldisc_put(o_ldisc.num); 1114 tty_ldisc_put(o_ldisc.num);
1115 1115
@@ -1181,9 +1181,8 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
1181 if (*str == '\0') 1181 if (*str == '\0')
1182 str = NULL; 1182 str = NULL;
1183 1183
1184 if (tty_line >= 0 && tty_line <= p->num && p->poll_init && 1184 if (tty_line >= 0 && tty_line <= p->num && p->ops &&
1185 !p->poll_init(p, tty_line, str)) { 1185 p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) {
1186
1187 res = p; 1186 res = p;
1188 *line = tty_line; 1187 *line = tty_line;
1189 break; 1188 break;
@@ -1452,8 +1451,7 @@ static void do_tty_hangup(struct work_struct *work)
1452 /* We may have no line discipline at this point */ 1451 /* We may have no line discipline at this point */
1453 if (ld->flush_buffer) 1452 if (ld->flush_buffer)
1454 ld->flush_buffer(tty); 1453 ld->flush_buffer(tty);
1455 if (tty->driver->flush_buffer) 1454 tty_driver_flush_buffer(tty);
1456 tty->driver->flush_buffer(tty);
1457 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && 1455 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
1458 ld->write_wakeup) 1456 ld->write_wakeup)
1459 ld->write_wakeup(tty); 1457 ld->write_wakeup(tty);
@@ -1516,11 +1514,11 @@ static void do_tty_hangup(struct work_struct *work)
1516 * So we just call close() the right number of times. 1514 * So we just call close() the right number of times.
1517 */ 1515 */
1518 if (cons_filp) { 1516 if (cons_filp) {
1519 if (tty->driver->close) 1517 if (tty->ops->close)
1520 for (n = 0; n < closecount; n++) 1518 for (n = 0; n < closecount; n++)
1521 tty->driver->close(tty, cons_filp); 1519 tty->ops->close(tty, cons_filp);
1522 } else if (tty->driver->hangup) 1520 } else if (tty->ops->hangup)
1523 (tty->driver->hangup)(tty); 1521 (tty->ops->hangup)(tty);
1524 /* 1522 /*
1525 * We don't want to have driver/ldisc interactions beyond 1523 * We don't want to have driver/ldisc interactions beyond
1526 * the ones we did here. The driver layer expects no 1524 * the ones we did here. The driver layer expects no
@@ -1752,8 +1750,8 @@ void stop_tty(struct tty_struct *tty)
1752 wake_up_interruptible(&tty->link->read_wait); 1750 wake_up_interruptible(&tty->link->read_wait);
1753 } 1751 }
1754 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 1752 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1755 if (tty->driver->stop) 1753 if (tty->ops->stop)
1756 (tty->driver->stop)(tty); 1754 (tty->ops->stop)(tty);
1757} 1755}
1758 1756
1759EXPORT_SYMBOL(stop_tty); 1757EXPORT_SYMBOL(stop_tty);
@@ -1786,8 +1784,8 @@ void start_tty(struct tty_struct *tty)
1786 wake_up_interruptible(&tty->link->read_wait); 1784 wake_up_interruptible(&tty->link->read_wait);
1787 } 1785 }
1788 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 1786 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1789 if (tty->driver->start) 1787 if (tty->ops->start)
1790 (tty->driver->start)(tty); 1788 (tty->ops->start)(tty);
1791 /* If we have a running line discipline it may need kicking */ 1789 /* If we have a running line discipline it may need kicking */
1792 tty_wakeup(tty); 1790 tty_wakeup(tty);
1793} 1791}
@@ -1972,10 +1970,13 @@ static ssize_t tty_write(struct file *file, const char __user *buf,
1972 tty = (struct tty_struct *)file->private_data; 1970 tty = (struct tty_struct *)file->private_data;
1973 if (tty_paranoia_check(tty, inode, "tty_write")) 1971 if (tty_paranoia_check(tty, inode, "tty_write"))
1974 return -EIO; 1972 return -EIO;
1975 if (!tty || !tty->driver->write || 1973 if (!tty || !tty->ops->write ||
1976 (test_bit(TTY_IO_ERROR, &tty->flags))) 1974 (test_bit(TTY_IO_ERROR, &tty->flags)))
1977 return -EIO; 1975 return -EIO;
1978 1976 /* Short term debug to catch buggy drivers */
1977 if (tty->ops->write_room == NULL)
1978 printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
1979 tty->driver->name);
1979 ld = tty_ldisc_ref_wait(tty); 1980 ld = tty_ldisc_ref_wait(tty);
1980 if (!ld->write) 1981 if (!ld->write)
1981 ret = -EIO; 1982 ret = -EIO;
@@ -2122,6 +2123,7 @@ static int init_dev(struct tty_driver *driver, int idx,
2122 goto fail_no_mem; 2123 goto fail_no_mem;
2123 initialize_tty_struct(tty); 2124 initialize_tty_struct(tty);
2124 tty->driver = driver; 2125 tty->driver = driver;
2126 tty->ops = driver->ops;
2125 tty->index = idx; 2127 tty->index = idx;
2126 tty_line_name(driver, idx, tty->name); 2128 tty_line_name(driver, idx, tty->name);
2127 2129
@@ -2152,6 +2154,7 @@ static int init_dev(struct tty_driver *driver, int idx,
2152 goto free_mem_out; 2154 goto free_mem_out;
2153 initialize_tty_struct(o_tty); 2155 initialize_tty_struct(o_tty);
2154 o_tty->driver = driver->other; 2156 o_tty->driver = driver->other;
2157 o_tty->ops = driver->ops;
2155 o_tty->index = idx; 2158 o_tty->index = idx;
2156 tty_line_name(driver->other, idx, o_tty->name); 2159 tty_line_name(driver->other, idx, o_tty->name);
2157 2160
@@ -2456,8 +2459,8 @@ static void release_dev(struct file *filp)
2456 } 2459 }
2457 } 2460 }
2458#endif 2461#endif
2459 if (tty->driver->close) 2462 if (tty->ops->close)
2460 tty->driver->close(tty, filp); 2463 tty->ops->close(tty, filp);
2461 2464
2462 /* 2465 /*
2463 * Sanity check: if tty->count is going to zero, there shouldn't be 2466 * Sanity check: if tty->count is going to zero, there shouldn't be
@@ -2740,8 +2743,8 @@ got_driver:
2740 printk(KERN_DEBUG "opening %s...", tty->name); 2743 printk(KERN_DEBUG "opening %s...", tty->name);
2741#endif 2744#endif
2742 if (!retval) { 2745 if (!retval) {
2743 if (tty->driver->open) 2746 if (tty->ops->open)
2744 retval = tty->driver->open(tty, filp); 2747 retval = tty->ops->open(tty, filp);
2745 else 2748 else
2746 retval = -ENODEV; 2749 retval = -ENODEV;
2747 } 2750 }
@@ -2840,7 +2843,7 @@ static int ptmx_open(struct inode *inode, struct file *filp)
2840 goto out1; 2843 goto out1;
2841 2844
2842 check_tty_count(tty, "tty_open"); 2845 check_tty_count(tty, "tty_open");
2843 retval = ptm_driver->open(tty, filp); 2846 retval = ptm_driver->ops->open(tty, filp);
2844 if (!retval) 2847 if (!retval)
2845 return 0; 2848 return 0;
2846out1: 2849out1:
@@ -3336,25 +3339,20 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
3336 3339
3337static int send_break(struct tty_struct *tty, unsigned int duration) 3340static int send_break(struct tty_struct *tty, unsigned int duration)
3338{ 3341{
3339 int retval = -EINTR;
3340
3341 lock_kernel();
3342 if (tty_write_lock(tty, 0) < 0) 3342 if (tty_write_lock(tty, 0) < 0)
3343 goto out; 3343 return -EINTR;
3344 tty->driver->break_ctl(tty, -1); 3344 tty->ops->break_ctl(tty, -1);
3345 if (!signal_pending(current)) 3345 if (!signal_pending(current))
3346 msleep_interruptible(duration); 3346 msleep_interruptible(duration);
3347 tty->driver->break_ctl(tty, 0); 3347 tty->ops->break_ctl(tty, 0);
3348 tty_write_unlock(tty); 3348 tty_write_unlock(tty);
3349 if (!signal_pending(current)) 3349 if (!signal_pending(current))
3350 retval = 0; 3350 return -EINTR;
3351out: 3351 return 0;
3352 unlock_kernel();
3353 return retval;
3354} 3352}
3355 3353
3356/** 3354/**
3357 * tiocmget - get modem status 3355 * tty_tiocmget - get modem status
3358 * @tty: tty device 3356 * @tty: tty device
3359 * @file: user file pointer 3357 * @file: user file pointer
3360 * @p: pointer to result 3358 * @p: pointer to result
@@ -3369,10 +3367,8 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p
3369{ 3367{
3370 int retval = -EINVAL; 3368 int retval = -EINVAL;
3371 3369
3372 if (tty->driver->tiocmget) { 3370 if (tty->ops->tiocmget) {
3373 lock_kernel(); 3371 retval = tty->ops->tiocmget(tty, file);
3374 retval = tty->driver->tiocmget(tty, file);
3375 unlock_kernel();
3376 3372
3377 if (retval >= 0) 3373 if (retval >= 0)
3378 retval = put_user(retval, p); 3374 retval = put_user(retval, p);
@@ -3381,7 +3377,7 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p
3381} 3377}
3382 3378
3383/** 3379/**
3384 * tiocmset - set modem status 3380 * tty_tiocmset - set modem status
3385 * @tty: tty device 3381 * @tty: tty device
3386 * @file: user file pointer 3382 * @file: user file pointer
3387 * @cmd: command - clear bits, set bits or set all 3383 * @cmd: command - clear bits, set bits or set all
@@ -3398,7 +3394,7 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
3398{ 3394{
3399 int retval = -EINVAL; 3395 int retval = -EINVAL;
3400 3396
3401 if (tty->driver->tiocmset) { 3397 if (tty->ops->tiocmset) {
3402 unsigned int set, clear, val; 3398 unsigned int set, clear, val;
3403 3399
3404 retval = get_user(val, p); 3400 retval = get_user(val, p);
@@ -3422,9 +3418,7 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
3422 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 3418 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
3423 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 3419 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
3424 3420
3425 lock_kernel(); 3421 retval = tty->ops->tiocmset(tty, file, set, clear);
3426 retval = tty->driver->tiocmset(tty, file, set, clear);
3427 unlock_kernel();
3428 } 3422 }
3429 return retval; 3423 return retval;
3430} 3424}
@@ -3455,23 +3449,25 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3455 3449
3456 retval = -EINVAL; 3450 retval = -EINVAL;
3457 3451
3458 if (!tty->driver->break_ctl) { 3452 if (!tty->ops->break_ctl) {
3459 switch (cmd) { 3453 switch (cmd) {
3460 case TIOCSBRK: 3454 case TIOCSBRK:
3461 case TIOCCBRK: 3455 case TIOCCBRK:
3462 if (tty->driver->ioctl) 3456 if (tty->ops->ioctl)
3463 retval = tty->driver->ioctl(tty, file, cmd, arg); 3457 retval = tty->ops->ioctl(tty, file, cmd, arg);
3458 if (retval != -EINVAL && retval != -ENOIOCTLCMD)
3459 printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
3464 return retval; 3460 return retval;
3465 3461
3466 /* These two ioctl's always return success; even if */ 3462 /* These two ioctl's always return success; even if */
3467 /* the driver doesn't support them. */ 3463 /* the driver doesn't support them. */
3468 case TCSBRK: 3464 case TCSBRK:
3469 case TCSBRKP: 3465 case TCSBRKP:
3470 if (!tty->driver->ioctl) 3466 if (!tty->ops->ioctl)
3471 return 0; 3467 return 0;
3472 lock_kernel(); 3468 retval = tty->ops->ioctl(tty, file, cmd, arg);
3473 retval = tty->driver->ioctl(tty, file, cmd, arg); 3469 if (retval != -EINVAL && retval != -ENOIOCTLCMD)
3474 unlock_kernel(); 3470 printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
3475 if (retval == -ENOIOCTLCMD) 3471 if (retval == -ENOIOCTLCMD)
3476 retval = 0; 3472 retval = 0;
3477 return retval; 3473 return retval;
@@ -3491,9 +3487,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3491 if (retval) 3487 if (retval)
3492 return retval; 3488 return retval;
3493 if (cmd != TIOCCBRK) { 3489 if (cmd != TIOCCBRK) {
3494 lock_kernel();
3495 tty_wait_until_sent(tty, 0); 3490 tty_wait_until_sent(tty, 0);
3496 unlock_kernel();
3497 if (signal_pending(current)) 3491 if (signal_pending(current))
3498 return -EINTR; 3492 return -EINTR;
3499 } 3493 }
@@ -3531,7 +3525,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3531 case TIOCGSID: 3525 case TIOCGSID:
3532 return tiocgsid(tty, real_tty, p); 3526 return tiocgsid(tty, real_tty, p);
3533 case TIOCGETD: 3527 case TIOCGETD:
3534 /* FIXME: check this is ok */
3535 return put_user(tty->ldisc.num, (int __user *)p); 3528 return put_user(tty->ldisc.num, (int __user *)p);
3536 case TIOCSETD: 3529 case TIOCSETD:
3537 return tiocsetd(tty, p); 3530 return tiocsetd(tty, p);
@@ -3543,15 +3536,13 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3543 * Break handling 3536 * Break handling
3544 */ 3537 */
3545 case TIOCSBRK: /* Turn break on, unconditionally */ 3538 case TIOCSBRK: /* Turn break on, unconditionally */
3546 lock_kernel(); 3539 if (tty->ops->break_ctl)
3547 tty->driver->break_ctl(tty, -1); 3540 tty->ops->break_ctl(tty, -1);
3548 unlock_kernel();
3549 return 0; 3541 return 0;
3550 3542
3551 case TIOCCBRK: /* Turn break off, unconditionally */ 3543 case TIOCCBRK: /* Turn break off, unconditionally */
3552 lock_kernel(); 3544 if (tty->ops->break_ctl)
3553 tty->driver->break_ctl(tty, 0); 3545 tty->ops->break_ctl(tty, 0);
3554 unlock_kernel();
3555 return 0; 3546 return 0;
3556 case TCSBRK: /* SVID version: non-zero arg --> no break */ 3547 case TCSBRK: /* SVID version: non-zero arg --> no break */
3557 /* non-zero arg means wait for all output data 3548 /* non-zero arg means wait for all output data
@@ -3580,8 +3571,8 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3580 } 3571 }
3581 break; 3572 break;
3582 } 3573 }
3583 if (tty->driver->ioctl) { 3574 if (tty->ops->ioctl) {
3584 retval = (tty->driver->ioctl)(tty, file, cmd, arg); 3575 retval = (tty->ops->ioctl)(tty, file, cmd, arg);
3585 if (retval != -ENOIOCTLCMD) 3576 if (retval != -ENOIOCTLCMD)
3586 return retval; 3577 return retval;
3587 } 3578 }
@@ -3608,8 +3599,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
3608 if (tty_paranoia_check(tty, inode, "tty_ioctl")) 3599 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
3609 return -EINVAL; 3600 return -EINVAL;
3610 3601
3611 if (tty->driver->compat_ioctl) { 3602 if (tty->ops->compat_ioctl) {
3612 retval = (tty->driver->compat_ioctl)(tty, file, cmd, arg); 3603 retval = (tty->ops->compat_ioctl)(tty, file, cmd, arg);
3613 if (retval != -ENOIOCTLCMD) 3604 if (retval != -ENOIOCTLCMD)
3614 return retval; 3605 return retval;
3615 } 3606 }
@@ -3659,8 +3650,7 @@ void __do_SAK(struct tty_struct *tty)
3659 3650
3660 tty_ldisc_flush(tty); 3651 tty_ldisc_flush(tty);
3661 3652
3662 if (tty->driver->flush_buffer) 3653 tty_driver_flush_buffer(tty);
3663 tty->driver->flush_buffer(tty);
3664 3654
3665 read_lock(&tasklist_lock); 3655 read_lock(&tasklist_lock);
3666 /* Kill the entire session */ 3656 /* Kill the entire session */
@@ -3871,15 +3861,27 @@ static void initialize_tty_struct(struct tty_struct *tty)
3871 INIT_WORK(&tty->SAK_work, do_SAK_work); 3861 INIT_WORK(&tty->SAK_work, do_SAK_work);
3872} 3862}
3873 3863
3874/* 3864/**
3875 * The default put_char routine if the driver did not define one. 3865 * tty_put_char - write one character to a tty
3866 * @tty: tty
3867 * @ch: character
3868 *
3869 * Write one byte to the tty using the provided put_char method
3870 * if present. Returns the number of characters successfully output.
3871 *
3872 * Note: the specific put_char operation in the driver layer may go
3873 * away soon. Don't call it directly, use this method
3876 */ 3874 */
3877 3875
3878static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) 3876int tty_put_char(struct tty_struct *tty, unsigned char ch)
3879{ 3877{
3880 tty->driver->write(tty, &ch, 1); 3878 if (tty->ops->put_char)
3879 return tty->ops->put_char(tty, ch);
3880 return tty->ops->write(tty, &ch, 1);
3881} 3881}
3882 3882
3883EXPORT_SYMBOL_GPL(tty_put_char);
3884
3883static struct class *tty_class; 3885static struct class *tty_class;
3884 3886
3885/** 3887/**
@@ -3962,37 +3964,8 @@ void put_tty_driver(struct tty_driver *driver)
3962void tty_set_operations(struct tty_driver *driver, 3964void tty_set_operations(struct tty_driver *driver,
3963 const struct tty_operations *op) 3965 const struct tty_operations *op)
3964{ 3966{
3965 driver->open = op->open; 3967 driver->ops = op;
3966 driver->close = op->close; 3968};
3967 driver->write = op->write;
3968 driver->put_char = op->put_char;
3969 driver->flush_chars = op->flush_chars;
3970 driver->write_room = op->write_room;
3971 driver->chars_in_buffer = op->chars_in_buffer;
3972 driver->ioctl = op->ioctl;
3973 driver->compat_ioctl = op->compat_ioctl;
3974 driver->set_termios = op->set_termios;
3975 driver->throttle = op->throttle;
3976 driver->unthrottle = op->unthrottle;
3977 driver->stop = op->stop;
3978 driver->start = op->start;
3979 driver->hangup = op->hangup;
3980 driver->break_ctl = op->break_ctl;
3981 driver->flush_buffer = op->flush_buffer;
3982 driver->set_ldisc = op->set_ldisc;
3983 driver->wait_until_sent = op->wait_until_sent;
3984 driver->send_xchar = op->send_xchar;
3985 driver->read_proc = op->read_proc;
3986 driver->write_proc = op->write_proc;
3987 driver->tiocmget = op->tiocmget;
3988 driver->tiocmset = op->tiocmset;
3989#ifdef CONFIG_CONSOLE_POLL
3990 driver->poll_init = op->poll_init;
3991 driver->poll_get_char = op->poll_get_char;
3992 driver->poll_put_char = op->poll_put_char;
3993#endif
3994}
3995
3996 3969
3997EXPORT_SYMBOL(alloc_tty_driver); 3970EXPORT_SYMBOL(alloc_tty_driver);
3998EXPORT_SYMBOL(put_tty_driver); 3971EXPORT_SYMBOL(put_tty_driver);
@@ -4055,9 +4028,6 @@ int tty_register_driver(struct tty_driver *driver)
4055 return error; 4028 return error;
4056 } 4029 }
4057 4030
4058 if (!driver->put_char)
4059 driver->put_char = tty_default_put_char;
4060
4061 mutex_lock(&tty_mutex); 4031 mutex_lock(&tty_mutex);
4062 list_add(&driver->tty_drivers, &tty_drivers); 4032 list_add(&driver->tty_drivers, &tty_drivers);
4063 mutex_unlock(&tty_mutex); 4033 mutex_unlock(&tty_mutex);