diff options
Diffstat (limited to 'drivers/base/firmware_loader/fallback.c')
-rw-r--r-- | drivers/base/firmware_loader/fallback.c | 661 |
1 files changed, 661 insertions, 0 deletions
diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c new file mode 100644 index 000000000000..9b65837256d6 --- /dev/null +++ b/drivers/base/firmware_loader/fallback.c | |||
@@ -0,0 +1,661 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | #include <linux/types.h> | ||
4 | #include <linux/kconfig.h> | ||
5 | #include <linux/list.h> | ||
6 | #include <linux/slab.h> | ||
7 | #include <linux/security.h> | ||
8 | #include <linux/highmem.h> | ||
9 | #include <linux/umh.h> | ||
10 | |||
11 | #include "fallback.h" | ||
12 | #include "firmware.h" | ||
13 | |||
14 | /* | ||
15 | * firmware fallback mechanism | ||
16 | */ | ||
17 | |||
18 | extern struct firmware_fallback_config fw_fallback_config; | ||
19 | |||
20 | /* These getters are vetted to use int properly */ | ||
21 | static inline int __firmware_loading_timeout(void) | ||
22 | { | ||
23 | return fw_fallback_config.loading_timeout; | ||
24 | } | ||
25 | |||
26 | /* These setters are vetted to use int properly */ | ||
27 | static void __fw_fallback_set_timeout(int timeout) | ||
28 | { | ||
29 | fw_fallback_config.loading_timeout = timeout; | ||
30 | } | ||
31 | |||
32 | /* | ||
33 | * use small loading timeout for caching devices' firmware because all these | ||
34 | * firmware images have been loaded successfully at lease once, also system is | ||
35 | * ready for completing firmware loading now. The maximum size of firmware in | ||
36 | * current distributions is about 2M bytes, so 10 secs should be enough. | ||
37 | */ | ||
38 | void fw_fallback_set_cache_timeout(void) | ||
39 | { | ||
40 | fw_fallback_config.old_timeout = __firmware_loading_timeout(); | ||
41 | __fw_fallback_set_timeout(10); | ||
42 | } | ||
43 | |||
44 | /* Restores the timeout to the value last configured during normal operation */ | ||
45 | void fw_fallback_set_default_timeout(void) | ||
46 | { | ||
47 | __fw_fallback_set_timeout(fw_fallback_config.old_timeout); | ||
48 | } | ||
49 | |||
50 | static long firmware_loading_timeout(void) | ||
51 | { | ||
52 | return __firmware_loading_timeout() > 0 ? | ||
53 | __firmware_loading_timeout() * HZ : MAX_JIFFY_OFFSET; | ||
54 | } | ||
55 | |||
56 | static inline bool fw_sysfs_done(struct fw_priv *fw_priv) | ||
57 | { | ||
58 | return __fw_state_check(fw_priv, FW_STATUS_DONE); | ||
59 | } | ||
60 | |||
61 | static inline bool fw_sysfs_loading(struct fw_priv *fw_priv) | ||
62 | { | ||
63 | return __fw_state_check(fw_priv, FW_STATUS_LOADING); | ||
64 | } | ||
65 | |||
66 | static inline int fw_sysfs_wait_timeout(struct fw_priv *fw_priv, long timeout) | ||
67 | { | ||
68 | return __fw_state_wait_common(fw_priv, timeout); | ||
69 | } | ||
70 | |||
71 | struct fw_sysfs { | ||
72 | bool nowait; | ||
73 | struct device dev; | ||
74 | struct fw_priv *fw_priv; | ||
75 | struct firmware *fw; | ||
76 | }; | ||
77 | |||
78 | static struct fw_sysfs *to_fw_sysfs(struct device *dev) | ||
79 | { | ||
80 | return container_of(dev, struct fw_sysfs, dev); | ||
81 | } | ||
82 | |||
83 | static void __fw_load_abort(struct fw_priv *fw_priv) | ||
84 | { | ||
85 | /* | ||
86 | * There is a small window in which user can write to 'loading' | ||
87 | * between loading done and disappearance of 'loading' | ||
88 | */ | ||
89 | if (fw_sysfs_done(fw_priv)) | ||
90 | return; | ||
91 | |||
92 | list_del_init(&fw_priv->pending_list); | ||
93 | fw_state_aborted(fw_priv); | ||
94 | } | ||
95 | |||
96 | static void fw_load_abort(struct fw_sysfs *fw_sysfs) | ||
97 | { | ||
98 | struct fw_priv *fw_priv = fw_sysfs->fw_priv; | ||
99 | |||
100 | __fw_load_abort(fw_priv); | ||
101 | } | ||
102 | |||
103 | static LIST_HEAD(pending_fw_head); | ||
104 | |||
105 | void kill_pending_fw_fallback_reqs(bool only_kill_custom) | ||
106 | { | ||
107 | struct fw_priv *fw_priv; | ||
108 | struct fw_priv *next; | ||
109 | |||
110 | mutex_lock(&fw_lock); | ||
111 | list_for_each_entry_safe(fw_priv, next, &pending_fw_head, | ||
112 | pending_list) { | ||
113 | if (!fw_priv->need_uevent || !only_kill_custom) | ||
114 | __fw_load_abort(fw_priv); | ||
115 | } | ||
116 | mutex_unlock(&fw_lock); | ||
117 | } | ||
118 | |||
119 | static ssize_t timeout_show(struct class *class, struct class_attribute *attr, | ||
120 | char *buf) | ||
121 | { | ||
122 | return sprintf(buf, "%d\n", __firmware_loading_timeout()); | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * firmware_timeout_store - set number of seconds to wait for firmware | ||
127 | * @class: device class pointer | ||
128 | * @attr: device attribute pointer | ||
129 | * @buf: buffer to scan for timeout value | ||
130 | * @count: number of bytes in @buf | ||
131 | * | ||
132 | * Sets the number of seconds to wait for the firmware. Once | ||
133 | * this expires an error will be returned to the driver and no | ||
134 | * firmware will be provided. | ||
135 | * | ||
136 | * Note: zero means 'wait forever'. | ||
137 | **/ | ||
138 | static ssize_t timeout_store(struct class *class, struct class_attribute *attr, | ||
139 | const char *buf, size_t count) | ||
140 | { | ||
141 | int tmp_loading_timeout = simple_strtol(buf, NULL, 10); | ||
142 | |||
143 | if (tmp_loading_timeout < 0) | ||
144 | tmp_loading_timeout = 0; | ||
145 | |||
146 | __fw_fallback_set_timeout(tmp_loading_timeout); | ||
147 | |||
148 | return count; | ||
149 | } | ||
150 | static CLASS_ATTR_RW(timeout); | ||
151 | |||
152 | static struct attribute *firmware_class_attrs[] = { | ||
153 | &class_attr_timeout.attr, | ||
154 | NULL, | ||
155 | }; | ||
156 | ATTRIBUTE_GROUPS(firmware_class); | ||
157 | |||
158 | static void fw_dev_release(struct device *dev) | ||
159 | { | ||
160 | struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); | ||
161 | |||
162 | kfree(fw_sysfs); | ||
163 | } | ||
164 | |||
165 | static int do_firmware_uevent(struct fw_sysfs *fw_sysfs, struct kobj_uevent_env *env) | ||
166 | { | ||
167 | if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->fw_priv->fw_name)) | ||
168 | return -ENOMEM; | ||
169 | if (add_uevent_var(env, "TIMEOUT=%i", __firmware_loading_timeout())) | ||
170 | return -ENOMEM; | ||
171 | if (add_uevent_var(env, "ASYNC=%d", fw_sysfs->nowait)) | ||
172 | return -ENOMEM; | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
178 | { | ||
179 | struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); | ||
180 | int err = 0; | ||
181 | |||
182 | mutex_lock(&fw_lock); | ||
183 | if (fw_sysfs->fw_priv) | ||
184 | err = do_firmware_uevent(fw_sysfs, env); | ||
185 | mutex_unlock(&fw_lock); | ||
186 | return err; | ||
187 | } | ||
188 | |||
189 | static struct class firmware_class = { | ||
190 | .name = "firmware", | ||
191 | .class_groups = firmware_class_groups, | ||
192 | .dev_uevent = firmware_uevent, | ||
193 | .dev_release = fw_dev_release, | ||
194 | }; | ||
195 | |||
196 | int register_sysfs_loader(void) | ||
197 | { | ||
198 | return class_register(&firmware_class); | ||
199 | } | ||
200 | |||
201 | void unregister_sysfs_loader(void) | ||
202 | { | ||
203 | class_unregister(&firmware_class); | ||
204 | } | ||
205 | |||
206 | static ssize_t firmware_loading_show(struct device *dev, | ||
207 | struct device_attribute *attr, char *buf) | ||
208 | { | ||
209 | struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); | ||
210 | int loading = 0; | ||
211 | |||
212 | mutex_lock(&fw_lock); | ||
213 | if (fw_sysfs->fw_priv) | ||
214 | loading = fw_sysfs_loading(fw_sysfs->fw_priv); | ||
215 | mutex_unlock(&fw_lock); | ||
216 | |||
217 | return sprintf(buf, "%d\n", loading); | ||
218 | } | ||
219 | |||
220 | /* Some architectures don't have PAGE_KERNEL_RO */ | ||
221 | #ifndef PAGE_KERNEL_RO | ||
222 | #define PAGE_KERNEL_RO PAGE_KERNEL | ||
223 | #endif | ||
224 | |||
225 | /* one pages buffer should be mapped/unmapped only once */ | ||
226 | static int map_fw_priv_pages(struct fw_priv *fw_priv) | ||
227 | { | ||
228 | if (!fw_priv->is_paged_buf) | ||
229 | return 0; | ||
230 | |||
231 | vunmap(fw_priv->data); | ||
232 | fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, | ||
233 | PAGE_KERNEL_RO); | ||
234 | if (!fw_priv->data) | ||
235 | return -ENOMEM; | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * firmware_loading_store - set value in the 'loading' control file | ||
241 | * @dev: device pointer | ||
242 | * @attr: device attribute pointer | ||
243 | * @buf: buffer to scan for loading control value | ||
244 | * @count: number of bytes in @buf | ||
245 | * | ||
246 | * The relevant values are: | ||
247 | * | ||
248 | * 1: Start a load, discarding any previous partial load. | ||
249 | * 0: Conclude the load and hand the data to the driver code. | ||
250 | * -1: Conclude the load with an error and discard any written data. | ||
251 | **/ | ||
252 | static ssize_t firmware_loading_store(struct device *dev, | ||
253 | struct device_attribute *attr, | ||
254 | const char *buf, size_t count) | ||
255 | { | ||
256 | struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); | ||
257 | struct fw_priv *fw_priv; | ||
258 | ssize_t written = count; | ||
259 | int loading = simple_strtol(buf, NULL, 10); | ||
260 | int i; | ||
261 | |||
262 | mutex_lock(&fw_lock); | ||
263 | fw_priv = fw_sysfs->fw_priv; | ||
264 | if (fw_state_is_aborted(fw_priv)) | ||
265 | goto out; | ||
266 | |||
267 | switch (loading) { | ||
268 | case 1: | ||
269 | /* discarding any previous partial load */ | ||
270 | if (!fw_sysfs_done(fw_priv)) { | ||
271 | for (i = 0; i < fw_priv->nr_pages; i++) | ||
272 | __free_page(fw_priv->pages[i]); | ||
273 | vfree(fw_priv->pages); | ||
274 | fw_priv->pages = NULL; | ||
275 | fw_priv->page_array_size = 0; | ||
276 | fw_priv->nr_pages = 0; | ||
277 | fw_state_start(fw_priv); | ||
278 | } | ||
279 | break; | ||
280 | case 0: | ||
281 | if (fw_sysfs_loading(fw_priv)) { | ||
282 | int rc; | ||
283 | |||
284 | /* | ||
285 | * Several loading requests may be pending on | ||
286 | * one same firmware buf, so let all requests | ||
287 | * see the mapped 'buf->data' once the loading | ||
288 | * is completed. | ||
289 | * */ | ||
290 | rc = map_fw_priv_pages(fw_priv); | ||
291 | if (rc) | ||
292 | dev_err(dev, "%s: map pages failed\n", | ||
293 | __func__); | ||
294 | else | ||
295 | rc = security_kernel_post_read_file(NULL, | ||
296 | fw_priv->data, fw_priv->size, | ||
297 | READING_FIRMWARE); | ||
298 | |||
299 | /* | ||
300 | * Same logic as fw_load_abort, only the DONE bit | ||
301 | * is ignored and we set ABORT only on failure. | ||
302 | */ | ||
303 | list_del_init(&fw_priv->pending_list); | ||
304 | if (rc) { | ||
305 | fw_state_aborted(fw_priv); | ||
306 | written = rc; | ||
307 | } else { | ||
308 | fw_state_done(fw_priv); | ||
309 | } | ||
310 | break; | ||
311 | } | ||
312 | /* fallthrough */ | ||
313 | default: | ||
314 | dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading); | ||
315 | /* fallthrough */ | ||
316 | case -1: | ||
317 | fw_load_abort(fw_sysfs); | ||
318 | break; | ||
319 | } | ||
320 | out: | ||
321 | mutex_unlock(&fw_lock); | ||
322 | return written; | ||
323 | } | ||
324 | |||
325 | static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); | ||
326 | |||
327 | static void firmware_rw_data(struct fw_priv *fw_priv, char *buffer, | ||
328 | loff_t offset, size_t count, bool read) | ||
329 | { | ||
330 | if (read) | ||
331 | memcpy(buffer, fw_priv->data + offset, count); | ||
332 | else | ||
333 | memcpy(fw_priv->data + offset, buffer, count); | ||
334 | } | ||
335 | |||
336 | static void firmware_rw(struct fw_priv *fw_priv, char *buffer, | ||
337 | loff_t offset, size_t count, bool read) | ||
338 | { | ||
339 | while (count) { | ||
340 | void *page_data; | ||
341 | int page_nr = offset >> PAGE_SHIFT; | ||
342 | int page_ofs = offset & (PAGE_SIZE-1); | ||
343 | int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count); | ||
344 | |||
345 | page_data = kmap(fw_priv->pages[page_nr]); | ||
346 | |||
347 | if (read) | ||
348 | memcpy(buffer, page_data + page_ofs, page_cnt); | ||
349 | else | ||
350 | memcpy(page_data + page_ofs, buffer, page_cnt); | ||
351 | |||
352 | kunmap(fw_priv->pages[page_nr]); | ||
353 | buffer += page_cnt; | ||
354 | offset += page_cnt; | ||
355 | count -= page_cnt; | ||
356 | } | ||
357 | } | ||
358 | |||
359 | static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, | ||
360 | struct bin_attribute *bin_attr, | ||
361 | char *buffer, loff_t offset, size_t count) | ||
362 | { | ||
363 | struct device *dev = kobj_to_dev(kobj); | ||
364 | struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); | ||
365 | struct fw_priv *fw_priv; | ||
366 | ssize_t ret_count; | ||
367 | |||
368 | mutex_lock(&fw_lock); | ||
369 | fw_priv = fw_sysfs->fw_priv; | ||
370 | if (!fw_priv || fw_sysfs_done(fw_priv)) { | ||
371 | ret_count = -ENODEV; | ||
372 | goto out; | ||
373 | } | ||
374 | if (offset > fw_priv->size) { | ||
375 | ret_count = 0; | ||
376 | goto out; | ||
377 | } | ||
378 | if (count > fw_priv->size - offset) | ||
379 | count = fw_priv->size - offset; | ||
380 | |||
381 | ret_count = count; | ||
382 | |||
383 | if (fw_priv->data) | ||
384 | firmware_rw_data(fw_priv, buffer, offset, count, true); | ||
385 | else | ||
386 | firmware_rw(fw_priv, buffer, offset, count, true); | ||
387 | |||
388 | out: | ||
389 | mutex_unlock(&fw_lock); | ||
390 | return ret_count; | ||
391 | } | ||
392 | |||
393 | static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size) | ||
394 | { | ||
395 | struct fw_priv *fw_priv= fw_sysfs->fw_priv; | ||
396 | int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT; | ||
397 | |||
398 | /* If the array of pages is too small, grow it... */ | ||
399 | if (fw_priv->page_array_size < pages_needed) { | ||
400 | int new_array_size = max(pages_needed, | ||
401 | fw_priv->page_array_size * 2); | ||
402 | struct page **new_pages; | ||
403 | |||
404 | new_pages = vmalloc(new_array_size * sizeof(void *)); | ||
405 | if (!new_pages) { | ||
406 | fw_load_abort(fw_sysfs); | ||
407 | return -ENOMEM; | ||
408 | } | ||
409 | memcpy(new_pages, fw_priv->pages, | ||
410 | fw_priv->page_array_size * sizeof(void *)); | ||
411 | memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * | ||
412 | (new_array_size - fw_priv->page_array_size)); | ||
413 | vfree(fw_priv->pages); | ||
414 | fw_priv->pages = new_pages; | ||
415 | fw_priv->page_array_size = new_array_size; | ||
416 | } | ||
417 | |||
418 | while (fw_priv->nr_pages < pages_needed) { | ||
419 | fw_priv->pages[fw_priv->nr_pages] = | ||
420 | alloc_page(GFP_KERNEL | __GFP_HIGHMEM); | ||
421 | |||
422 | if (!fw_priv->pages[fw_priv->nr_pages]) { | ||
423 | fw_load_abort(fw_sysfs); | ||
424 | return -ENOMEM; | ||
425 | } | ||
426 | fw_priv->nr_pages++; | ||
427 | } | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * firmware_data_write - write method for firmware | ||
433 | * @filp: open sysfs file | ||
434 | * @kobj: kobject for the device | ||
435 | * @bin_attr: bin_attr structure | ||
436 | * @buffer: buffer being written | ||
437 | * @offset: buffer offset for write in total data store area | ||
438 | * @count: buffer size | ||
439 | * | ||
440 | * Data written to the 'data' attribute will be later handed to | ||
441 | * the driver as a firmware image. | ||
442 | **/ | ||
443 | static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, | ||
444 | struct bin_attribute *bin_attr, | ||
445 | char *buffer, loff_t offset, size_t count) | ||
446 | { | ||
447 | struct device *dev = kobj_to_dev(kobj); | ||
448 | struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); | ||
449 | struct fw_priv *fw_priv; | ||
450 | ssize_t retval; | ||
451 | |||
452 | if (!capable(CAP_SYS_RAWIO)) | ||
453 | return -EPERM; | ||
454 | |||
455 | mutex_lock(&fw_lock); | ||
456 | fw_priv = fw_sysfs->fw_priv; | ||
457 | if (!fw_priv || fw_sysfs_done(fw_priv)) { | ||
458 | retval = -ENODEV; | ||
459 | goto out; | ||
460 | } | ||
461 | |||
462 | if (fw_priv->data) { | ||
463 | if (offset + count > fw_priv->allocated_size) { | ||
464 | retval = -ENOMEM; | ||
465 | goto out; | ||
466 | } | ||
467 | firmware_rw_data(fw_priv, buffer, offset, count, false); | ||
468 | retval = count; | ||
469 | } else { | ||
470 | retval = fw_realloc_pages(fw_sysfs, offset + count); | ||
471 | if (retval) | ||
472 | goto out; | ||
473 | |||
474 | retval = count; | ||
475 | firmware_rw(fw_priv, buffer, offset, count, false); | ||
476 | } | ||
477 | |||
478 | fw_priv->size = max_t(size_t, offset + count, fw_priv->size); | ||
479 | out: | ||
480 | mutex_unlock(&fw_lock); | ||
481 | return retval; | ||
482 | } | ||
483 | |||
484 | static struct bin_attribute firmware_attr_data = { | ||
485 | .attr = { .name = "data", .mode = 0644 }, | ||
486 | .size = 0, | ||
487 | .read = firmware_data_read, | ||
488 | .write = firmware_data_write, | ||
489 | }; | ||
490 | |||
491 | static struct attribute *fw_dev_attrs[] = { | ||
492 | &dev_attr_loading.attr, | ||
493 | NULL | ||
494 | }; | ||
495 | |||
496 | static struct bin_attribute *fw_dev_bin_attrs[] = { | ||
497 | &firmware_attr_data, | ||
498 | NULL | ||
499 | }; | ||
500 | |||
501 | static const struct attribute_group fw_dev_attr_group = { | ||
502 | .attrs = fw_dev_attrs, | ||
503 | .bin_attrs = fw_dev_bin_attrs, | ||
504 | }; | ||
505 | |||
506 | static const struct attribute_group *fw_dev_attr_groups[] = { | ||
507 | &fw_dev_attr_group, | ||
508 | NULL | ||
509 | }; | ||
510 | |||
511 | static struct fw_sysfs * | ||
512 | fw_create_instance(struct firmware *firmware, const char *fw_name, | ||
513 | struct device *device, unsigned int opt_flags) | ||
514 | { | ||
515 | struct fw_sysfs *fw_sysfs; | ||
516 | struct device *f_dev; | ||
517 | |||
518 | fw_sysfs = kzalloc(sizeof(*fw_sysfs), GFP_KERNEL); | ||
519 | if (!fw_sysfs) { | ||
520 | fw_sysfs = ERR_PTR(-ENOMEM); | ||
521 | goto exit; | ||
522 | } | ||
523 | |||
524 | fw_sysfs->nowait = !!(opt_flags & FW_OPT_NOWAIT); | ||
525 | fw_sysfs->fw = firmware; | ||
526 | f_dev = &fw_sysfs->dev; | ||
527 | |||
528 | device_initialize(f_dev); | ||
529 | dev_set_name(f_dev, "%s", fw_name); | ||
530 | f_dev->parent = device; | ||
531 | f_dev->class = &firmware_class; | ||
532 | f_dev->groups = fw_dev_attr_groups; | ||
533 | exit: | ||
534 | return fw_sysfs; | ||
535 | } | ||
536 | |||
537 | /* load a firmware via user helper */ | ||
538 | static int _request_firmware_load(struct fw_sysfs *fw_sysfs, | ||
539 | unsigned int opt_flags, long timeout) | ||
540 | { | ||
541 | int retval = 0; | ||
542 | struct device *f_dev = &fw_sysfs->dev; | ||
543 | struct fw_priv *fw_priv = fw_sysfs->fw_priv; | ||
544 | |||
545 | /* fall back on userspace loading */ | ||
546 | if (!fw_priv->data) | ||
547 | fw_priv->is_paged_buf = true; | ||
548 | |||
549 | dev_set_uevent_suppress(f_dev, true); | ||
550 | |||
551 | retval = device_add(f_dev); | ||
552 | if (retval) { | ||
553 | dev_err(f_dev, "%s: device_register failed\n", __func__); | ||
554 | goto err_put_dev; | ||
555 | } | ||
556 | |||
557 | mutex_lock(&fw_lock); | ||
558 | list_add(&fw_priv->pending_list, &pending_fw_head); | ||
559 | mutex_unlock(&fw_lock); | ||
560 | |||
561 | if (opt_flags & FW_OPT_UEVENT) { | ||
562 | fw_priv->need_uevent = true; | ||
563 | dev_set_uevent_suppress(f_dev, false); | ||
564 | dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_name); | ||
565 | kobject_uevent(&fw_sysfs->dev.kobj, KOBJ_ADD); | ||
566 | } else { | ||
567 | timeout = MAX_JIFFY_OFFSET; | ||
568 | } | ||
569 | |||
570 | retval = fw_sysfs_wait_timeout(fw_priv, timeout); | ||
571 | if (retval < 0) { | ||
572 | mutex_lock(&fw_lock); | ||
573 | fw_load_abort(fw_sysfs); | ||
574 | mutex_unlock(&fw_lock); | ||
575 | } | ||
576 | |||
577 | if (fw_state_is_aborted(fw_priv)) { | ||
578 | if (retval == -ERESTARTSYS) | ||
579 | retval = -EINTR; | ||
580 | else | ||
581 | retval = -EAGAIN; | ||
582 | } else if (fw_priv->is_paged_buf && !fw_priv->data) | ||
583 | retval = -ENOMEM; | ||
584 | |||
585 | device_del(f_dev); | ||
586 | err_put_dev: | ||
587 | put_device(f_dev); | ||
588 | return retval; | ||
589 | } | ||
590 | |||
591 | static int fw_load_from_user_helper(struct firmware *firmware, | ||
592 | const char *name, struct device *device, | ||
593 | unsigned int opt_flags) | ||
594 | { | ||
595 | struct fw_sysfs *fw_sysfs; | ||
596 | long timeout; | ||
597 | int ret; | ||
598 | |||
599 | timeout = firmware_loading_timeout(); | ||
600 | if (opt_flags & FW_OPT_NOWAIT) { | ||
601 | timeout = usermodehelper_read_lock_wait(timeout); | ||
602 | if (!timeout) { | ||
603 | dev_dbg(device, "firmware: %s loading timed out\n", | ||
604 | name); | ||
605 | return -EBUSY; | ||
606 | } | ||
607 | } else { | ||
608 | ret = usermodehelper_read_trylock(); | ||
609 | if (WARN_ON(ret)) { | ||
610 | dev_err(device, "firmware: %s will not be loaded\n", | ||
611 | name); | ||
612 | return ret; | ||
613 | } | ||
614 | } | ||
615 | |||
616 | fw_sysfs = fw_create_instance(firmware, name, device, opt_flags); | ||
617 | if (IS_ERR(fw_sysfs)) { | ||
618 | ret = PTR_ERR(fw_sysfs); | ||
619 | goto out_unlock; | ||
620 | } | ||
621 | |||
622 | fw_sysfs->fw_priv = firmware->priv; | ||
623 | ret = _request_firmware_load(fw_sysfs, opt_flags, timeout); | ||
624 | |||
625 | if (!ret) | ||
626 | ret = assign_fw(firmware, device, opt_flags); | ||
627 | |||
628 | out_unlock: | ||
629 | usermodehelper_read_unlock(); | ||
630 | |||
631 | return ret; | ||
632 | } | ||
633 | |||
634 | static bool fw_force_sysfs_fallback(unsigned int opt_flags) | ||
635 | { | ||
636 | if (fw_fallback_config.force_sysfs_fallback) | ||
637 | return true; | ||
638 | if (!(opt_flags & FW_OPT_USERHELPER)) | ||
639 | return false; | ||
640 | return true; | ||
641 | } | ||
642 | |||
643 | static bool fw_run_sysfs_fallback(unsigned int opt_flags) | ||
644 | { | ||
645 | if ((opt_flags & FW_OPT_NOFALLBACK)) | ||
646 | return false; | ||
647 | |||
648 | return fw_force_sysfs_fallback(opt_flags); | ||
649 | } | ||
650 | |||
651 | int fw_sysfs_fallback(struct firmware *fw, const char *name, | ||
652 | struct device *device, | ||
653 | unsigned int opt_flags, | ||
654 | int ret) | ||
655 | { | ||
656 | if (!fw_run_sysfs_fallback(opt_flags)) | ||
657 | return ret; | ||
658 | |||
659 | dev_warn(device, "Falling back to user helper\n"); | ||
660 | return fw_load_from_user_helper(fw, name, device, opt_flags); | ||
661 | } | ||