public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] DevFS support for /dev/cpu/X/(cpuid|msr)
@ 2002-01-06 18:17 Matt Dainty
  2002-01-06 19:34 ` Richard Gooch
  0 siblings, 1 reply; 28+ messages in thread
From: Matt Dainty @ 2002-01-06 18:17 UTC (permalink / raw)
  To: linux-kernel; +Cc: H. Peter Anvin

[-- Attachment #1: Type: text/plain, Size: 499 bytes --]

Hi,

Please find attached a patch to add support for devfs to the i386 cpuid and
msr drivers. Not only that, but it fixes a problem with loading these
drivers as modules in that the exit hooks on the module never run, (simply
changing the function prototypes to include 'static' seems to fix this).

Patch is against 2.4.17. SMP environment isn't tested, but I can't see any
reason why it wouldn't work...

Cheers

Matt
-- 
"Phased plasma rifle in a forty-watt range?"
"Hey, just what you see, pal"

[-- Attachment #2: patch-2.4.17-cpuid-msr-devfs.patch --]
[-- Type: text/plain, Size: 4306 bytes --]

diff -ur linux-2.4.17.orig/arch/i386/kernel/cpuid.c linux-2.4.17/arch/i386/kernel/cpuid.c
--- linux-2.4.17.orig/arch/i386/kernel/cpuid.c	Sat Jan  5 19:20:08 2002
+++ linux-2.4.17/arch/i386/kernel/cpuid.c	Sun Jan  6 18:09:08 2002
@@ -23,6 +23,11 @@
  *
  * This driver uses /dev/cpu/%d/cpuid where %d is the minor number, and on
  * an SMP box will direct the access to CPU %d.
+ *
+ * ChangeLog
+ *
+ * 2002-01-06	Matt Dainty <matt@bodgit-n-scarper.com>
+ *		Added support for devfs
  */
 
 #include <linux/module.h>
@@ -35,12 +40,16 @@
 #include <linux/poll.h>
 #include <linux/smp.h>
 #include <linux/major.h>
+#include <linux/threads.h>
+#include <linux/devfs_fs_kernel.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+static devfs_handle_t devfs_handle[NR_CPUS];
+
 #ifdef CONFIG_SMP
 
 struct cpuid_command {
@@ -140,24 +149,45 @@
   open:		cpuid_open,
 };
 
-int __init cpuid_init(void)
+static int __init cpuid_init(void)
 {
-  if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
+  int i;
+  char name[16];
+
+  if (devfs_register_chrdev(CPUID_MAJOR, "cpu/%d/cpuid", &cpuid_fops)) {
     printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
 	   CPUID_MAJOR);
     return -EBUSY;
   }
+  for(i = 0; i < NR_CPUS; i++) {
+    sprintf(name, "cpu/%d/cpuid", i);
+    if ((devfs_handle[i] = devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+					  CPUID_MAJOR, i,
+					  S_IFCHR | S_IRUSR | S_IRGRP,
+					  &cpuid_fops, NULL)) == NULL) {
+      printk(KERN_ERR "cpuid: failed to devfs_register()\n");
+    }
+  }
 
   return 0;
 }
 
-void __exit cpuid_exit(void)
+static void __exit cpuid_exit(void)
 {
-  unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+  int i;
+  devfs_handle_t parent;
+
+  for(i = 0; i < NR_CPUS; i++) {
+    parent = devfs_get_parent(devfs_handle[i]);
+    devfs_unregister(devfs_handle[i]);
+    if(devfs_get_first_child(parent) == NULL)
+      devfs_unregister(parent);
+  }
+  devfs_unregister_chrdev(CPUID_MAJOR, "cpu/%d/cpuid");
 }
 
 module_init(cpuid_init);
-module_exit(cpuid_exit)
+module_exit(cpuid_exit);
 
 EXPORT_NO_SYMBOLS;
 
diff -ur linux-2.4.17.orig/arch/i386/kernel/msr.c linux-2.4.17/arch/i386/kernel/msr.c
--- linux-2.4.17.orig/arch/i386/kernel/msr.c	Sat Jan  5 19:20:08 2002
+++ linux-2.4.17/arch/i386/kernel/msr.c	Sun Jan  6 18:09:18 2002
@@ -22,6 +22,11 @@
  *
  * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
  * an SMP box will direct the access to CPU %d.
+ *
+ * ChangeLog
+ *
+ * 2002-01-06   Matt Dainty <matt@bodgit-n-scarper.com>
+ *              Added support for devfs
  */
 
 #include <linux/module.h>
@@ -34,12 +39,16 @@
 #include <linux/poll.h>
 #include <linux/smp.h>
 #include <linux/major.h>
+#include <linux/threads.h>
+#include <linux/devfs_fs_kernel.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+static devfs_handle_t devfs_handle[NR_CPUS];
+
 /* Note: "err" is handled in a funny way below.  Otherwise one version
    of gcc or another breaks. */
 
@@ -248,24 +257,45 @@
   open:		msr_open,
 };
 
-int __init msr_init(void)
+static int __init msr_init(void)
 {
-  if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
+  int i;
+  char name[16];
+
+  if (devfs_register_chrdev(MSR_MAJOR, "cpu/%d/msr", &msr_fops)) {
     printk(KERN_ERR "msr: unable to get major %d for msr\n",
 	   MSR_MAJOR);
     return -EBUSY;
   }
+  for(i = 0; i < NR_CPUS; i++) {
+    sprintf(name, "cpu/%d/msr", i);
+    if ((devfs_handle[i] = devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+					  MSR_MAJOR, i,
+					  S_IFCHR | S_IRUSR | S_IRGRP | S_IWUSR,
+					  &msr_fops, NULL)) == NULL) {
+      printk(KERN_ERR "msr: failed to devfs_register()\n");
+    }
+  }
   
   return 0;
 }
 
-void __exit msr_exit(void)
+static void __exit msr_exit(void)
 {
-  unregister_chrdev(MSR_MAJOR, "cpu/msr");
+  int i;
+  devfs_handle_t parent;
+
+  for(i = 0; i < NR_CPUS; i++) {
+    parent = devfs_get_parent(devfs_handle[i]);
+    devfs_unregister(devfs_handle[i]);
+    if(devfs_get_first_child(parent) == NULL)
+      devfs_unregister(parent);
+  }
+  devfs_unregister_chrdev(MSR_MAJOR, "cpu/%d/msr");
 }
 
 module_init(msr_init);
-module_exit(msr_exit)
+module_exit(msr_exit);
 
 EXPORT_NO_SYMBOLS;
 

^ permalink raw reply	[flat|nested] 28+ messages in thread
* Re: [PATCH] DevFS support for /dev/cpu/X/(cpuid|msr)
@ 2002-02-18 10:50 Ishan Jayawardena
  2002-02-18 18:25 ` Richard Gooch
  0 siblings, 1 reply; 28+ messages in thread
