Re: [PATCH] TTY changes for 2.5.69

From: Greg KH (greg@kroah.com)
Date: Wed May 07 2003 - 18:16:28 EST


ChangeSet 1.1115, 2003/05/07 15:51:02-07:00, greg@kroah.com

TTY: add tty class support for all tty devices.

 drivers/char/tty_io.c | 146 +++++++++++++++++++++++++++++++++++++++++---------
 include/linux/tty.h | 3 -
 2 files changed, 122 insertions(+), 27 deletions(-)

diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c Wed May 7 16:00:04 2003
+++ b/drivers/char/tty_io.c Wed May 7 16:00:04 2003
@@ -2088,22 +2088,6 @@
 }
 
 #ifdef CONFIG_DEVFS_FS
-static void tty_register_devfs(struct tty_driver *driver, unsigned index)
-{
- dev_t dev = MKDEV(driver->major, driver->minor_start) + index;
- char buf[32];
-
- if (index >= driver->num) {
- printk(KERN_ERR "Attempt to register invalid tty line number "
- "with devfs (%d).\n", index);
- return;
- }
-
- tty_line_name(driver, index, buf);
- devfs_register(NULL, buf, 0, MAJOR(dev), MINOR(dev),
- S_IFCHR | S_IRUSR | S_IWUSR, &tty_fops, NULL);
-}
-
 static void tty_unregister_devfs(struct tty_driver *driver, int index)
 {
         char path[64];
@@ -2111,21 +2095,131 @@
         devfs_remove(path);
 }
 #else
-# define tty_register_devfs(driver, index) do { } while (0)
 # define tty_unregister_devfs(driver, index) do { } while (0)
 #endif /* CONFIG_DEVFS_FS */
 
-/*
- * Register a tty device described by <driver>, with minor number <minor>.
+static struct class tty_class = {
+ .name = "tty",
+};
+
+struct tty_dev {
+ struct list_head node;
+ dev_t dev;
+ struct class_device class_dev;
+};
+#define to_tty_dev(d) container_of(d, struct tty_dev, class_dev)
+
+static LIST_HEAD(tty_dev_list);
+
+static ssize_t show_dev(struct class_device *class_dev, char *buf)
+{
+ struct tty_dev *tty_dev = to_tty_dev(class_dev);
+ return sprintf(buf, "%04x\n", tty_dev->dev);
+}
+static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
+
+static void tty_add_class_device(char *name, dev_t dev, struct device *device)
+{
+ struct tty_dev *tty_dev = NULL;
+ char *temp;
+ int retval;
+
+ tty_dev = kmalloc(sizeof(*tty_dev), GFP_KERNEL);
+ if (!tty_dev)
+ return;
+ memset(tty_dev, 0x00, sizeof(*tty_dev));
+
+ /* stupid '/' in tty name strings... */
+ temp = strchr(name, '/');
+ if (temp && (temp[1] != 0x00))
+ ++temp;
+ else
+ temp = name;
+
+ tty_dev->class_dev.dev = device;
+ tty_dev->class_dev.class = &tty_class;
+ snprintf(tty_dev->class_dev.class_id, BUS_ID_SIZE, "%s", temp);
+ retval = class_device_register(&tty_dev->class_dev);
+ if (retval)
+ goto error;
+ class_device_create_file (&tty_dev->class_dev, &class_device_attr_dev);
+ tty_dev->dev = dev;
+ list_add(&tty_dev->node, &tty_dev_list);
+ return;
+error:
+ kfree(tty_dev);
+}
+
+void tty_remove_class_device(dev_t dev)
+{
+ struct tty_dev *tty_dev = NULL;
+ struct list_head *tmp;
+ int found = 0;
+
+ list_for_each (tmp, &tty_dev_list) {
+ tty_dev = list_entry(tmp, struct tty_dev, node);
+ if ((MAJOR(tty_dev->dev) == MAJOR(dev)) &&
+ (MINOR(tty_dev->dev) == MINOR(dev))) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ list_del(&tty_dev->node);
+ class_device_unregister(&tty_dev->class_dev);
+ kfree(tty_dev);
+ }
+}
+
+/**
+ * tty_register_device - register a tty device
+ * @driver: the tty driver that describes the tty device
+ * @index: the index in the tty driver for this tty device
+ * @device: a struct device that is associated with this tty device.
+ * This field is optional, if there is no known struct device for this
+ * tty device it can be set to NULL safely.
+ *
+ * This call is required to be made to register an individual tty device if
+ * the tty driver's flags have the TTY_DRIVER_NO_DEVFS bit set. If that
+ * bit is not set, this function should not be called.
  */
