[patch][devfs] Utility functions to handle /dev/cpu/

From: alvin@diaspar.net
Date: Fri May 17 2002 - 23:09:48 EST


Greetings,
        These functions are helpers for drivers that may need to (un)register devfs entries across the /dev/cpu/* subtree. Two drivers that need such functionality to work with devfs out-of-the-box are the MSR driver and the CPUID driver on x86.
        Patches made against 2.4.19-pre8-ac4 + cryptoapi.
        Please CC comments, suggestions, flames to: ioshadij@hotmail.com; I've not subscribed to l-k.

Ishan Oshadi Jayawardena

PATCH 1:
--- linux/fs/devfs/base.c.1 Thu May 16 23:39:58 2002
+++ linux/fs/devfs/base.c Fri May 17 17:04:04 2002
@@ -924,6 +924,25 @@ void devfs_put (devfs_handle_t de)
 } /* End Function devfs_put */
 
 /**
+ * _devfs_update_dev_cpu - Update the /dev/cpu/ hierarchy
+ *
+ * This function should be updated when/if CPU Hotplugging support is added
+ * so that plugging in/out a CPU will be reflected in the /dev/cpu/
+ * hierarchy.
+ */
+
+void _devfs_update_dev_cpu (void)
+{
+ int tmp;
+ for (tmp = 0; tmp < smp_num_cpus; tmp++)
+ {
+ char path[8];
+ sprintf (path, "cpu/%d", tmp);
+ devfs_mk_dir (NULL, path, NULL);
+ }
+} /* End Function _devfs_update_dev_cpu */
+
+/**
  * _devfs_search_dir - Search for a devfs entry in a directory.
  * @dir: The directory to search.
  * @name: The name of the entry to search for.
@@ -3466,7 +3485,6 @@ static ssize_t stat_read (struct file *f
 } /* End Function stat_read */
 #endif
 
-
 static int __init init_devfs_fs (void)
 {
     int err;
@@ -3500,6 +3518,9 @@ void __init mount_devfs_fs (void)
     err = do_mount ("none", "/dev", "devfs", 0, "");
     if (err == 0) printk (KERN_INFO "Mounted devfs on /dev\n");
     else PRINTK ("(): unable to mount devfs, err: %d\n", err);
+
+ _devfs_update_dev_cpu ();
+
 } /* End Function mount_devfs_fs */
 
 module_init(init_devfs_fs)
--- linux/fs/devfs/util.c.1 Thu May 16 21:37:40 2002
+++ linux/fs/devfs/util.c Fri May 17 17:02:25 2002
@@ -424,3 +424,56 @@ void devfs_dealloc_unique_number (struct
                number);
 } /* End Function devfs_dealloc_unique_number */
 EXPORT_SYMBOL(devfs_dealloc_unique_number);
+
+/**
+ * devfs_per_cpu_register - Populate /dev/cpu/%d with a device entry.
+ *
+ * @name: The name of the entry.
+ * @flags: A set of bitwise-ORed flags (DEVFS_FL_*).
+ * @mode: The default file mode.
+ * @ops: The &file_operations or &block_device_operations structure.
+ * This must not be externally deallocated.
+ * @info: An arbitrary pointer which will be written to
+ * the @private_data field of the &file structure
+ * passed to the device driver. You can set this
+ * to whatever you like, and change it once the file
+ * is opened (the next file opened will not see this change).
+ *
+ */
+
+void devfs_per_cpu_register (const char *name, unsigned int flags,
+ unsigned int major, unsigned int minor_start,
+ umode_t mode, void *ops, void *info)
+{
+ int i;
+ char path[128];
+
+ for (i = 0; i < smp_num_cpus; i++)
+ {
+ sprintf (path, "cpu/%d/%s", i, name);
+ devfs_register (NULL, path, flags, major, minor_start + i,
+ mode, ops, info);
+ }
+} /* End Function devfs_per_cpu_register */
+EXPORT_SYMBOL(devfs_per_cpu_register);
+
+/**
+ * devfs_per_cpu_unregister - Unregister a device entry across /dev/cpu/%d
+ *
+ * @name: The name of the entry.
+ *
+ */
+
+void devfs_per_cpu_unregister (const char *name)
+{
+ int i;
+ char path[128];
+
+ for (i = smp_num_cpus - 1; i >= 0; i--)
+ {
+ sprintf (path, "cpu/%d/%s", i, name);
+ /* NOTE: `type' argument is irrelevent. We always have a name. */
+ devfs_unregister(devfs_get_handle (NULL, path, 0, 0, 0, 0));
+ }
+} /* End Function devfs_per_cpu_unregister */
+EXPORT_SYMBOL(devfs_per_cpu_unregister);
--- linux/include/linux/devfs_fs_kernel.h.1 Thu May 16 21:47:49 2002
+++ linux/include/linux/devfs_fs_kernel.h Thu May 16 21:53:01 2002
@@ -107,6 +107,11 @@ extern void devfs_register_series (devfs
                                   unsigned int flags, unsigned int major,
                                   unsigned int minor_start,
                                   umode_t mode, void *ops, void *info);
