]> err.no Git - linux-2.6/blobdiff - drivers/char/tty_io.c
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6] / drivers / char / tty_io.c
index d27a08b374d050da20be594e332ffe026191b506..0e6866fe0f96d5fb19b0098a85d4a5ba52351d33 100644 (file)
@@ -915,7 +915,7 @@ static void tty_reset_termios(struct tty_struct *tty)
  *     do_tty_hangup           -       actual handler for hangup events
  *     @work: tty device
  *
-k *    This can be called by the "eventd" kernel thread.  That is process
+ *     This can be called by the "eventd" kernel thread.  That is process
  *     synchronous but doesn't hold any locks, so we need to make sure we
  *     have the appropriate locks for what we're doing.
  *
@@ -1119,19 +1119,6 @@ int tty_hung_up_p(struct file *filp)
 
 EXPORT_SYMBOL(tty_hung_up_p);
 
-/**
- *     is_tty  -       checker whether file is a TTY
- *     @filp:          file handle that may be a tty
- *
- *     Check if the file handle is a tty handle.
- */
-
-int is_tty(struct file *filp)
-{
-       return filp->f_op->read == tty_read
-               || filp->f_op->read == hung_up_tty_read;
-}
-
 static void session_clear_tty(struct pid *session)
 {
        struct task_struct *p;
@@ -1174,8 +1161,8 @@ void disassociate_ctty(int on_exit)
        tty = get_current_tty();
        if (tty) {
                tty_pgrp = get_pid(tty->pgrp);
-               mutex_unlock(&tty_mutex);
                lock_kernel();
+               mutex_unlock(&tty_mutex);
                /* XXX: here we race, there is nothing protecting tty */
                if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
                        tty_vhangup(tty);
@@ -2849,16 +2836,29 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
 
 static int send_break(struct tty_struct *tty, unsigned int duration)
 {
-       if (tty_write_lock(tty, 0) < 0)
-               return -EINTR;
-       tty->ops->break_ctl(tty, -1);
-       if (!signal_pending(current))
-               msleep_interruptible(duration);
-       tty->ops->break_ctl(tty, 0);
-       tty_write_unlock(tty);
-       if (signal_pending(current))
-               return -EINTR;
-       return 0;
+       int retval;
+
+       if (tty->ops->break_ctl == NULL)
+               return 0;
+
+       if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
+               retval = tty->ops->break_ctl(tty, duration);
+       else {
+               /* Do the work ourselves */
+               if (tty_write_lock(tty, 0) < 0)
+                       return -EINTR;
+               retval = tty->ops->break_ctl(tty, -1);
+               if (retval)
+                       goto out;
+               if (!signal_pending(current))
+                       msleep_interruptible(duration);
+               retval = tty->ops->break_ctl(tty, 0);
+out:
+               tty_write_unlock(tty);
+               if (signal_pending(current))
+                       retval = -EINTR;
+       }
+       return retval;
 }
 
 /**
@@ -2949,36 +2949,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
            tty->driver->subtype == PTY_TYPE_MASTER)
                real_tty = tty->link;
 
-       /*
-        * Break handling by driver
-        */
-
-       retval = -EINVAL;
-
-       if (!tty->ops->break_ctl) {
-               switch (cmd) {
-               case TIOCSBRK:
-               case TIOCCBRK:
-                       if (tty->ops->ioctl)
-                               retval = tty->ops->ioctl(tty, file, cmd, arg);
-                       if (retval != -EINVAL && retval != -ENOIOCTLCMD)
-                               printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
-                       return retval;
-
-               /* These two ioctl's always return success; even if */
-               /* the driver doesn't support them. */
-               case TCSBRK:
-               case TCSBRKP:
-                       if (!tty->ops->ioctl)
-                               return 0;
-                       retval = tty->ops->ioctl(tty, file, cmd, arg);
-                       if (retval != -EINVAL && retval != -ENOIOCTLCMD)
-                               printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
-                       if (retval == -ENOIOCTLCMD)
-                               retval = 0;
-                       return retval;
-               }
-       }
 
        /*
         * Factor out some common prep work
@@ -3000,6 +2970,9 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                break;
        }
 
+       /*
+        *      Now do the stuff.
+        */
        switch (cmd) {
        case TIOCSTI:
                return tiocsti(tty, p);
@@ -3043,12 +3016,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
         */
        case TIOCSBRK:  /* Turn break on, unconditionally */
                if (tty->ops->break_ctl)
-                       tty->ops->break_ctl(tty, -1);
+                       return tty->ops->break_ctl(tty, -1);
                return 0;
-
        case TIOCCBRK:  /* Turn break off, unconditionally */
                if (tty->ops->break_ctl)
-                       tty->ops->break_ctl(tty, 0);
+                       return tty->ops->break_ctl(tty, 0);
                return 0;
        case TCSBRK:   /* SVID version: non-zero arg --> no break */
                /* non-zero arg means wait for all output data
@@ -3427,7 +3399,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index,
        else
                tty_line_name(driver, index, name);
 
-       return device_create(tty_class, device, dev, name);
+       return device_create_drvdata(tty_class, device, dev, NULL, name);
 }
 
 /**
@@ -3608,7 +3580,6 @@ void proc_clear_tty(struct task_struct *p)
        p->signal->tty = NULL;
        spin_unlock_irq(&p->sighand->siglock);
 }
-EXPORT_SYMBOL(proc_clear_tty);
 
 /* Called under the sighand lock */
 
@@ -3705,20 +3676,22 @@ static int __init tty_init(void)
        if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
                panic("Couldn't register /dev/tty driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), "tty");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
+                             "tty");
 
        cdev_init(&console_cdev, &console_fops);
        if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
                panic("Couldn't register /dev/console driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), "console");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
+                             "console");
 
 #ifdef CONFIG_UNIX98_PTYS
        cdev_init(&ptmx_cdev, &ptmx_fops);
        if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
                panic("Couldn't register /dev/ptmx driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), "ptmx");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
 #endif
 
 #ifdef CONFIG_VT
@@ -3726,7 +3699,7 @@ static int __init tty_init(void)
        if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
                panic("Couldn't register /dev/tty0 driver\n");
-       device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), "tty0");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
 
        vty_init();
 #endif