[patch-2.3.49-pre1] /dev/cpu/microcode v1.03

From: Tigran Aivazian (tigran@aivazian.fsnet.co.uk)
Date: Tue Feb 29 2000 - 16:53:05 EST


Hi Linus,

This patch updates the P6 microcode driver to use devfs and adds a couple
of cleanups. Please consider it.

  http://www.ocston.org/~tigran/patches/microcode/mc-2.3.49-p1.patch

Regards,
Tigran

diff -urN -X dontdiff linux/Documentation/Configure.help linux-mc/Documentation/Configure.help
--- linux/Documentation/Configure.help Sun Feb 27 04:32:12 2000
+++ linux-mc/Documentation/Configure.help Tue Feb 29 21:39:38 2000
@@ -11113,13 +11113,15 @@
   Intel processors in P6 family, e.g. Pentium Pro, Pentium II,
   Pentium III, Xeon etc. You will obviously need the actual microcode
   binary data itself which is not shipped with the Linux kernel.
- Contact Intel to obtain the latest revision of microcode for
- your CPU(s). With this support compiled you can use dd(1) to write
- microcode, for example:
+ With this support compiled you can use dd(1) to write microcode,
+ for example:
 
- # dd if=/etc/microcode of=/proc/driver/microcode bs=98304 count=1
+ # dd if=/etc/microcode of=/dev/cpu/microcode bs=98304 count=1
 
- You need to be superuser to do that.
+ You need to be superuser to do that. For latest news and information
+ on obtaining all the required ingredients for this driver, check:
+
+ http://www.ocston.org/~tigran/patches/microcode
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
diff -urN -X dontdiff linux/arch/i386/config.in linux-mc/arch/i386/config.in
--- linux/arch/i386/config.in Mon Feb 21 04:37:09 2000
+++ linux-mc/arch/i386/config.in Tue Feb 29 19:35:48 2000
@@ -49,8 +49,8 @@
    define_bool CONFIG_X86_USE_3DNOW y
 fi
 
-if [ "$CONFIG_PROC_FS" = "y" ]; then
- tristate '/proc/driver/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE
+if [ "$CONFIG_DEVFS_FS" = "y" ]; then
+ tristate '/dev/cpu/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE
 fi
 
 choice 'High Memory Support' \
diff -urN -X dontdiff linux/arch/i386/kernel/Makefile linux-mc/arch/i386/kernel/Makefile
--- linux/arch/i386/kernel/Makefile Wed Feb 16 22:36:52 2000
+++ linux-mc/arch/i386/kernel/Makefile Tue Feb 29 19:35:48 2000
@@ -40,14 +40,12 @@
   endif
 endif
 
-ifeq ($(CONFIG_PROC_FS),y)
 ifeq ($(CONFIG_MICROCODE),y)
 OX_OBJS += microcode.o
 else
   ifeq ($(CONFIG_MICROCODE),m)
   MX_OBJS += microcode.o
   endif
-endif
 endif
 
 ifeq ($(CONFIG_ACPI),y)
diff -urN -X dontdiff linux/arch/i386/kernel/microcode.c linux-mc/arch/i386/kernel/microcode.c
--- linux/arch/i386/kernel/microcode.c Sun Feb 27 04:33:02 2000
+++ linux-mc/arch/i386/kernel/microcode.c Tue Feb 29 19:35:48 2000
@@ -23,20 +23,23 @@
  * 1.02 21 February 2000, Tigran Aivazian <tigran@sco.com>
  * Added 'device trimming' support. open(O_WRONLY) zeroes
  * and frees the saved copy of applied microcode.
+ * 1.03 29 February 2000, Tigran Aivazian <tigran@sco.com>
+ * Made to use devfs (/dev/cpu/microcode) + cleanups.
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
-#include <linux/proc_fs.h>
+#include <linux/devfs_fs_kernel.h>
 
 #include <asm/msr.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 
-#define MICROCODE_VERSION "1.02"
+#define MICROCODE_VERSION "1.03"
 
 MODULE_DESCRIPTION("CPU (P6) microcode update driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@ocston.org>");
@@ -60,9 +63,10 @@
 static unsigned long microcode_status = 0;
 
 /* the actual array of microcode blocks, each 2048 bytes */
-static struct microcode * microcode = NULL;
+static struct microcode *microcode = NULL;
 static unsigned int microcode_num = 0;
 static char *mc_applied = NULL; /* holds an array of applied microcode blocks */
+static unsigned int mc_fsize; /* used often, so compute once at microcode_init() */
 
 static struct file_operations microcode_fops = {
         read: microcode_read,
@@ -71,23 +75,25 @@
         release: microcode_release,
 };
 
