#include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/sysctl.h>
+#include <linux/device.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
 static int pty_limit_min = 0;
 static int pty_limit_max = NR_UNIX98_PTY_MAX;
 
+static struct cdev ptmx_cdev;
+
 static struct ctl_table pty_table[] = {
        {
                .ctl_name       = PTY_MAX,
        .shutdown = pty_shutdown
 };
 
+
+/**
+ *     ptmx_open               -       open a unix 98 pty master
+ *     @inode: inode of device file
+ *     @filp: file pointer to tty
+ *
+ *     Allocate a unix98 pty master device from the ptmx driver.
+ *
+ *     Locking: tty_mutex protects the init_dev work. tty->count should
+ *             protect the rest.
+ *             allocated_ptys_lock handles the list of free pty numbers
+ */
+
+static int __ptmx_open(struct inode *inode, struct file *filp)
+{
+       struct tty_struct *tty;
+       int retval;
+       int index;
+
+       nonseekable_open(inode, filp);
+
+       /* find a device that is not in use. */
+       index = devpts_new_index();
+       if (index < 0)
+               return index;
+
+       mutex_lock(&tty_mutex);
+       retval = tty_init_dev(ptm_driver, index, &tty, 1);
+       mutex_unlock(&tty_mutex);
+
+       if (retval)
+               goto out;
+
+       set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
+       filp->private_data = tty;
+       file_move(filp, &tty->tty_files);
+
+       retval = devpts_pty_new(tty->link);
+       if (retval)
+               goto out1;
+
+       retval = ptm_driver->ops->open(tty, filp);
+       if (!retval)
+               return 0;
+out1:
+       tty_release_dev(filp);
+       return retval;
+out:
+       devpts_kill_index(index);
+       return retval;
+}
+
+static int ptmx_open(struct inode *inode, struct file *filp)
+{
+       int ret;
+
+       lock_kernel();
+       ret = __ptmx_open(inode, filp);
+       unlock_kernel();
+       return ret;
+}
+
+static struct file_operations ptmx_fops;
+
 static void __init unix98_pty_init(void)
 {
        ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
 
        pty_table[1].data = &ptm_driver->refcount;
        register_sysctl_table(pty_root_table);
+
+       /* Now create the /dev/ptmx special device */
+       tty_default_fops(&ptmx_fops);
+       ptmx_fops.open = ptmx_open;
+
+       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), NULL, "ptmx");
 }
+
 #else
 static inline void unix98_pty_init(void) { }
 #endif
 
  * implement CONFIG_VT and generalize console device interface.
  *     -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97
  *
- * Rewrote init_dev and release_dev to eliminate races.
+ * Rewrote tty_init_dev and tty_release_dev to eliminate races.
  *     -- Bill Hawes <whawes@star.net>, June 97
  *
  * Added devfs support.
 DEFINE_MUTEX(tty_mutex);
 EXPORT_SYMBOL(tty_mutex);
 
-#ifdef CONFIG_UNIX98_PTYS
-extern struct tty_driver *ptm_driver;  /* Unix98 pty masters; for /dev/ptmx */
-static int ptmx_open(struct inode *, struct file *);
-#endif
-
 static void initialize_tty_struct(struct tty_struct *tty);
 
 static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
        .fasync         = tty_fasync,
 };
 
-#ifdef CONFIG_UNIX98_PTYS
-static const struct file_operations ptmx_fops = {
-       .llseek         = no_llseek,
-       .read           = tty_read,
-       .write          = tty_write,
-       .poll           = tty_poll,
-       .unlocked_ioctl = tty_ioctl,
-       .compat_ioctl   = tty_compat_ioctl,
-       .open           = ptmx_open,
-       .release        = tty_release,
-       .fasync         = tty_fasync,
-};
-#endif
-
 static const struct file_operations console_fops = {
        .llseek         = no_llseek,
        .read           = tty_read,
 }
 
 /**
- *     init_dev                -       initialise a tty device
+ *     tty_init_dev            -       initialise a tty device
  *     @driver: tty driver we are opening a device on
  *     @idx: device index
  *     @ret_tty: returned tty structure
  * relaxed for the (most common) case of reopening a tty.
  */
 
