Messages in this thread Patch in this message | | | Date | Wed, 05 Jul 2000 18:40:51 +0800 | From | "Langdale, Philip" <> | Subject | [patch] Makes cpuid and msr drivers devfs aware |
| |
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/
| |