-static struct proc_dir_entry *proc_microcode;
+static devfs_handle_t devfs_handle;
 
 static int __init microcode_init(void)
 {
- proc_microcode = create_proc_entry("microcode", S_IWUSR|S_IRUSR, proc_root_driver);
- if (!proc_microcode) {
- printk(KERN_ERR "microcode: can't create /proc/driver/microcode\n");
- return -ENOMEM;
- }
- proc_microcode->proc_fops = &microcode_fops;
+ devfs_handle = devfs_register(NULL, "cpu/microcode", 0, DEVFS_FL_DEFAULT, 0, 0,
+ S_IFREG | S_IRUSR | S_IWUSR, 0, 0, &microcode_fops, NULL);
+ if (!devfs_handle) {
+ printk(KERN_ERR "microcode: can't create /dev/cpu/microcode\n");
+ return -ENOMEM;
+ }
+ /* XXX assume no hotplug CPUs so smp_num_cpus does not change */
+ mc_fsize = smp_num_cpus * sizeof(struct microcode);
         printk(KERN_INFO "P6 Microcode Update Driver v%s registered\n", MICROCODE_VERSION);
         return 0;
 }
 
 static void __exit microcode_exit(void)
 {
- remove_proc_entry("microcode", proc_root_driver);
+ devfs_unregister(devfs_handle);
         if (mc_applied)
                 kfree(mc_applied);
         printk(KERN_INFO "P6 Microcode Update Driver v%s unregistered\n", MICROCODE_VERSION);
@@ -108,25 +114,21 @@
         if (test_and_set_bit(MICROCODE_IS_OPEN, &microcode_status))
                 return -EBUSY;
 
- if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
- proc_microcode->size = 0;
- if (mc_applied) {
- memset(mc_applied, 0, smp_num_cpus * sizeof(struct microcode));
- kfree(mc_applied);
- mc_applied = NULL;
- }
+ if ((file->f_flags & O_ACCMODE) == O_WRONLY && mc_applied) {
+ devfs_set_file_size(devfs_handle, 0);
+ memset(mc_applied, 0, mc_fsize);
+ kfree(mc_applied);
+ mc_applied = NULL;
         }
 
         MOD_INC_USE_COUNT;
-
         return 0;
 }
 
 static int microcode_release(struct inode *inode, struct file *file)
 {
- MOD_DEC_USE_COUNT;
-
         clear_bit(MICROCODE_IS_OPEN, &microcode_status);
+ MOD_DEC_USE_COUNT;
         return 0;
 }
 
@@ -156,19 +158,17 @@
                         memcpy(m, &microcode[update_req[i].slot], sizeof(struct microcode));
                 }
         }
- return error ? -EIO : 0;
+ return error;
 }
 
 static void do_update_one(void *arg)
 {
- struct update_req *req;
- struct cpuinfo_x86 * c;
+ int cpu_num = smp_processor_id();
+ struct cpuinfo_x86 *c = cpu_data + cpu_num;
+ struct update_req *req = (struct update_req *)arg + cpu_num;
         unsigned int pf = 0, val[2], rev, sig;
- int i, cpu_num;
+ int i;
 
- cpu_num = smp_processor_id();
- c = cpu_data + cpu_num;
- req = (struct update_req *)arg + cpu_num;
         req->err = 1; /* be pessimistic */
 
         if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6)
@@ -210,8 +210,8 @@
 
                                 req->err = 0;
                                 req->slot = i;
- printk(KERN_ERR "microcode: CPU%d microcode updated "
- "from revision %d to %d, date=%08x\n",
+ printk(KERN_ERR "microcode: CPU%d updated from revision "
+ "%d to %d, date=%08x\n",
                                                 cpu_num, rev, val[1], m->date);
                         }
                         break;
@@ -220,12 +220,10 @@
 
 static ssize_t microcode_read(struct file *file, char *buf, size_t len, loff_t *ppos)
 {
- size_t fsize = smp_num_cpus * sizeof(struct microcode);
-
- if (!proc_microcode->size || *ppos >= fsize)
- return 0; /* EOF */
- if (*ppos + len > fsize)
- len = fsize - *ppos;
+ if (*ppos >= mc_fsize)
+ return 0;
+ if (*ppos + len > mc_fsize)
+ len = mc_fsize - *ppos;
         if (copy_to_user(buf, mc_applied + *ppos, len))
                 return -EFAULT;
         *ppos += len;
@@ -242,33 +240,34 @@
                 return -EINVAL;
         }
         if (!mc_applied) {
- int size = smp_num_cpus * sizeof(struct microcode);
- mc_applied = kmalloc(size, GFP_KERNEL);
+ mc_applied = kmalloc(mc_fsize, GFP_KERNEL);
                 if (!mc_applied) {
- printk(KERN_ERR "microcode: can't allocate memory for saved microcode\n");
+ printk(KERN_ERR "microcode: out of memory for saved microcode\n");
                         return -ENOMEM;
                 }
- memset(mc_applied, 0, size);
+ memset(mc_applied, 0, mc_fsize);
         }
         
         lock_kernel();
         microcode_num = len/sizeof(struct microcode);
         microcode = vmalloc(len);
         if (!microcode) {
- unlock_kernel();
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out_unlock;
         }
         if (copy_from_user(microcode, buf, len)) {
- vfree(microcode);
- unlock_kernel();
- return -EFAULT;
- }
- ret = do_microcode_update();
- if (!ret) {
- proc_microcode->size = smp_num_cpus * sizeof(struct microcode);
- ret = (ssize_t)len;
+ ret = -EFAULT;
+ goto out_vfree;
         }
+ if(do_microcode_update()) {
+ ret = -EIO;
+ goto out_vfree;
+ }
+ devfs_set_file_size(devfs_handle, mc_fsize);
+ ret = (ssize_t)len;
+out_vfree:
         vfree(microcode);
+out_unlock:
         unlock_kernel();
         return ret;
 }

-
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 : Tue Feb 29 2000 - 21:00:23 EST