diff options
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r-- | drivers/base/firmware_class.c | 38 |
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 | ||
285 | static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) | 285 | static 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 | ||
305 | static bool fw_get_filesystem_firmware(struct device *device, | 309 | static 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) |