+extern void devfs_per_cpu_register (const char *name, unsigned int flags,
+ unsigned int major,
+ unsigned int minor_start, umode_t mode,
+ void *ops, void *info);
+extern void devfs_per_cpu_unregister (const char *name);
 extern int devfs_alloc_major (char type);
 extern void devfs_dealloc_major (char type, int major);
 extern kdev_t devfs_alloc_devnum (char type);
@@ -272,6 +277,19 @@ static inline void devfs_register_series
                                          unsigned int major,
                                          unsigned int minor_start,
                                          umode_t mode, void *ops, void *info)
+{
+ return;
+}
+static inline void devfs_per_cpu_register (const char *name,
+ unsigned int flags,
+ unsigned int major,
+ unsigned int minor_start,
+ umode_t mode, void *ops, void *info)
+{
+ return;
+}
+
+static inline void devfs_per_cpu_unregister (const char *name);
 {
     return;
 }
# PATCH 2: This patch uses the above functions to add devfs support to \
# the MSR and CPUID drivers.
--- linux/arch/i386/kernel/msr.c.1 Thu May 16 21:53:13 2002
+++ linux/arch/i386/kernel/msr.c Thu May 16 22:47:26 2002
@@ -34,6 +34,7 @@
 #include <linux/poll.h>
 #include <linux/smp.h>
 #include <linux/major.h>
+#include <linux/devfs_fs_kernel.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
@@ -250,18 +251,26 @@ static struct file_operations msr_fops =
 
 int __init msr_init(void)
 {
+#ifndef CONFIG_DEVFS_FS
   if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
     printk(KERN_ERR "msr: unable to get major %d for msr\n",
           MSR_MAJOR);
     return -EBUSY;
   }
-
+#else
+ devfs_per_cpu_register("msr", DEVFS_FL_DEFAULT, 202, 0,
+ S_IFCHR | S_IRUSR | S_IWUSR, &msr_fops, NULL);
+#endif
   return 0;
 }
 
 void __exit msr_exit(void)
 {
+#ifndef CONFIG_DEVFS_FS
   unregister_chrdev(MSR_MAJOR, "cpu/msr");
+#else
+ devfs_per_cpu_unregister("msr");
+#endif
 }
 
 module_init(msr_init);
--- linux/arch/i386/kernel/cpuid.c.1 Thu May 16 22:01:31 2002
+++ linux/arch/i386/kernel/cpuid.c Thu May 16 22:47:10 2002
@@ -35,6 +35,7 @@
 #include <linux/poll.h>
 #include <linux/smp.h>
 #include <linux/major.h>
+#include <linux/devfs_fs_kernel.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
@@ -142,18 +143,26 @@ static struct file_operations cpuid_fops
 
 int __init cpuid_init(void)
 {
+#ifndef CONFIG_DEVFS_FS
   if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
     printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
           CPUID_MAJOR);
     return -EBUSY;
   }
-
+#else
+ devfs_per_cpu_register("cpuid", DEVFS_FL_DEFAULT, 203, 0,
+ S_IFCHR | S_IRUSR | S_IWUSR, &cpuid_fops, NULL);
+#endif
   return 0;
 }
 
 void __exit cpuid_exit(void)
 {
+#ifndef CONFIG_DEVFS_FS
   unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+#else
+ devfs_per_cpu_unregister("cpuid");
+#endif
 }
 
 module_init(cpuid_init);





-
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 : Thu May 23 2002 - 22:00:14 EST