-void tty_register_device(struct tty_driver *driver, unsigned index)
+void tty_register_device(struct tty_driver *driver, unsigned index,
+ struct device *device)
 {
- tty_register_devfs(driver, index);
+ dev_t dev = MKDEV(driver->major, driver->minor_start) + index;
+ char name[64];
+
+ if (index >= driver->num) {
+ printk(KERN_ERR "Attempt to register invalid tty line number "
+ " (%d).\n", index);
+ return;
+ }
+
+ tty_line_name(driver, index, name);
+ devfs_register(NULL, name, 0, MAJOR(dev), MINOR(dev),
+ S_IFCHR | S_IRUSR | S_IWUSR, &tty_fops, NULL);
+
+ /* stupid console driver devfs names... change vc/X into ttyX */
+ if (driver->type == TTY_DRIVER_TYPE_CONSOLE)
+ sprintf(name, "tty%d", MINOR(dev));
+
+ /* we don't care about the ptys */
+ if (driver->type != TTY_DRIVER_TYPE_PTY)
+ tty_add_class_device (name, dev, device);
 }
 
+/**
+ * tty_unregister_device - unregister a tty device
+ * @driver: the tty driver that describes the tty device
+ * @index: the index in the tty driver for this tty device
+ *
+ * If a tty device is registered with a call to tty_register_device() then
+ * this function must be made when the tty device is gone.
+ */
 void tty_unregister_device(struct tty_driver *driver, unsigned index)
 {
         tty_unregister_devfs(driver, index);
+ tty_remove_class_device(MKDEV(driver->major, driver->minor_start) + index);
 }
 
 EXPORT_SYMBOL(tty_register_device);
@@ -2207,7 +2301,7 @@
         
         if ( !(driver->flags & TTY_DRIVER_NO_DEVFS) ) {
                 for(i = 0; i < driver->num; i++)
- tty_register_device(driver, i);
+ tty_register_device(driver, i, NULL);
         }
         proc_tty_register_driver(driver);
         return error;
@@ -2288,10 +2382,6 @@
 extern int vty_init(void);
 #endif
 
-static struct class tty_class = {
- .name = "tty",
-};
-
 static int __init tty_class_init(void)
 {
         return class_register(&tty_class);
@@ -2311,6 +2401,7 @@
 
         devfs_register (NULL, "tty", 0, TTYAUX_MAJOR, 0,
                         S_IFCHR | S_IRUGO | S_IWUGO, &tty_fops, NULL);
+ tty_add_class_device ("tty", MKDEV(TTYAUX_MAJOR, 0), NULL);
 
         if (register_chrdev_region(TTYAUX_MAJOR, 1, 1,
                                    "/dev/console", &tty_fops) < 0)
@@ -2318,6 +2409,7 @@
 
         devfs_register (NULL, "console", 0, TTYAUX_MAJOR, 1,
                         S_IFCHR | S_IRUSR | S_IWUSR, &tty_fops, NULL);
+ tty_add_class_device ("console", MKDEV(TTYAUX_MAJOR, 1), NULL);
 
 #ifdef CONFIG_UNIX98_PTYS
         if (register_chrdev_region(TTYAUX_MAJOR, 2, 1,
@@ -2326,6 +2418,7 @@
 
         devfs_register (NULL, "ptmx", 0, TTYAUX_MAJOR, 2,
                         S_IFCHR | S_IRUGO | S_IWUGO, &tty_fops, NULL);
+ tty_add_class_device ("ptmx", MKDEV(TTYAUX_MAJOR, 2), NULL);
 #endif
         
 #ifdef CONFIG_VT
@@ -2335,6 +2428,7 @@
 
         devfs_register (NULL, "vc/0", 0, TTY_MAJOR, 0,
                         S_IFCHR | S_IRUSR | S_IWUSR, &tty_fops, NULL);
+ tty_add_class_device ("tty0", MKDEV(TTY_MAJOR, 0), NULL);
 
         vty_init();
 #endif
diff -Nru a/include/linux/tty.h b/include/linux/tty.h
--- a/include/linux/tty.h Wed May 7 16:00:04 2003
+++ b/include/linux/tty.h Wed May 7 16:00:04 2003
@@ -243,6 +243,7 @@
 #define L_PENDIN(tty) _L_FLAG((tty),PENDIN)
 #define L_IEXTEN(tty) _L_FLAG((tty),IEXTEN)
 
+struct device;
 /*
  * Where all of the state associated with a tty is kept while the tty
  * is open. Since the termios state should be kept even if the tty
@@ -380,7 +381,7 @@
 extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc);
 extern int tty_register_driver(struct tty_driver *driver);
 extern int tty_unregister_driver(struct tty_driver *driver);
-extern void tty_register_device(struct tty_driver *driver, unsigned index);
+extern void tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev);
 extern void tty_unregister_device(struct tty_driver *driver, unsigned index);
 extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp,
                              int buflen);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed May 07 2003 - 22:00:33 EST