From: Ishan Jayawardena @ 2002-02-18 10:50 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 570 bytes --]

Perhaps this will suit your taste better...

I'd love to extend this work to support Paul Russell's hotplug cpu work, but 
I have absolutely no way at present to test it. (If some kind party would 
like to donate a quad pentium 4 Xeon with hotplug cpu support, I'll be more 
than happy to do so ;)

This is against 2.4.18-pre9-ac4 with devfs v199.9

Relevent comments, advise, improvisations, flames, welcome.

I. O. Jayawardena
.



_________________________________________________________________
Send and receive Hotmail on your mobile device: http://mobile.msn.com

[-- Attachment #2: devfs.patch --]
[-- Type: application/octet-stream, Size: 8004 bytes --]

--- linux/fs/devfs/base.c	Mon Feb 18 16:07:49 2002
+++ linux-ioj/fs/devfs/base.c	Mon Feb 18 12:45:42 2002
@@ -631,6 +631,7 @@
 #include <linux/init.h>
 #include <linux/devfs_fs.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/threads.h>
 #include <linux/smp_lock.h>
 #include <linux/smp.h>
 #include <linux/version.h>
@@ -1624,6 +1625,72 @@ devfs_handle_t devfs_register (devfs_han
 
 
 /**
+ * 	devfs_register_per_cpu - register a device node across all 
+ *		cpu-specific directories.
+ *	@leafname - the name of the device node
+ *
+ *	All other parameters are for devfs_register(). Returns zero on success.
+ */
+
+int devfs_register_per_cpu (const char *leafname, unsigned int flags, 
+			unsigned int major, unsigned int minor_start,
+			umode_t mode, void *ops, void *info)
+{
+    int i;
+    char *name;
+    char tmp[5] = { "0" }; /* FIXME: this string may overflow, but we don't know
+			the sizeof smp_num_cpus until we get it into a string */
+
+    if (smp_num_cpus > 1) sprintf (tmp, "%d", smp_num_cpus - 1);
+    name = kmalloc (strlen (leafname) + strlen (tmp) + sizeof (char) * 6, 
+			GFP_KERNEL);
+    if (!name) return -ENOMEM;
+    for(i = 0; i < smp_num_cpus; i++) {
+	sprintf (name, "cpu/%d/%s", i, leafname);
+	if (!devfs_register (NULL, name, flags, major, minor_start + i, 
+					mode, ops, info)) {
+	    PRINTK ("(): devfs_register() failed.\n");
+	    kfree (name);
+	    return -EAGAIN;
+	}
+    }
+    kfree (name);
+    return 0;
+} /* End function devfs_register_per_cpu */
+
+
+/**
+ *	devfs_unregister_per_cpu - unregister a node across /dev/cpu/
+ *	@leafname - the name of the device node
+ *
+ *	Unregisters a number of nodes (probably registered with
+ *	devfs_register_per_cpu() )
+ */
+
+void devfs_unregister_per_cpu (const char *leafname)
+{
+    int i;
+    char *name;
+    char tmp[5] = { "0" };
+    devfs_handle_t dh;
+
+    if (smp_num_cpus > 1) sprintf (tmp, "%d", smp_num_cpus - 1);
+    name = kmalloc (strlen (leafname) + strlen (tmp) + sizeof (char) * 6,
+			GFP_KERNEL);
+    if (!name) return;
+    for (i = 0; i < smp_num_cpus; i++) {
+	sprintf (name, "cpu/%d/%s", i, leafname);
+	dh = _devfs_walk_path (NULL, name, strlen (name), 0);
+	if (!dh) {
+	    kfree (name);
+	    return;
+	}
+	devfs_unregister (dh);
+    }
+    kfree (name);
+} /* End function devfs_unregister_per_cpu */
+
+/**
  *	_devfs_unhook - Unhook a device entry from its parents list
  *	@de: The entry to unhook.
  *
@@ -2355,7 +2422,9 @@ __setup("devfs=", devfs_setup);
 
 EXPORT_SYMBOL(devfs_put);
 EXPORT_SYMBOL(devfs_register);
+EXPORT_SYMBOL(devfs_register_per_cpu);
 EXPORT_SYMBOL(devfs_unregister);
+EXPORT_SYMBOL(devfs_unregister_per_cpu);
 EXPORT_SYMBOL(devfs_mk_symlink);
 EXPORT_SYMBOL(devfs_mk_dir);
 EXPORT_SYMBOL(devfs_get_handle);
@@ -3172,6 +3241,17 @@ static int devfs_mknod (struct inode *di
 			  inode->i_uid, inode->i_gid, fs_info, 0);
     return 0;
 }   /*  End Function devfs_mknod  */
+
+void devfs_mk_dir_per_cpu (void)
+{
+    int i;
+    char name[7];
+
+    for (i = 0; i < smp_num_cpus; i++) {
+	sprintf (name, "cpu/%d", i);
+	devfs_mk_dir (NULL, name, NULL);
+    }
+}
 
 static int devfs_readlink (struct dentry *dentry, char *buffer, int buflen)
 {
--- linux/include/linux/devfs_fs_kernel.h	Mon Feb 18 16:05:21 2002
+++ linux-ioj/include/linux/devfs_fs_kernel.h	Mon Feb 18 14:08:38 2002
@@ -73,12 +73,17 @@ extern devfs_handle_t devfs_register (de
 				      unsigned int flags,
 				      unsigned int major, unsigned int minor,
 				      umode_t mode, void *ops, void *info);
+extern int devfs_register_per_cpu (const char *leafname, unsigned int flags,
+				   unsigned int major, unsigned int minor_start,
+				   umode_t mode, void *ops, void *info);
 extern void devfs_unregister (devfs_handle_t de);
+extern void devfs_unregister_per_cpu (const char *leafname);
 extern int devfs_mk_symlink (devfs_handle_t dir, const char *name,
 			     unsigned int flags, const char *link,
 			     devfs_handle_t *handle, void *info);
 extern devfs_handle_t devfs_mk_dir (devfs_handle_t dir, const char *name,
 				    void *info);
+extern void devfs_mk_dir_per_cpu (void);
 extern devfs_handle_t devfs_get_handle (devfs_handle_t dir, const char *name,
 					unsigned int major,unsigned int minor,
 					char type, int traverse_symlinks);
@@ -149,9 +154,20 @@ static inline devfs_handle_t devfs_regis
 {
     return NULL;
 }
+static inline int devfs_register_per_cpu (const char *name,
+					  unsigned int flags, 
+					  unsigned int major, 
+					  unsigned int minor_start,
+					  umode_t mode, void *ops, void *info);
+{
+    return NULL;
+}
 static inline void devfs_unregister (devfs_handle_t de)
 {
-    return;
+}
+static inline void devfs_unregister_per_cpu (const char *name)
+{
+    return NULL;
 }
 static inline int devfs_mk_symlink (devfs_handle_t dir, const char *name,
 				    unsigned int flags, const char *link,
@@ -163,6 +179,9 @@ static inline devfs_handle_t devfs_mk_di
 					   const char *name, void *info)
 {
     return NULL;
+}
+static inline void devfs_mk_dir_per_cpu (void)
+{
 }
 static inline devfs_handle_t devfs_get_handle (devfs_handle_t dir,
 					       const char *name,
--- linux/init/main.c	Mon Feb 18 16:07:37 2002
+++ linux-ioj/init/main.c	Sun Feb 17 23:26:43 2002
@@ -497,9 +497,13 @@ unsigned long wait_init_idle;
 static void __init smp_init(void)
 {
 	APIC_init_uniprocessor();
+
+	devfs_mk_dir_per_cpu();
 }
 #else
-#define smp_init()	do { } while (0)
+#define smp_init()	do { \
+		devfs_mk_dir_per_cpu(); \
+	} while (0)
 #endif
 
 #else
@@ -523,6 +527,8 @@ static void __init smp_init(void)
 		barrier();
 	}
 	printk("All processors have done init_idle\n");
+
+	devfs_mk_dir_per_cpu();
 }
 
 #endif
--- linux/arch/i386/kernel/cpuid.c	Thu Oct 11 12:04:57 2001
+++ linux-ioj/arch/i386/kernel/cpuid.c	Mon Feb 18 15:19:32 2002
@@ -32,6 +32,7 @@
 #include <linux/errno.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
+#include <linux/devfs_fs_kernel.h>
 #include <linux/poll.h>
 #include <linux/smp.h>
 #include <linux/major.h>
@@ -140,24 +141,26 @@ static struct file_operations cpuid_fops
   open:		cpuid_open,
 };
 
