fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / ppc64 / kernel / nvram.c
index 89d6a0a..4e71781 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/rtas.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
+#include <asm/systemcfg.h>
 
 #undef DEBUG_NVRAM
 
@@ -43,9 +44,9 @@ static struct nvram_partition * nvram_part;
 static long nvram_error_log_index = -1;
 static long nvram_error_log_size = 0;
 
-volatile int no_more_logging = 1; /* Until we initialize everything,
-                                  * make sure we don't try logging
-                                  * anything */
+int no_logging = 1;    /* Until we initialize everything,
+                        * make sure we don't try logging
+                        * anything */
 
 extern volatile int error_log_cnt;
 
@@ -77,7 +78,7 @@ static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
 }
 
 
-static ssize_t dev_nvram_read(struct file *file, char *buf,
+static ssize_t dev_nvram_read(struct file *file, char __user *buf,
                          size_t count, loff_t *ppos)
 {
        ssize_t len;
@@ -88,7 +89,7 @@ static ssize_t dev_nvram_read(struct file *file, char *buf,
                return -ENODEV;
        size = ppc_md.nvram_size();
 
-       if (verify_area(VERIFY_WRITE, buf, count))
+       if (!access_ok(VERIFY_WRITE, buf, count))
                return -EFAULT;
        if (*ppos >= size)
                return 0;
@@ -117,7 +118,7 @@ static ssize_t dev_nvram_read(struct file *file, char *buf,
 
 }
 
-static ssize_t dev_nvram_write(struct file *file, const char *buf,
+static ssize_t dev_nvram_write(struct file *file, const char __user *buf,
                           size_t count, loff_t *ppos)
 {
        ssize_t len;
@@ -128,7 +129,7 @@ static ssize_t dev_nvram_write(struct file *file, const char *buf,
                return -ENODEV;
        size = ppc_md.nvram_size();
 
-       if (verify_area(VERIFY_READ, buf, count))
+       if (!access_ok(VERIFY_READ, buf, count))
                return -EFAULT;
        if (*ppos >= size)
                return 0;
@@ -338,9 +339,9 @@ static int nvram_remove_os_partition(void)
 static int nvram_create_os_partition(void)
 {
        struct list_head * p;
-       struct nvram_partition * part;
-       struct nvram_partition * new_part = NULL;
-       struct nvram_partition * free_part;
+       struct nvram_partition *part = NULL;
+       struct nvram_partition *new_part = NULL;
+       struct nvram_partition *free_part = NULL;
        int seq_init[2] = { 0, 0 };
        loff_t tmp_index;
        long size = 0;
@@ -363,13 +364,11 @@ static int nvram_create_os_partition(void)
                        free_part = part;
                }
        }
-       if (!size) {
+       if (!size)
                return -ENOSPC;
-       }
        
        /* Create our OS partition */
-       new_part = (struct nvram_partition *)
-               kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+       new_part = kmalloc(sizeof(*new_part), GFP_KERNEL);
        if (!new_part) {
                printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n");
                return -ENOMEM;
@@ -378,7 +377,7 @@ static int nvram_create_os_partition(void)
        new_part->index = free_part->index;
        new_part->header.signature = NVRAM_SIG_OS;
        new_part->header.length = size;
-       sprintf(new_part->header.name, "ppc64,linux");
+       strcpy(new_part->header.name, "ppc64,linux");
        new_part->header.checksum = nvram_checksum(&new_part->header);
 
        rc = nvram_write_header(new_part);
@@ -393,7 +392,8 @@ static int nvram_create_os_partition(void)
        tmp_index = new_part->index + NVRAM_HEADER_LEN;
        rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index);
        if (rc <= 0) {
-               printk(KERN_ERR "nvram_create_os_partition: nvram_write failed (%d)\n", rc);
+               printk(KERN_ERR "nvram_create_os_partition: nvram_write "
+                               "failed (%d)\n", rc);
                return rc;
        }
        
@@ -506,8 +506,8 @@ static int nvram_scan_partitions(void)
        struct nvram_partition * tmp_part;
        unsigned char c_sum;
        char * header;
-       long size;
        int total_size;
+       int err;
 
        if (ppc_md.nvram_size == NULL)
                return -ENODEV;
@@ -521,29 +521,37 @@ static int nvram_scan_partitions(void)
 
        while (cur_index < total_size) {
 
-               size = ppc_md.nvram_read(header, NVRAM_HEADER_LEN, &cur_index);
-               if (size != NVRAM_HEADER_LEN) {
+               err = ppc_md.nvram_read(header, NVRAM_HEADER_LEN, &cur_index);
+               if (err != NVRAM_HEADER_LEN) {
                        printk(KERN_ERR "nvram_scan_partitions: Error parsing "
                               "nvram partitions\n");
-                       kfree(header);
-                       return size;
+                       goto out;
                }
 
                cur_index -= NVRAM_HEADER_LEN; /* nvram_read will advance us */
 
                memcpy(&phead, header, NVRAM_HEADER_LEN);
 
+               err = 0;
                c_sum = nvram_checksum(&phead);
-               if (c_sum != phead.checksum)
-                       printk(KERN_WARNING "WARNING: nvram partition checksum "
-                              "was %02x, should be %02x!\n", phead.checksum, c_sum);
-               
+               if (c_sum != phead.checksum) {
+                       printk(KERN_WARNING "WARNING: nvram partition checksum"
+                              " was %02x, should be %02x!\n",
+                              phead.checksum, c_sum);
+                       printk(KERN_WARNING "Terminating nvram partition scan\n");
+                       goto out;
+               }
+               if (!phead.length) {
+                       printk(KERN_WARNING "WARNING: nvram corruption "
+                              "detected: 0-length partition\n");
+                       goto out;
+               }
                tmp_part = (struct nvram_partition *)
                        kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+               err = -ENOMEM;
                if (!tmp_part) {
                        printk(KERN_ERR "nvram_scan_partitions: kmalloc failed\n");
-                       kfree(header);
-                       return -ENOMEM;
+                       goto out;
                }
                
                memcpy(&tmp_part->header, &phead, NVRAM_HEADER_LEN);
@@ -552,9 +560,11 @@ static int nvram_scan_partitions(void)
                
                cur_index += phead.length * NVRAM_BLOCK_LEN;
        }
+       err = 0;
 
+ out:
        kfree(header);
-       return 0;
+       return err;
 }
 
 static int __init nvram_init(void)
@@ -603,6 +613,7 @@ void __exit nvram_cleanup(void)
 }
 
 
+#ifdef CONFIG_PPC_PSERIES
 
 /* nvram_write_error_log
  *
@@ -639,7 +650,7 @@ int nvram_write_error_log(char * buff, int length, unsigned int err_type)
        loff_t tmp_index;
        struct err_log_info info;
        
-       if (no_more_logging) {
+       if (no_logging) {
                return -EPERM;
        }
 
@@ -710,7 +721,7 @@ int nvram_read_error_log(char * buff, int length, unsigned int * err_type)
 /* This doesn't actually zero anything, but it sets the event_logged
  * word to tell that this event is safely in syslog.
  */
-int nvram_clear_error_log()
+int nvram_clear_error_log(void)
 {
        loff_t tmp_index;
        int clear_word = ERR_FLAG_ALREADY_LOGGED;
@@ -727,6 +738,7 @@ int nvram_clear_error_log()
        return 0;
 }
 
+#endif /* CONFIG_PPC_PSERIES */
 
 module_init(nvram_init);
 module_exit(nvram_cleanup);