firmware: Sigma: Fix endianess issues
[linux-2.6.git] / drivers / firmware / dell_rbu.c
index fc17599..2f452f1 100644 (file)
@@ -36,6 +36,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/blkdev.h>
@@ -123,7 +124,7 @@ static int create_packet(void *data, size_t length)
        if (!newpacket) {
                printk(KERN_WARNING
                        "dell_rbu:%s: failed to allocate new "
-                       "packet\n", __FUNCTION__);
+                       "packet\n", __func__);
                retval = -ENOMEM;
                spin_lock(&rbu_data.lock);
                goto out_noalloc;
@@ -152,7 +153,7 @@ static int create_packet(void *data, size_t length)
                printk(KERN_WARNING
                        "dell_rbu:%s: failed to allocate "
                        "invalid_addr_packet_array \n",
-                       __FUNCTION__);
+                       __func__);
                retval = -ENOMEM;
                spin_lock(&rbu_data.lock);
                goto out_alloc_packet;
@@ -164,7 +165,7 @@ static int create_packet(void *data, size_t length)
                if (!packet_data_temp_buf) {
                        printk(KERN_WARNING
                                "dell_rbu:%s: failed to allocate new "
-                               "packet\n", __FUNCTION__);
+                               "packet\n", __func__);
                        retval = -ENOMEM;
                        spin_lock(&rbu_data.lock);
                        goto out_alloc_packet_array;
@@ -220,7 +221,7 @@ out_noalloc:
        return retval;
 }
 
-static int packetize_data(void *data, size_t length)
+static int packetize_data(const u8 *data, size_t length)
 {
        int rc = 0;
        int done = 0;
@@ -249,7 +250,7 @@ static int packetize_data(void *data, size_t length)
                if ((rc = create_packet(temp, packet_length)))
                        return rc;
 
-               pr_debug("%p:%lu\n", temp, (end - temp));
+               pr_debug("%p:%td\n", temp, (end - temp));
                temp += packet_length;
        }
 
@@ -416,7 +417,7 @@ static int img_update_realloc(unsigned long size)
                 */
                if ((size != 0) && (rbu_data.image_update_buffer == NULL)) {
                        printk(KERN_ERR "dell_rbu:%s: corruption "
-                               "check failed\n", __FUNCTION__);
+                               "check failed\n", __func__);
                        return -EINVAL;
                }
                /*
@@ -507,11 +508,6 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
 
 static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
 {
-       unsigned char *ptemp = NULL;
-       size_t bytes_left = 0;
-       size_t data_length = 0;
-       ssize_t ret_count = 0;
-
        /* check to see if we have something to return */
        if ((rbu_data.image_update_buffer == NULL) ||
                (rbu_data.bios_image_size == 0)) {
@@ -519,32 +515,16 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
                        "bios_image_size %lu\n",
                        rbu_data.image_update_buffer,
                        rbu_data.bios_image_size);
-               ret_count = -ENOMEM;
-               goto read_rbu_data_exit;
-       }
-
-       if (pos > rbu_data.bios_image_size) {
-               ret_count = 0;
-               goto read_rbu_data_exit;
+               return -ENOMEM;
        }
 
-       bytes_left = rbu_data.bios_image_size - pos;
-       data_length = min(bytes_left, count);
-
-       ptemp = rbu_data.image_update_buffer;
-       memcpy(buffer, (ptemp + pos), data_length);
-
-       if ((pos + count) > rbu_data.bios_image_size)
-               /* this was the last copy */
-               ret_count = bytes_left;
-       else
-               ret_count = count;
-      read_rbu_data_exit:
-       return ret_count;
+       return memory_read_from_buffer(buffer, count, &pos,
+                       rbu_data.image_update_buffer, rbu_data.bios_image_size);
 }
 
-static ssize_t read_rbu_data(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj,
+                            struct bin_attribute *bin_attr,
+                            char *buffer, loff_t pos, size_t count)
 {
        ssize_t ret_count = 0;
 
@@ -565,9 +545,12 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
 {
        rbu_data.entry_created = 0;
 
-       if (!fw || !fw->size)
+       if (!fw)
                return;
 
+       if (!fw->size)
+               goto out;
+
        spin_lock(&rbu_data.lock);
        if (!strcmp(image_type, "mono")) {
                if (!img_update_realloc(fw->size))
@@ -589,19 +572,23 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
        } else
                pr_debug("invalid image type specified.\n");
        spin_unlock(&rbu_data.lock);
+ out:
+       release_firmware(fw);
 }
 
-static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
+                                  struct bin_attribute *bin_attr,
+                                  char *buffer, loff_t pos, size_t count)
 {
        int size = 0;
        if (!pos)
-               size = sprintf(buffer, "%s\n", image_type);
+               size = scnprintf(buffer, count, "%s\n", image_type);
        return size;
 }
 