-static int init_dev(struct tty_driver *driver, int idx,
+int tty_init_dev(struct tty_driver *driver, int idx,
        struct tty_struct **ret_tty, int first_ok)
 {
        struct tty_struct *tty, *o_tty;
                        goto end_init;
                }
                /*
-                * It's safe from now on because init_dev() is called with
-                * tty_mutex held and release_dev() won't change tty->count
+                * It's safe from now on because tty_init_dev() is called with
+                * tty_mutex held and tty_release_dev() won't change tty->count
                 * or tty->flags without having to grab tty_mutex
                 */
                if (tty && driver->subtype == PTY_TYPE_MASTER)
 
        /* FIXME */
        if (!test_bit(TTY_LDISC, &tty->flags))
-               printk(KERN_ERR "init_dev but no ldisc\n");
+               printk(KERN_ERR "tty_init_dev but no ldisc\n");
 success:
        *ret_tty = tty;
 
        /* call the tty release_tty routine to clean out this slot */
 release_mem_out:
        if (printk_ratelimit())
-               printk(KERN_INFO "init_dev: ldisc open failed, "
+               printk(KERN_INFO "tty_init_dev: ldisc open failed, "
                                 "clearing slot %d\n", idx);
        release_tty(tty, idx);
        goto end_init;
  * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
  * lead to double frees or releasing memory still in use.
  */
-static void release_dev(struct file *filp)
+void tty_release_dev(struct file *filp)
 {
        struct tty_struct *tty, *o_tty;
        int     pty_master, tty_closing, o_tty_closing, do_sleep;
 
        tty = (struct tty_struct *)filp->private_data;
        if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode,
-                                                       "release_dev"))
+                                                       "tty_release_dev"))
                return;
 
