[patch] Makes cpuid and msr drivers devfs aware

From: Langdale, Philip (philipl@mail.utexas.edu)
Date: Wed Jul 05 2000 - 05:40:51 EST


Hi all,

This is my first ( attempted ) contribution, so try
not to laugh too hard. :-)

Notes:

- SMP aware, but I don't have an smp box to confirm this.

- Doesn't attempt to remove individual cpu directories as
  there is no clean method to do so right now, and Richard
  has pointed out that there might be reason to keep them
  as they indicate the existance of said cpus. Suits me :-)

- Currently allows for up to 999 cpus before buffer overflow.
  Probably sufficent for the time being. :-)

- Unregisters major device on exit ( which was missing before ).

I'm not sure what the 'done thing' is when it comes to implementing
devfs support. Some drivers use #ifdef and others rely on the stub
functions in the devfs_fs_kernel.h header. I went with the first
method as there doesn't seem to be much point iterating through
the cpus to do nothing.

So, enjoy, I guess. :-)

--phil

diff -u -r linux-2.4.0-test3-pre2/arch/i386/kernel/cpuid.c linux-2.4.0-test3-pre2-new/arch/i386/kernel/cpuid.c
--- linux-2.4.0-test3-pre2/arch/i386/kernel/cpuid.c Mon Jun 26 11:18:10 2000
+++ linux-2.4.0-test3-pre2-new/arch/i386/kernel/cpuid.c Wed Jul 5 18:09:45 2000
@@ -2,6 +2,7 @@
 /* ----------------------------------------------------------------------- *
  *
  * Copyright 2000 H. Peter Anvin - All Rights Reserved
+ * Copyright 2000 Philip Langdale - All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,6 +42,19 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+#ifdef CONFIG_DEVFS_FS
+
+#include <linux/devfs_fs_kernel.h>
+
+static devfs_handle_t cpu_devfs_handle = NULL;
+
+#ifndef TRUE
+# define TRUE 1
+# define FALSE 0
+#endif /* TRUE */
+
+#endif /* CONFIG_DEVFS_FS */
+
 #ifdef CONFIG_SMP
 
 struct cpuid_command {
@@ -142,17 +156,56 @@
 
 int __init cpuid_init(void)
 {
- if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
- printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
- CPUID_MAJOR);
+#ifdef CONFIG_DEVFS_FS
+ int minor;
+ char minor_string[10];
+
+ cpu_devfs_handle = devfs_find_handle(NULL,"cpu",0,0,0,FALSE);
+ if ( !cpu_devfs_handle ) {
+ printk(KERN_ERR "cpuid: unable to find cpu/ directory\n");
+ return -EBUSY;
+ }
+ for( minor=0 ; minor<smp_num_cpus ; minor++ )
+ {
+ sprintf(minor_string,"%d/cpuid",minor);
+ if (!devfs_register(cpu_devfs_handle, minor_string, DEVFS_FL_DEFAULT,
+ CPUID_MAJOR, minor, S_IFCHR | S_IRUGO | S_IWUSR,
+ &cpuid_fops, NULL)) {
+ printk(KERN_ERR "cpuid: unable to register cpuid for cpu %d\n",minor);
+ return -EBUSY;
+ }
+ }
+ if ( devfs_register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops) ) {
+#else /* CONFIG_DEVFS_FS */
+ if ( register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops) ) {
+#endif /* CONFIG_DEVFS_FS */
+ printk(KERN_ERR "cpuid: unable to register char major %d\n", CPUID_MAJOR);
     return -EBUSY;
   }
-
   return 0;
 }
 
 void __exit cpuid_exit(void)
 {
+#ifdef CONFIG_DEVFS_FS
+ int minor;
+ char minor_string[10];
+ static devfs_handle_t cpuid_node_devfs_handle;
+
+ for( minor=0 ; minor<smp_num_cpus ; minor++ ) {
+ cpuid_node_devfs_handle = NULL;
+ sprintf(minor_string,"%d/cpuid",minor);
+ cpuid_node_devfs_handle = devfs_find_handle(cpu_devfs_handle,minor_string,
+ CPUID_MAJOR,minor,0,FALSE);
+ if ( !cpuid_node_devfs_handle )
+ printk(KERN_ERR "cpuid: unable to find cpuid for cpu %d\n",minor);
+ devfs_unregister(cpuid_node_devfs_handle);
+ }
+ if ( devfs_unregister_chrdev(CPUID_MAJOR,"cpu/cpuid") )
+#else
+ if ( unregister_chrdev(CPUID_MAJOR,"cpu/cpuid") )
+#endif /* CONFIG_DEVFS_FS */
+ printk(KERN_ERR "cpuid: unable to unregister char major %d\n", CPUID_MAJOR);
 }
 
 module_init(cpuid_init);