-int __init cpuid_init(void)
+static int __init cpuid_init(void)
 {
-  if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
+  if (devfs_register_chrdev(CPUID_MAJOR, "cpu/%d/cpuid", &cpuid_fops)) {
     printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
 	   CPUID_MAJOR);
     return -EBUSY;
   }
 
-  return 0;
+  return devfs_register_per_cpu("cpuid", DEVFS_FL_DEFAULT, CPUID_MAJOR, 0,
+		S_IFCHR | S_IRUSR | S_IRGRP, &cpuid_fops, NULL);
 }
 
 void __exit cpuid_exit(void)
 {
-  unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+  devfs_unregister_chrdev(CPUID_MAJOR, "cpu/%d/cpuid");
+  devfs_unregister_per_cpu("cpuid");
 }
 
 module_init(cpuid_init);
-module_exit(cpuid_exit)
+module_exit(cpuid_exit);
 
 EXPORT_NO_SYMBOLS;
 
--- linux/arch/i386/kernel/msr.c	Thu Oct 11 12:04:57 2001
+++ linux-ioj/arch/i386/kernel/msr.c	Mon Feb 18 15:19:05 2002
@@ -31,6 +31,7 @@
 #include <linux/errno.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
+#include <linux/devfs_fs_kernel.h>
 #include <linux/poll.h>
 #include <linux/smp.h>
 #include <linux/major.h>