-static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
+                                   struct bin_attribute *bin_attr,
+                                   char *buffer, loff_t pos, size_t count)
 {
        int rc = count;
        int req_firm_rc = 0;
@@ -634,12 +621,12 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
                        spin_unlock(&rbu_data.lock);
                        req_firm_rc = request_firmware_nowait(THIS_MODULE,
                                FW_ACTION_NOHOTPLUG, "dell_rbu",
-                               &rbu_device->dev, &context,
+                               &rbu_device->dev, GFP_KERNEL, &context,
                                callbackfn_rbu);
                        if (req_firm_rc) {
                                printk(KERN_ERR
                                        "dell_rbu:%s request_firmware_nowait"
-                                       " failed %d\n", __FUNCTION__, rc);
+                                       " failed %d\n", __func__, rc);
                                rc = -EIO;
                        } else
                                rbu_data.entry_created = 1;
@@ -660,20 +647,22 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
        return rc;
 }
 
-static ssize_t read_rbu_packet_size(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj,
+                                   struct bin_attribute *bin_attr,
+                                   char *buffer, loff_t pos, size_t count)
 {
        int size = 0;
        if (!pos) {
                spin_lock(&rbu_data.lock);
-               size = sprintf(buffer, "%lu\n", rbu_data.packetsize);
+               size = scnprintf(buffer, count, "%lu\n", rbu_data.packetsize);
                spin_unlock(&rbu_data.lock);
        }
        return size;
 }
 
-static ssize_t write_rbu_packet_size(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj,
+                                    struct bin_attribute *bin_attr,
+                                    char *buffer, loff_t pos, size_t count)
 {
        unsigned long temp;
        spin_lock(&rbu_data.lock);
@@ -687,45 +676,57 @@ static ssize_t write_rbu_packet_size(struct kobject *kobj, char *buffer,
 }
 
 static struct bin_attribute rbu_data_attr = {
-       .attr = {.name = "data",.owner = THIS_MODULE,.mode = 0444},
+       .attr = {.name = "data", .mode = 0444},
        .read = read_rbu_data,
 };
 
 static struct bin_attribute rbu_image_type_attr = {
-       .attr = {.name = "image_type",.owner = THIS_MODULE,.mode = 0644},
+       .attr = {.name = "image_type", .mode = 0644},
        .read = read_rbu_image_type,
        .write = write_rbu_image_type,
 };
 
 static struct bin_attribute rbu_packet_size_attr = {
-       .attr = {.name = "packet_size",.owner = THIS_MODULE,.mode = 0644},
+       .attr = {.name = "packet_size", .mode = 0644},
        .read = read_rbu_packet_size,
        .write = write_rbu_packet_size,
 };
 
 static int __init dcdrbu_init(void)
 {
-       int rc = 0;
+       int rc;
        spin_lock_init(&rbu_data.lock);
 
        init_packet_head();
-       rbu_device =
-               platform_device_register_simple("dell_rbu", -1, NULL, 0);
-       if (!rbu_device) {
+       rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0);
+       if (IS_ERR(rbu_device)) {
                printk(KERN_ERR
                        "dell_rbu:%s:platform_device_register_simple "
-                       "failed\n", __FUNCTION__);
-               return -EIO;
+                       "failed\n", __func__);
+               return PTR_ERR(rbu_device);
        }
 
-       sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
-       sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
-       sysfs_create_bin_file(&rbu_device->dev.kobj,
+       rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
+       if (rc)
+               goto out_devreg;
+       rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
+       if (rc)
+               goto out_data;
+       rc = sysfs_create_bin_file(&rbu_device->dev.kobj,
                &rbu_packet_size_attr);
+       if (rc)
+               goto out_imtype;
 
        rbu_data.entry_created = 0;
-       return rc;
+       return 0;
 
+out_imtype:
+       sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
+out_data:
+       sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
+out_devreg:
+       platform_device_unregister(rbu_device);
+       return rc;
 }
 
 static __exit void dcdrbu_exit(void)