aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r--drivers/base/firmware_class.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 10a4467c63f1..eb8fb94ae2c5 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -282,31 +282,35 @@ static noinline_for_stack long fw_file_size(struct file *file)
282 return st.size; 282 return st.size;
283} 283}
284 284
285static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) 285static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
286{ 286{
287 long size; 287 long size;
288 char *buf; 288 char *buf;
289 int rc;
289 290
290 size = fw_file_size(file); 291 size = fw_file_size(file);
291 if (size <= 0) 292 if (size <= 0)
292 return false; 293 return -EINVAL;
293 buf = vmalloc(size); 294 buf = vmalloc(size);
294 if (!buf) 295 if (!buf)
295 return false; 296 return -ENOMEM;
296 if (kernel_read(file, 0, buf, size) != size) { 297 rc = kernel_read(file, 0, buf, size);
298 if (rc != size) {
299 if (rc > 0)
300 rc = -EIO;
297 vfree(buf); 301 vfree(buf);
298 return false; 302 return rc;
299 } 303 }
300 fw_buf->data = buf; 304 fw_buf->data = buf;
301 fw_buf->size = size; 305 fw_buf->size = size;
302 return true; 306 return 0;
303} 307}
304 308
305static bool fw_get_filesystem_firmware(struct device *device, 309static int fw_get_filesystem_firmware(struct device *device,
306 struct firmware_buf *buf) 310 struct firmware_buf *buf)
307{ 311{
308 int i; 312 int i;
309 bool success = false; 313 int rc = -ENOENT;
310 char *path = __getname(); 314 char *path = __getname();
311 315
312 for (i = 0; i < ARRAY_SIZE(fw_path); i++) { 316 for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
@@ -321,14 +325,17 @@ static bool fw_get_filesystem_firmware(struct device *device,
321 file = filp_open(path, O_RDONLY, 0); 325 file = filp_open(path, O_RDONLY, 0);
322 if (IS_ERR(file)) 326 if (IS_ERR(file))
323 continue; 327 continue;
324 success = fw_read_file_contents(file, buf); 328 rc = fw_read_file_contents(file, buf);
325 fput(file); 329 fput(file);
326 if (success) 330 if (rc)
331 dev_warn(device, "firmware, attempted to load %s, but failed with error %d\n",
332 path, rc);
333 else
327 break; 334 break;
328 } 335 }
329 __putname(path); 336 __putname(path);
330 337
331 if (success) { 338 if (!rc) {
332 dev_dbg(device, "firmware: direct-loading firmware %s\n", 339 dev_dbg(device, "firmware: direct-loading firmware %s\n",
333 buf->fw_id); 340 buf->fw_id);
334 mutex_lock(&fw_lock); 341 mutex_lock(&fw_lock);
@@ -337,7 +344,7 @@ static bool fw_get_filesystem_firmware(struct device *device,
337 mutex_unlock(&fw_lock); 344 mutex_unlock(&fw_lock);
338 } 345 }
339 346
340 return success; 347 return rc;
341} 348}
342 349
343/* firmware holds the ownership of pages */ 350/* firmware holds the ownership of pages */
@@ -1086,9 +1093,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
1086 } 1093 }
1087 } 1094 }
1088 1095
1089 if (!fw_get_filesystem_firmware(device, fw->priv)) 1096 ret = fw_get_filesystem_firmware(device, fw->priv);
1097 if (ret) {
1098 dev_warn(device, "Direct firmware load failed with error %d\n",
1099 ret);
1100 dev_warn(device, "Falling back to user helper\n");
1090 ret = fw_load_from_user_helper(fw, name, device, 1101 ret = fw_load_from_user_helper(fw, name, device,
1091 uevent, nowait, timeout); 1102 uevent, nowait, timeout);
1103 }
1092 1104
1093 /* don't cache firmware handled without uevent */ 1105 /* don't cache firmware handled without uevent */
1094 if (!ret) 1106 if (!ret)