@@ -248,24 +249,26 @@ static struct file_operations msr_fops =
   open:		msr_open,
 };
 
-int __init msr_init(void)
+static int __init msr_init(void)
 {
-  if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
+  if (devfs_register_chrdev(MSR_MAJOR, "cpu/%d/msr", &msr_fops)) {
     printk(KERN_ERR "msr: unable to get major %d for msr\n",
 	   MSR_MAJOR);
     return -EBUSY;
   }
   
-  return 0;
+  return devfs_register_per_cpu("msr", DEVFS_FL_DEFAULT, MSR_MAJOR, 0,
+			S_IFCHR | S_IRUSR | S_IRGRP, &msr_fops, NULL);
 }
 
 void __exit msr_exit(void)
 {
-  unregister_chrdev(MSR_MAJOR, "cpu/msr");
+  devfs_unregister_chrdev(MSR_MAJOR, "cpu/%d/msr");
+  devfs_unregister_per_cpu("msr");
 }
 
 module_init(msr_init);
-module_exit(msr_exit)
+module_exit(msr_exit);
 
 EXPORT_NO_SYMBOLS;
 

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2002-02-18 18:38 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-01-06 18:17 [PATCH] DevFS support for /dev/cpu/X/(cpuid|msr) Matt Dainty
2002-01-06 19:34 ` Richard Gooch
2002-01-06 20:43   ` Matt Dainty
2002-01-06 21:08     ` H. Peter Anvin
2002-01-06 21:11       ` Richard Gooch
2002-01-06 21:12         ` H. Peter Anvin
2002-01-06 21:06   ` H. Peter Anvin
2002-01-06 21:08     ` Richard Gooch
2002-01-06 21:10       ` H. Peter Anvin
2002-01-06 21:36         ` Russell King
2002-01-07  0:44           ` H. Peter Anvin
2002-01-07  1:31         ` Richard Gooch
2002-01-07  1:32           ` H. Peter Anvin
2002-01-07  1:40             ` Richard Gooch
2002-01-07  1:44               ` H. Peter Anvin
2002-01-08 11:13               ` Matt Dainty
2002-01-08  9:14                 ` Rusty Russell
2002-01-08 12:02                   ` Matt Dainty
2002-01-08 17:35                     ` Richard Gooch
2002-01-08 17:17                   ` H. Peter Anvin
2002-01-09  1:01                     ` Rusty Russell
2002-01-09  3:16                       ` H. Peter Anvin
2002-01-09  3:28                         ` Rusty Russell
2002-01-09  3:30                         ` Richard Gooch
2002-01-09  3:47                           ` H. Peter Anvin
2002-01-09  5:41                             ` Richard Gooch
  -- strict thread matches above, loose matches on Subject: below --
2002-02-18 10:50 Ishan Jayawardena
2002-02-18 18:25 ` Richard Gooch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox