Attempt kernel firmware load before going to udev.
Neil Gabriel [Tue, 21 Jan 2014 18:03:59 +0000 (12:03 -0600)]
request_firmware() should fall back to usermodehelper
routines to load firmware only after a failed attempt
to load it directly. Prior to this change, the code
will attempt to lock the usermodehelper state before
attempting to load the firmware directly. If the
usermodehelper is disabled, the lock attempts will
fail and request_firmware() will exit without even
attempting a direct load.

Bug 1403956

Change-Id: I26c502d30657eab3d382d139618f9daa366068cf
Signed-off-by: Neil Gabriel <ngabriel@nvidia.com>
Reviewed-on: http://git-master/r/358303
Reviewed-on: http://git-master/r/362065
(cherry picked from commit 50ba73a322afff1e63d1cc2880bef7c907db98d6)
Reviewed-on: http://git-master/r/366457
Reviewed-by: Pankaj Dabade <pdabade@nvidia.com>
Tested-by: Pankaj Dabade <pdabade@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Winnie Hsu <whsu@nvidia.com>

drivers/base/firmware_class.c

index 01e2103..cbb8b00 100644 (file)
@@ -1026,32 +1026,34 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
                goto out;
 
        ret = 0;
-       timeout = firmware_loading_timeout();
-       if (nowait) {
-               timeout = usermodehelper_read_lock_wait(timeout);
-               if (!timeout) {
-                       dev_dbg(device, "firmware: %s loading timed out\n",
-                               name);
-                       ret = -EBUSY;
-                       goto out;
-               }
-       } else {
-               ret = usermodehelper_read_trylock();
-               if (WARN_ON(ret)) {
-                       dev_err(device, "firmware: %s will not be loaded\n",
-                               name);
-                       goto out;
+       if (!fw_get_filesystem_firmware(device, fw->priv)) {
+               timeout = firmware_loading_timeout();
+               if (nowait) {
+                       timeout = usermodehelper_read_lock_wait(timeout);
+                       if (!timeout) {
+                               dev_dbg(device, "firmware: %s loading timed out\n",
+                                       name);
+                               ret = -EBUSY;
+                               goto out;
+                       }
+               } else {
+                       ret = usermodehelper_read_trylock();
+                       if (WARN_ON(ret)) {
+                               dev_err(device, "firmware: %s will not be loaded\n",
+                                       name);
+                               goto out;
+                       }
                }
-       }
 
-       if (!fw_get_filesystem_firmware(device, fw->priv))
                ret = fw_load_from_user_helper(fw, name, device,
                                               uevent, nowait, timeout);
+
+               usermodehelper_read_unlock();
+       }
+
        if (!ret)
                ret = assign_firmware_buf(fw, device);
 
-       usermodehelper_read_unlock();
-
  out:
        if (ret < 0) {
                release_firmware(fw);