-       check_tty_count(tty, "release_dev");
+       check_tty_count(tty, "tty_release_dev");
 
        tty_fasync(-1, filp, 0);
 
 
 #ifdef TTY_PARANOIA_CHECK
        if (idx < 0 || idx >= tty->driver->num) {
-               printk(KERN_DEBUG "release_dev: bad idx when trying to "
+               printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
                                  "free (%s)\n", tty->name);
                return;
        }
        if (!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
                if (tty != tty->driver->ttys[idx]) {
-                       printk(KERN_DEBUG "release_dev: driver.table[%d] not tty "
+                       printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
                               "for (%s)\n", idx, tty->name);
                        return;
                }
                if (tty->termios != tty->driver->termios[idx]) {
-                       printk(KERN_DEBUG "release_dev: driver.termios[%d] not termios "
+                       printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
                               "for (%s)\n",
                               idx, tty->name);
                        return;
                }
                if (tty->termios_locked != tty->driver->termios_locked[idx]) {
-                       printk(KERN_DEBUG "release_dev: driver.termios_locked[%d] not "
+                       printk(KERN_DEBUG "tty_release_dev: driver.termios_locked[%d] not "
                               "termios_locked for (%s)\n",
                               idx, tty->name);
                        return;
 #endif
 
 #ifdef TTY_DEBUG_HANGUP
-       printk(KERN_DEBUG "release_dev of %s (tty count=%d)...",
+       printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...",
               tty_name(tty, buf), tty->count);
 #endif
 
        if (tty->driver->other &&
             !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
                if (o_tty != tty->driver->other->ttys[idx]) {
-                       printk(KERN_DEBUG "release_dev: other->table[%d] "
+                       printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
                                          "not o_tty for (%s)\n",
                               idx, tty->name);
                        return;
                }
                if (o_tty->termios != tty->driver->other->termios[idx]) {
-                       printk(KERN_DEBUG "release_dev: other->termios[%d] "
+                       printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
                                          "not o_termios for (%s)\n",
                               idx, tty->name);
                        return;
                }
                if (o_tty->termios_locked !=
                      tty->driver->other->termios_locked[idx]) {
-                       printk(KERN_DEBUG "release_dev: other->termios_locked["
+                       printk(KERN_DEBUG "tty_release_dev: other->termios_locked["
                                          "%d] not o_termios_locked for (%s)\n",
                               idx, tty->name);
                        return;
                }
                if (o_tty->link != tty) {
-                       printk(KERN_DEBUG "release_dev: bad pty pointers\n");
+                       printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
                        return;
                }
        }
                if (!do_sleep)
                        break;
 
-               printk(KERN_WARNING "release_dev: %s: read/write wait queue "
+               printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
                                    "active!\n", tty_name(tty, buf));
                mutex_unlock(&tty_mutex);
                schedule();
         */
        if (pty_master) {
                if (--o_tty->count < 0) {
-                       printk(KERN_WARNING "release_dev: bad pty slave count "
+                       printk(KERN_WARNING "tty_release_dev: bad pty slave count "
                                            "(%d) for %s\n",
                               o_tty->count, tty_name(o_tty, buf));
                        o_tty->count = 0;
                }
        }
        if (--tty->count < 0) {
-               printk(KERN_WARNING "release_dev: bad tty->count (%d) for %s\n",
+               printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n",
                       tty->count, tty_name(tty, buf));
                tty->count = 0;
        }
  *     The termios state of a pty is reset on first open so that
  *     settings don't persist across reuse.
  *
- *     Locking: tty_mutex protects tty, get_tty_driver and init_dev work.
+ *     Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work.
  *              tty->count should protect the rest.
  *              ->siglock protects ->signal/->sighand
  */
                return -ENODEV;
        }
 got_driver:
-       retval = init_dev(driver, index, &tty, 0);
+       retval = tty_init_dev(driver, index, &tty, 0);
        mutex_unlock(&tty_mutex);
        if (retval)
                return retval;
                printk(KERN_DEBUG "error %d in opening %s...", retval,
                       tty->name);
 #endif
-               release_dev(filp);
+               tty_release_dev(filp);
                if (retval != -ERESTARTSYS)
                        return retval;
                if (signal_pending(current))
 
 
 
-#ifdef CONFIG_UNIX98_PTYS
-/**
- *     ptmx_open               -       open a unix 98 pty master
- *     @inode: inode of device file
- *     @filp: file pointer to tty
- *
- *     Allocate a unix98 pty master device from the ptmx driver.
- *
- *     Locking: tty_mutex protects theinit_dev work. tty->count should
- *             protect the rest.
- *             allocated_ptys_lock handles the list of free pty numbers
- */
-
-static int __ptmx_open(struct inode *inode, struct file *filp)
-{
-       struct tty_struct *tty;
-       int retval;
-       int index;
-
-       nonseekable_open(inode, filp);
-
-       /* find a device that is not in use. */
-       index = devpts_new_index();
-       if (index < 0)
-               return index;
-
-       mutex_lock(&tty_mutex);
-       retval = init_dev(ptm_driver, index, &tty, 1);
-       mutex_unlock(&tty_mutex);
-
-       if (retval)
-               goto out;
-
-       set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
-       filp->private_data = tty;
-       file_move(filp, &tty->tty_files);
-
-       retval = devpts_pty_new(tty->link);
-       if (retval)
-               goto out1;
-
-       check_tty_count(tty, "ptmx_open");
-       retval = ptm_driver->ops->open(tty, filp);
-       if (!retval)
-               return 0;
-out1:
-       release_dev(filp);
-       return retval;
-out:
-       devpts_kill_index(index);
-       return retval;
-}
-
-static int ptmx_open(struct inode *inode, struct file *filp)
-{
-       int ret;
-
-       lock_kernel();
-       ret = __ptmx_open(inode, filp);
-       unlock_kernel();
-       return ret;
-}
-#endif
 
 /**
  *     tty_release             -       vfs callback for close
  *     this tty. There may however be several such references.
  *
  *     Locking:
- *             Takes bkl. See release_dev
+ *             Takes bkl. See tty_release_dev
  */
 
 static int tty_release(struct inode *inode, struct file *filp)
 {
        lock_kernel();
-       release_dev(filp);
+       tty_release_dev(filp);
        unlock_kernel();
        return 0;
 }
 
 EXPORT_SYMBOL_GPL(tty_put_char);
 
-static struct class *tty_class;
+struct class *tty_class;
 
 /**
  *     tty_register_device - register a tty device
 }
 EXPORT_SYMBOL_GPL(get_current_tty);
 
+void tty_default_fops(struct file_operations *fops)
+{
+       *fops = tty_fops;
+}
+
 /*
  * Initialize the console device. This is called *early*, so
  * we can't necessarily depend on lots of kernel help here.
 /* 3/2004 jmc: why do these devices exist? */
 
 static struct cdev tty_cdev, console_cdev;
-#ifdef CONFIG_UNIX98_PTYS
-static struct cdev ptmx_cdev;
-#endif
-#ifdef CONFIG_VT
-static struct cdev vc0_cdev;
-#endif
 
 /*
  * Ok, now we can initialize the rest of the tty devices and can count
        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_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
+       device_create(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_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
+       device_create(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_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
-#endif
-
 #ifdef CONFIG_VT
-       cdev_init(&vc0_cdev, &console_fops);
-       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_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
-
-       vty_init();
+       vty_init(&console_fops);
 #endif
        return 0;
 }
 
 #define TERMIOS_OLD    8
 
 
+/**
+ *     tty_chars_in_buffer     -       characters pending
+ *     @tty: terminal
+ *
+ *     Return the number of bytes of data in the device private
+ *     output queue. If no private method is supplied there is assumed
+ *     to be no queue on the device.
+ */
+
 int tty_chars_in_buffer(struct tty_struct *tty)
 {
        if (tty->ops->chars_in_buffer)
        else
                return 0;
 }
-
 EXPORT_SYMBOL(tty_chars_in_buffer);
 
+/**
+ *     tty_write_room          -       write queue space
+ *     @tty: terminal
+ *
+ *     Return the number of bytes that can be queued to this device
+ *     at the present time. The result should be treated as a guarantee
+ *     and the driver cannot offer a value it later shrinks by more than
+ *     the number of bytes written. If no method is provided 2K is always
+ *     returned and data may be lost as there will be no flow control.
+ */
+ 
 int tty_write_room(struct tty_struct *tty)
 {
        if (tty->ops->write_room)
                return tty->ops->write_room(tty);
        return 2048;
 }
-
 EXPORT_SYMBOL(tty_write_room);
 
+/**
+ *     tty_driver_flush_buffer -       discard internal buffer
+ *     @tty: terminal
+ *
+ *     Discard the internal output buffer for this device. If no method
+ *     is provided then either the buffer cannot be hardware flushed or
+ *     there is no buffer driver side.
+ */
 void tty_driver_flush_buffer(struct tty_struct *tty)
 {
        if (tty->ops->flush_buffer)
                tty->ops->flush_buffer(tty);
 }
-
 EXPORT_SYMBOL(tty_driver_flush_buffer);
 
+/**
+ *     tty_throttle            -       flow control
+ *     @tty: terminal
+ *
+ *     Indicate that a tty should stop transmitting data down the stack.
+ */
+
 void tty_throttle(struct tty_struct *tty)
 {
        /* check TTY_THROTTLED first so it indicates our state */
 }
 EXPORT_SYMBOL(tty_throttle);
 
+/**
+ *     tty_unthrottle          -       flow control
+ *     @tty: terminal
+ *
+ *     Indicate that a tty may continue transmitting data down the stack.
+ */
+
 void tty_unthrottle(struct tty_struct *tty)
 {
        if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
 }
 EXPORT_SYMBOL(tty_wait_until_sent);
 
+
+/*
+ *             Termios Helper Methods
+ */
+
 static void unset_locked_termios(struct ktermios *termios,
                                 struct ktermios *old,
                                 struct ktermios *locked)
 }
 EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
 
+/**
+ *     tty_encode_baud_rate            -       set baud rate of the tty
+ *     @ibaud: input baud rate
+ *     @obad: output baud rate
+ *
+ *     Update the current termios data for the tty with the new speed
+ *     settings. The caller must hold the termios_mutex for the tty in
+ *     question.
+ */
+
 void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
 {
        tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
  *     is a bit of layering violation here with n_tty in terms of the
  *     internal knowledge of this function.
  *
- *     Locking: termios_sem
+ *     Locking: termios_mutex
  */
 
 static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
  *     functions before using change_termios to do the actual changes.
  *
  *     Locking:
- *             Called functions take ldisc and termios_sem locks
+ *             Called functions take ldisc and termios_mutex locks
  */
 
 static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
  *     Updates a terminal from the legacy BSD style terminal information
  *     structure.
  *
- *     Locking: termios_sem
+ *     Locking: termios_mutex
  */
 
 static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)