--- 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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;