drm/radeon: Fix sparc regression in r300_scratch()
[safe/jmp/linux-2.6] / drivers / base / firmware_class.c
index 8a267c4..18518ba 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kthread.h>
 #include <linux/highmem.h>
 #include <linux/firmware.h>
-#include "base.h"
 
 #define to_dev(obj) container_of(obj, struct device, kobj)
 
@@ -40,7 +39,7 @@ static int loading_timeout = 60;      /* In seconds */
 static DEFINE_MUTEX(fw_lock);
 
 struct firmware_priv {
-       char fw_id[FIRMWARE_NAME_MAX];
+       char *fw_id;
        struct completion completion;
        struct bin_attribute attr_data;
        struct firmware *fw;
@@ -69,7 +68,9 @@ fw_load_abort(struct firmware_priv *fw_priv)
 }
 
 static ssize_t
-firmware_timeout_show(struct class *class, char *buf)
+firmware_timeout_show(struct class *class,
+                     struct class_attribute *attr,
+                     char *buf)
 {
        return sprintf(buf, "%d\n", loading_timeout);
 }
@@ -77,6 +78,7 @@ firmware_timeout_show(struct class *class, char *buf)
 /**
  * firmware_timeout_store - set number of seconds to wait for firmware
  * @class: device class pointer
+ * @attr: device attribute pointer
  * @buf: buffer to scan for timeout value
  * @count: number of bytes in @buf
  *
@@ -87,7 +89,9 @@ firmware_timeout_show(struct class *class, char *buf)
  *     Note: zero means 'wait forever'.
  **/
 static ssize_t
-firmware_timeout_store(struct class *class, const char *buf, size_t count)
+firmware_timeout_store(struct class *class,
+                       struct class_attribute *attr,
+                       const char *buf, size_t count)
 {
        loading_timeout = simple_strtol(buf, NULL, 10);
        if (loading_timeout < 0)
@@ -180,7 +184,6 @@ static ssize_t firmware_loading_store(struct device *dev,
                                goto err;
                        }
                        /* Pages will be freed by vfree() */
-                       fw_priv->pages = NULL;
                        fw_priv->page_array_size = 0;
                        fw_priv->nr_pages = 0;
                        complete(&fw_priv->completion);
@@ -217,8 +220,10 @@ firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr,
                ret_count = -ENODEV;
                goto out;
        }
-       if (offset > fw->size)
-               return 0;
+       if (offset > fw->size) {
+               ret_count = 0;
+               goto out;
+       }
        if (count > fw->size - offset)
                count = fw->size - offset;
 
@@ -355,6 +360,7 @@ static void fw_dev_release(struct device *dev)
        for (i = 0; i < fw_priv->nr_pages; i++)
                __free_page(fw_priv->pages[i]);
        kfree(fw_priv->pages);
+       kfree(fw_priv->fw_id);
        kfree(fw_priv);
        kfree(dev);
 
@@ -386,13 +392,19 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
 
        init_completion(&fw_priv->completion);
        fw_priv->attr_data = firmware_attr_data_tmpl;
-       strlcpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX);
+       fw_priv->fw_id = kstrdup(fw_name, GFP_KERNEL);
+       if (!fw_priv->fw_id) {
+               dev_err(device, "%s: Firmware name allocation failed\n",
+                       __func__);
+               retval = -ENOMEM;
+               goto error_kfree;
+       }
 
        fw_priv->timeout.function = firmware_class_timeout;
        fw_priv->timeout.data = (u_long) fw_priv;
        init_timer(&fw_priv->timeout);
 
-       dev_set_name(f_dev, dev_name(device));
+       dev_set_name(f_dev, "%s", dev_name(device));
        f_dev->parent = device;
        f_dev->class = &firmware_class;
        dev_set_drvdata(f_dev, fw_priv);
@@ -400,14 +412,15 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
        retval = device_register(f_dev);
        if (retval) {
                dev_err(device, "%s: device_register failed\n", __func__);
-               goto error_kfree;
+               put_device(f_dev);
+               return retval;
        }
        *dev_p = f_dev;
        return 0;
 
 error_kfree:
-       kfree(fw_priv);
        kfree(f_dev);
+       kfree(fw_priv);
        return retval;
 }
 
@@ -430,6 +443,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
        fw_priv = dev_get_drvdata(f_dev);
 
        fw_priv->fw = fw;
+       sysfs_bin_attr_init(&fw_priv->attr_data);
        retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
        if (retval) {
                dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
@@ -592,41 +606,40 @@ request_firmware_work_func(void *arg)
        }
        ret = _request_firmware(&fw, fw_work->name, fw_work->device,
                fw_work->uevent);
-       if (ret < 0)
-               fw_work->cont(NULL, fw_work->context);
-       else {
-               fw_work->cont(fw, fw_work->context);
-               release_firmware(fw);
-       }
+
+       fw_work->cont(fw, fw_work->context);
+
        module_put(fw_work->module);
        kfree(fw_work);
        return ret;
 }
 
 /**
- * request_firmware_nowait: asynchronous version of request_firmware
+ * request_firmware_nowait - asynchronous version of request_firmware
  * @module: module requesting the firmware
  * @uevent: sends uevent to copy the firmware image if this flag
  *     is non-zero else the firmware copy must be done manually.
  * @name: name of firmware file
  * @device: device for which firmware is being loaded
+ * @gfp: allocation flags
  * @context: will be passed over to @cont, and
  *     @fw may be %NULL if firmware request fails.
  * @cont: function will be called asynchronously when the firmware
  *     request is over.
  *
- *     Asynchronous variant of request_firmware() for contexts where
- *     it is not possible to sleep.
+ *     Asynchronous variant of request_firmware() for user contexts where
+ *     it is not possible to sleep for long time. It can't be called
+ *     in atomic contexts.
  **/
 int
 request_firmware_nowait(
        struct module *module, int uevent,
-       const char *name, struct device *device, void *context,
+       const char *name, struct device *device, gfp_t gfp, void *context,
        void (*cont)(const struct firmware *fw, void *context))
 {
        struct task_struct *task;
        struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
-                                               GFP_ATOMIC);
+                                               gfp);
 
        if (!fw_work)
                return -ENOMEM;