diff -u -r linux-2.4.0-test3-pre2/arch/i386/kernel/msr.c linux-2.4.0-test3-pre2-new/arch/i386/kernel/msr.c
--- linux-2.4.0-test3-pre2/arch/i386/kernel/msr.c Mon Jun 26 11:18:10 2000
+++ linux-2.4.0-test3-pre2-new/arch/i386/kernel/msr.c Wed Jul 5 18:10:06 2000
@@ -2,6 +2,7 @@
 /* ----------------------------------------------------------------------- *
  *
  * Copyright 2000 H. Peter Anvin - All Rights Reserved
+ * Copyright 2000 Philip Langdale - All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,6 +41,19 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+#ifdef CONFIG_DEVFS_FS
+
+#include <linux/devfs_fs_kernel.h>
+
+static devfs_handle_t cpu_devfs_handle = NULL;
+
+#ifndef TRUE
+# define TRUE 1
+# define FALSE 0
+#endif /* TRUE */
+
+#endif /* CONFIG_DEVFS_FS */
+
 /* Note: "err" is handled in a funny way below. Otherwise one version
    of gcc or another breaks. */
 
@@ -250,17 +264,56 @@
 
 int __init msr_init(void)
 {
- if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
- printk(KERN_ERR "msr: unable to get major %d for msr\n",
- MSR_MAJOR);
+#ifdef CONFIG_DEVFS_FS
+ int minor;
+ char minor_string[8];
+
+ cpu_devfs_handle = devfs_find_handle(NULL,"cpu",0,0,0,FALSE);
+ if(!cpu_devfs_handle) {
+ printk(KERN_ERR "msr: unable to find cpu/ directory\n");
+ return -EBUSY;
+ }
+ for( minor=0 ; minor<smp_num_cpus ; minor++ ) {
+ sprintf(minor_string,"%d/msr",minor);
+ if (!devfs_register(cpu_devfs_handle, minor_string, DEVFS_FL_DEFAULT,
+ MSR_MAJOR, minor, S_IFCHR | S_IRUSR | S_IWUSR,
+ &msr_fops, NULL)) {
+ printk(KERN_ERR "msr: unable to register msr for cpu %d\n",minor);
+ return -EBUSY;
+ }
+ }
+
+ if ( devfs_register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops) ) {
+#else
+ if ( register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops) ) {
+#endif /* CONFIG_DEVFS_FS */
+ printk(KERN_ERR "msr: unable to register char major %d\n", MSR_MAJOR);
     return -EBUSY;
   }
-
   return 0;
 }
 
 void __exit msr_exit(void)
 {
+#ifdef CONFIG_DEVFS_FS
+ int minor;
+ char minor_string[8];
+ static devfs_handle_t msr_node_devfs_handle;
+
+ for( minor=0 ; minor<smp_num_cpus ; minor++ ) {
+ msr_node_devfs_handle = NULL;
+ sprintf(minor_string,"%d/msr",minor);
+ msr_node_devfs_handle = devfs_find_handle(cpu_devfs_handle,minor_string,
+ CPUID_MAJOR,minor,0,FALSE);
+ if(!msr_node_devfs_handle)
+ printk(KERN_ERR "msr: unable to find msr for cpu %d\n",minor);
+ devfs_unregister(msr_node_devfs_handle);
+ }
+ if( devfs_unregister_chrdev(MSR_MAJOR,"cpu/msr") )
+#else /* CONFIG_DEVFS_FS */
+ if( unregister_chrdev(MSR_MAJOR,"cpu/msr") )
+#endif /* CONFIG_DEVFS_FS */
+ printk(KERN_ERR "msr: unable to unregister char major %d\n", MSR_MAJOR);
 }
 
 module_init(msr_init);

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



This archive was generated by hypermail 2b29 : Fri Jul 07 2000 - 21:00:16 EST