diff options
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r-- | drivers/base/firmware_class.c | 550 |
1 files changed, 299 insertions, 251 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index b392b353be39..4a223fedcd73 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -88,11 +88,6 @@ enum { | |||
88 | FW_STATUS_ABORT, | 88 | FW_STATUS_ABORT, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | enum fw_buf_fmt { | ||
92 | VMALLOC_BUF, /* used in direct loading */ | ||
93 | PAGE_BUF, /* used in loading via userspace */ | ||
94 | }; | ||
95 | |||
96 | static int loading_timeout = 60; /* In seconds */ | 91 | static int loading_timeout = 60; /* In seconds */ |
97 | 92 | ||
98 | static inline long firmware_loading_timeout(void) | 93 | static inline long firmware_loading_timeout(void) |
@@ -128,12 +123,14 @@ struct firmware_buf { | |||
128 | struct completion completion; | 123 | struct completion completion; |
129 | struct firmware_cache *fwc; | 124 | struct firmware_cache *fwc; |
130 | unsigned long status; | 125 | unsigned long status; |
131 | enum fw_buf_fmt fmt; | ||
132 | void *data; | 126 | void *data; |
133 | size_t size; | 127 | size_t size; |
128 | #ifdef CONFIG_FW_LOADER_USER_HELPER | ||
129 | bool is_paged_buf; | ||
134 | struct page **pages; | 130 | struct page **pages; |
135 | int nr_pages; | 131 | int nr_pages; |
136 | int page_array_size; | 132 | int page_array_size; |
133 | #endif | ||
137 | char fw_id[]; | 134 | char fw_id[]; |
138 | }; | 135 | }; |
139 | 136 | ||
@@ -142,14 +139,6 @@ struct fw_cache_entry { | |||
142 | char name[]; | 139 | char name[]; |
143 | }; | 140 | }; |
144 | 141 | ||
145 | struct firmware_priv { | ||
146 | struct delayed_work timeout_work; | ||
147 | bool nowait; | ||
148 | struct device dev; | ||
149 | struct firmware_buf *buf; | ||
150 | struct firmware *fw; | ||
151 | }; | ||
152 | |||
153 | struct fw_name_devm { | 142 | struct fw_name_devm { |
154 | unsigned long magic; | 143 | unsigned long magic; |
155 | char name[]; | 144 | char name[]; |
@@ -182,7 +171,6 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name, | |||
182 | strcpy(buf->fw_id, fw_name); | 171 | strcpy(buf->fw_id, fw_name); |
183 | buf->fwc = fwc; | 172 | buf->fwc = fwc; |
184 | init_completion(&buf->completion); | 173 | init_completion(&buf->completion); |
185 | buf->fmt = VMALLOC_BUF; | ||
186 | 174 | ||
187 | pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); | 175 | pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); |
188 | 176 | ||
@@ -240,7 +228,6 @@ static void __fw_free_buf(struct kref *ref) | |||
240 | { | 228 | { |
241 | struct firmware_buf *buf = to_fwbuf(ref); | 229 | struct firmware_buf *buf = to_fwbuf(ref); |
242 | struct firmware_cache *fwc = buf->fwc; | 230 | struct firmware_cache *fwc = buf->fwc; |
243 | int i; | ||
244 | 231 | ||
245 | pr_debug("%s: fw-%s buf=%p data=%p size=%u\n", | 232 | pr_debug("%s: fw-%s buf=%p data=%p size=%u\n", |
246 | __func__, buf->fw_id, buf, buf->data, | 233 | __func__, buf->fw_id, buf, buf->data, |
@@ -249,13 +236,15 @@ static void __fw_free_buf(struct kref *ref) | |||
249 | list_del(&buf->list); | 236 | list_del(&buf->list); |
250 | spin_unlock(&fwc->lock); | 237 | spin_unlock(&fwc->lock); |
251 | 238 | ||
252 | 239 | #ifdef CONFIG_FW_LOADER_USER_HELPER | |
253 | if (buf->fmt == PAGE_BUF) { | 240 | if (buf->is_paged_buf) { |
241 | int i; | ||
254 | vunmap(buf->data); | 242 | vunmap(buf->data); |
255 | for (i = 0; i < buf->nr_pages; i++) | 243 | for (i = 0; i < buf->nr_pages; i++) |
256 | __free_page(buf->pages[i]); | 244 | __free_page(buf->pages[i]); |
257 | kfree(buf->pages); | 245 | kfree(buf->pages); |
258 | } else | 246 | } else |
247 | #endif | ||
259 | vfree(buf->data); | 248 | vfree(buf->data); |
260 | kfree(buf); | 249 | kfree(buf); |
261 | } | 250 | } |
@@ -319,7 +308,8 @@ static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf | |||
319 | return true; | 308 | return true; |
320 | } | 309 | } |
321 | 310 | ||
322 | static bool fw_get_filesystem_firmware(struct firmware_buf *buf) | 311 | static bool fw_get_filesystem_firmware(struct device *device, |
312 | struct firmware_buf *buf) | ||
323 | { | 313 | { |
324 | int i; | 314 | int i; |
325 | bool success = false; | 315 | bool success = false; |
@@ -343,9 +333,114 @@ static bool fw_get_filesystem_firmware(struct firmware_buf *buf) | |||
343 | break; | 333 | break; |
344 | } | 334 | } |
345 | __putname(path); | 335 | __putname(path); |
336 | |||
337 | if (success) { | ||
338 | dev_dbg(device, "firmware: direct-loading firmware %s\n", | ||
339 | buf->fw_id); | ||
340 | mutex_lock(&fw_lock); | ||
341 | set_bit(FW_STATUS_DONE, &buf->status); | ||
342 | complete_all(&buf->completion); | ||
343 | mutex_unlock(&fw_lock); | ||
344 | } | ||
345 | |||
346 | return success; | 346 | return success; |
347 | } | 347 | } |
348 | 348 | ||
349 | /* firmware holds the ownership of pages */ | ||
350 | static void firmware_free_data(const struct firmware *fw) | ||
351 | { | ||
352 | /* Loaded directly? */ | ||
353 | if (!fw->priv) { | ||
354 | vfree(fw->data); | ||
355 | return; | ||
356 | } | ||
357 | fw_free_buf(fw->priv); | ||
358 | } | ||
359 | |||
360 | /* store the pages buffer info firmware from buf */ | ||
361 | static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) | ||
362 | { | ||
363 | fw->priv = buf; | ||
364 | #ifdef CONFIG_FW_LOADER_USER_HELPER | ||
365 | fw->pages = buf->pages; | ||
366 | #endif | ||
367 | fw->size = buf->size; | ||
368 | fw->data = buf->data; | ||
369 | |||
370 | pr_debug("%s: fw-%s buf=%p data=%p size=%u\n", | ||
371 | __func__, buf->fw_id, buf, buf->data, | ||
372 | (unsigned int)buf->size); | ||
373 | } | ||
374 | |||
375 | #ifdef CONFIG_PM_SLEEP | ||
376 | static void fw_name_devm_release(struct device *dev, void *res) | ||
377 | { | ||
378 | struct fw_name_devm *fwn = res; | ||
379 | |||
380 | if (fwn->magic == (unsigned long)&fw_cache) | ||
381 | pr_debug("%s: fw_name-%s devm-%p released\n", | ||
382 | __func__, fwn->name, res); | ||
383 | } | ||
384 | |||
385 | static int fw_devm_match(struct device *dev, void *res, | ||
386 | void *match_data) | ||
387 | { | ||
388 | struct fw_name_devm *fwn = res; | ||
389 | |||
390 | return (fwn->magic == (unsigned long)&fw_cache) && | ||
391 | !strcmp(fwn->name, match_data); | ||
392 | } | ||
393 | |||
394 | static struct fw_name_devm *fw_find_devm_name(struct device *dev, | ||
395 | const char *name) | ||
396 | { | ||
397 | struct fw_name_devm *fwn; | ||
398 | |||
399 | fwn = devres_find(dev, fw_name_devm_release, | ||
400 | fw_devm_match, (void *)name); | ||
401 | return fwn; | ||
402 | } | ||
403 | |||
404 | /* add firmware name into devres list */ | ||
405 | static int fw_add_devm_name(struct device *dev, const char *name) | ||
406 | { | ||
407 | struct fw_name_devm *fwn; | ||
408 | |||
409 | fwn = fw_find_devm_name(dev, name); | ||
410 | if (fwn) | ||
411 | return 1; | ||
412 | |||
413 | fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm) + | ||
414 | strlen(name) + 1, GFP_KERNEL); | ||
415 | if (!fwn) | ||
416 | return -ENOMEM; | ||
417 | |||
418 | fwn->magic = (unsigned long)&fw_cache; | ||
419 | strcpy(fwn->name, name); | ||
420 | devres_add(dev, fwn); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | #else | ||
425 | static int fw_add_devm_name(struct device *dev, const char *name) | ||
426 | { | ||
427 | return 0; | ||
428 | } | ||
429 | #endif | ||
430 | |||
431 | |||
432 | /* | ||
433 | * user-mode helper code | ||
434 | */ | ||
435 | #ifdef CONFIG_FW_LOADER_USER_HELPER | ||
436 | struct firmware_priv { | ||
437 | struct delayed_work timeout_work; | ||
438 | bool nowait; | ||
439 | struct device dev; | ||
440 | struct firmware_buf *buf; | ||
441 | struct firmware *fw; | ||
442 | }; | ||
443 | |||
349 | static struct firmware_priv *to_firmware_priv(struct device *dev) | 444 | static struct firmware_priv *to_firmware_priv(struct device *dev) |
350 | { | 445 | { |
351 | return container_of(dev, struct firmware_priv, dev); | 446 | return container_of(dev, struct firmware_priv, dev); |
@@ -359,6 +454,9 @@ static void fw_load_abort(struct firmware_priv *fw_priv) | |||
359 | complete_all(&buf->completion); | 454 | complete_all(&buf->completion); |
360 | } | 455 | } |
361 | 456 | ||
457 | #define is_fw_load_aborted(buf) \ | ||
458 | test_bit(FW_STATUS_ABORT, &(buf)->status) | ||
459 | |||
362 | static ssize_t firmware_timeout_show(struct class *class, | 460 | static ssize_t firmware_timeout_show(struct class *class, |
363 | struct class_attribute *attr, | 461 | struct class_attribute *attr, |
364 | char *buf) | 462 | char *buf) |
@@ -435,17 +533,6 @@ static ssize_t firmware_loading_show(struct device *dev, | |||
435 | return sprintf(buf, "%d\n", loading); | 533 | return sprintf(buf, "%d\n", loading); |
436 | } | 534 | } |
437 | 535 | ||
438 | /* firmware holds the ownership of pages */ | ||
439 | static void firmware_free_data(const struct firmware *fw) | ||
440 | { | ||
441 | /* Loaded directly? */ | ||
442 | if (!fw->priv) { | ||
443 | vfree(fw->data); | ||
444 | return; | ||
445 | } | ||
446 | fw_free_buf(fw->priv); | ||
447 | } | ||
448 | |||
449 | /* Some architectures don't have PAGE_KERNEL_RO */ | 536 | /* Some architectures don't have PAGE_KERNEL_RO */ |
450 | #ifndef PAGE_KERNEL_RO | 537 | #ifndef PAGE_KERNEL_RO |
451 | #define PAGE_KERNEL_RO PAGE_KERNEL | 538 | #define PAGE_KERNEL_RO PAGE_KERNEL |
@@ -454,7 +541,7 @@ static void firmware_free_data(const struct firmware *fw) | |||
454 | /* one pages buffer should be mapped/unmapped only once */ | 541 | /* one pages buffer should be mapped/unmapped only once */ |
455 | static int fw_map_pages_buf(struct firmware_buf *buf) | 542 | static int fw_map_pages_buf(struct firmware_buf *buf) |
456 | { | 543 | { |
457 | if (buf->fmt != PAGE_BUF) | 544 | if (!buf->is_paged_buf) |
458 | return 0; | 545 | return 0; |
459 | 546 | ||
460 | if (buf->data) | 547 | if (buf->data) |
@@ -727,171 +814,16 @@ exit: | |||
727 | return fw_priv; | 814 | return fw_priv; |
728 | } | 815 | } |
729 | 816 | ||
730 | /* store the pages buffer info firmware from buf */ | 817 | /* load a firmware via user helper */ |
731 | static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) | ||
732 | { | ||
733 | fw->priv = buf; | ||
734 | fw->pages = buf->pages; | ||
735 | fw->size = buf->size; | ||
736 | fw->data = buf->data; | ||
737 | |||
738 | pr_debug("%s: fw-%s buf=%p data=%p size=%u\n", | ||
739 | __func__, buf->fw_id, buf, buf->data, | ||
740 | (unsigned int)buf->size); | ||
741 | } | ||
742 | |||
743 | #ifdef CONFIG_PM_SLEEP | ||
744 | static void fw_name_devm_release(struct device *dev, void *res) | ||
745 | { | ||
746 | struct fw_name_devm *fwn = res; | ||
747 | |||
748 | if (fwn->magic == (unsigned long)&fw_cache) | ||
749 | pr_debug("%s: fw_name-%s devm-%p released\n", | ||
750 | __func__, fwn->name, res); | ||
751 | } | ||
752 | |||
753 | static int fw_devm_match(struct device *dev, void *res, | ||
754 | void *match_data) | ||
755 | { | ||
756 | struct fw_name_devm *fwn = res; | ||
757 | |||
758 | return (fwn->magic == (unsigned long)&fw_cache) && | ||
759 | !strcmp(fwn->name, match_data); | ||
760 | } | ||
761 | |||
762 | static struct fw_name_devm *fw_find_devm_name(struct device *dev, | ||
763 | const char *name) | ||
764 | { | ||
765 | struct fw_name_devm *fwn; | ||
766 | |||
767 | fwn = devres_find(dev, fw_name_devm_release, | ||
768 | fw_devm_match, (void *)name); | ||
769 | return fwn; | ||
770 | } | ||
771 | |||
772 | /* add firmware name into devres list */ | ||
773 | static int fw_add_devm_name(struct device *dev, const char *name) | ||
774 | { | ||
775 | struct fw_name_devm *fwn; | ||
776 | |||
777 | fwn = fw_find_devm_name(dev, name); | ||
778 | if (fwn) | ||
779 | return 1; | ||
780 | |||
781 | fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm) + | ||
782 | strlen(name) + 1, GFP_KERNEL); | ||
783 | if (!fwn) | ||
784 | return -ENOMEM; | ||
785 | |||
786 | fwn->magic = (unsigned long)&fw_cache; | ||
787 | strcpy(fwn->name, name); | ||
788 | devres_add(dev, fwn); | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | #else | ||
793 | static int fw_add_devm_name(struct device *dev, const char *name) | ||
794 | { | ||
795 | return 0; | ||
796 | } | ||
797 | #endif | ||
798 | |||
799 | static void _request_firmware_cleanup(const struct firmware **firmware_p) | ||
800 | { | ||
801 | release_firmware(*firmware_p); | ||
802 | *firmware_p = NULL; | ||
803 | } | ||
804 | |||
805 | static struct firmware_priv * | ||
806 | _request_firmware_prepare(const struct firmware **firmware_p, const char *name, | ||
807 | struct device *device, bool uevent, bool nowait) | ||
808 | { | ||
809 | struct firmware *firmware; | ||
810 | struct firmware_priv *fw_priv = NULL; | ||
811 | struct firmware_buf *buf; | ||
812 | int ret; | ||
813 | |||
814 | if (!firmware_p) | ||
815 | return ERR_PTR(-EINVAL); | ||
816 | |||
817 | *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); | ||
818 | if (!firmware) { | ||
819 | dev_err(device, "%s: kmalloc(struct firmware) failed\n", | ||
820 | __func__); | ||
821 | return ERR_PTR(-ENOMEM); | ||
822 | } | ||
823 | |||
824 | if (fw_get_builtin_firmware(firmware, name)) { | ||
825 | dev_dbg(device, "firmware: using built-in firmware %s\n", name); | ||
826 | return NULL; | ||
827 | } | ||
828 | |||
829 | ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf); | ||
830 | if (!ret) | ||
831 | fw_priv = fw_create_instance(firmware, name, device, | ||
832 | uevent, nowait); | ||
833 | |||
834 | if (IS_ERR(fw_priv) || ret < 0) { | ||
835 | kfree(firmware); | ||
836 | *firmware_p = NULL; | ||
837 | return ERR_PTR(-ENOMEM); | ||
838 | } else if (fw_priv) { | ||
839 | fw_priv->buf = buf; | ||
840 | |||
841 | /* | ||
842 | * bind with 'buf' now to avoid warning in failure path | ||
843 | * of requesting firmware. | ||
844 | */ | ||
845 | firmware->priv = buf; | ||
846 | return fw_priv; | ||
847 | } | ||
848 | |||
849 | /* share the cached buf, which is inprogessing or completed */ | ||
850 | check_status: | ||
851 | mutex_lock(&fw_lock); | ||
852 | if (test_bit(FW_STATUS_ABORT, &buf->status)) { | ||
853 | fw_priv = ERR_PTR(-ENOENT); | ||
854 | firmware->priv = buf; | ||
855 | _request_firmware_cleanup(firmware_p); | ||
856 | goto exit; | ||
857 | } else if (test_bit(FW_STATUS_DONE, &buf->status)) { | ||
858 | fw_priv = NULL; | ||
859 | fw_set_page_data(buf, firmware); | ||
860 | goto exit; | ||
861 | } | ||
862 | mutex_unlock(&fw_lock); | ||
863 | wait_for_completion(&buf->completion); | ||
864 | goto check_status; | ||
865 | |||
866 | exit: | ||
867 | mutex_unlock(&fw_lock); | ||
868 | return fw_priv; | ||
869 | } | ||
870 | |||
871 | static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | 818 | static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, |
872 | long timeout) | 819 | long timeout) |
873 | { | 820 | { |
874 | int retval = 0; | 821 | int retval = 0; |
875 | struct device *f_dev = &fw_priv->dev; | 822 | struct device *f_dev = &fw_priv->dev; |
876 | struct firmware_buf *buf = fw_priv->buf; | 823 | struct firmware_buf *buf = fw_priv->buf; |
877 | struct firmware_cache *fwc = &fw_cache; | ||
878 | int direct_load = 0; | ||
879 | |||
880 | /* try direct loading from fs first */ | ||
881 | if (fw_get_filesystem_firmware(buf)) { | ||
882 | dev_dbg(f_dev->parent, "firmware: direct-loading" | ||
883 | " firmware %s\n", buf->fw_id); | ||
884 | |||
885 | mutex_lock(&fw_lock); | ||
886 | set_bit(FW_STATUS_DONE, &buf->status); | ||
887 | mutex_unlock(&fw_lock); | ||
888 | complete_all(&buf->completion); | ||
889 | direct_load = 1; | ||
890 | goto handle_fw; | ||
891 | } | ||
892 | 824 | ||
893 | /* fall back on userspace loading */ | 825 | /* fall back on userspace loading */ |
894 | buf->fmt = PAGE_BUF; | 826 | buf->is_paged_buf = true; |
895 | 827 | ||
896 | dev_set_uevent_suppress(f_dev, true); | 828 | dev_set_uevent_suppress(f_dev, true); |
897 | 829 | ||
@@ -929,47 +861,196 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
929 | 861 | ||
930 | cancel_delayed_work_sync(&fw_priv->timeout_work); | 862 | cancel_delayed_work_sync(&fw_priv->timeout_work); |
931 | 863 | ||
932 | handle_fw: | 864 | fw_priv->buf = NULL; |
865 | |||
866 | device_remove_file(f_dev, &dev_attr_loading); | ||
867 | err_del_bin_attr: | ||
868 | device_remove_bin_file(f_dev, &firmware_attr_data); | ||
869 | err_del_dev: | ||
870 | device_del(f_dev); | ||
871 | err_put_dev: | ||
872 | put_device(f_dev); | ||
873 | return retval; | ||
874 | } | ||
875 | |||
876 | static int fw_load_from_user_helper(struct firmware *firmware, | ||
877 | const char *name, struct device *device, | ||
878 | bool uevent, bool nowait, long timeout) | ||
879 | { | ||
880 | struct firmware_priv *fw_priv; | ||
881 | |||
882 | fw_priv = fw_create_instance(firmware, name, device, uevent, nowait); | ||
883 | if (IS_ERR(fw_priv)) | ||
884 | return PTR_ERR(fw_priv); | ||
885 | |||
886 | fw_priv->buf = firmware->priv; | ||
887 | return _request_firmware_load(fw_priv, uevent, timeout); | ||
888 | } | ||
889 | #else /* CONFIG_FW_LOADER_USER_HELPER */ | ||
890 | static inline int | ||
891 | fw_load_from_user_helper(struct firmware *firmware, const char *name, | ||
892 | struct device *device, bool uevent, bool nowait, | ||
893 | long timeout) | ||
894 | { | ||
895 | return -ENOENT; | ||
896 | } | ||
897 | |||
898 | /* No abort during direct loading */ | ||
899 | #define is_fw_load_aborted(buf) false | ||
900 | |||
901 | #endif /* CONFIG_FW_LOADER_USER_HELPER */ | ||
902 | |||
903 | |||
904 | /* wait until the shared firmware_buf becomes ready (or error) */ | ||
905 | static int sync_cached_firmware_buf(struct firmware_buf *buf) | ||
906 | { | ||
907 | int ret = 0; | ||
908 | |||
909 | mutex_lock(&fw_lock); | ||
910 | while (!test_bit(FW_STATUS_DONE, &buf->status)) { | ||
911 | if (is_fw_load_aborted(buf)) { | ||
912 | ret = -ENOENT; | ||
913 | break; | ||
914 | } | ||
915 | mutex_unlock(&fw_lock); | ||
916 | wait_for_completion(&buf->completion); | ||
917 | mutex_lock(&fw_lock); | ||
918 | } | ||
919 | mutex_unlock(&fw_lock); | ||
920 | return ret; | ||
921 | } | ||
922 | |||
923 | /* prepare firmware and firmware_buf structs; | ||
924 | * return 0 if a firmware is already assigned, 1 if need to load one, | ||
925 | * or a negative error code | ||
926 | */ | ||
927 | static int | ||
928 | _request_firmware_prepare(struct firmware **firmware_p, const char *name, | ||
929 | struct device *device) | ||
930 | { | ||
931 | struct firmware *firmware; | ||
932 | struct firmware_buf *buf; | ||
933 | int ret; | ||
934 | |||
935 | *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); | ||
936 | if (!firmware) { | ||
937 | dev_err(device, "%s: kmalloc(struct firmware) failed\n", | ||
938 | __func__); | ||
939 | return -ENOMEM; | ||
940 | } | ||
941 | |||
942 | if (fw_get_builtin_firmware(firmware, name)) { | ||
943 | dev_dbg(device, "firmware: using built-in firmware %s\n", name); | ||
944 | return 0; /* assigned */ | ||
945 | } | ||
946 | |||
947 | ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf); | ||
948 | |||
949 | /* | ||
950 | * bind with 'buf' now to avoid warning in failure path | ||
951 | * of requesting firmware. | ||
952 | */ | ||
953 | firmware->priv = buf; | ||
954 | |||
955 | if (ret > 0) { | ||
956 | ret = sync_cached_firmware_buf(buf); | ||
957 | if (!ret) { | ||
958 | fw_set_page_data(buf, firmware); | ||
959 | return 0; /* assigned */ | ||
960 | } | ||
961 | } | ||
962 | |||
963 | if (ret < 0) | ||
964 | return ret; | ||
965 | return 1; /* need to load */ | ||
966 | } | ||
967 | |||
968 | static int assign_firmware_buf(struct firmware *fw, struct device *device) | ||
969 | { | ||
970 | struct firmware_buf *buf = fw->priv; | ||
971 | |||
933 | mutex_lock(&fw_lock); | 972 | mutex_lock(&fw_lock); |
934 | if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status)) | 973 | if (!buf->size || is_fw_load_aborted(buf)) { |
935 | retval = -ENOENT; | 974 | mutex_unlock(&fw_lock); |
975 | return -ENOENT; | ||
976 | } | ||
936 | 977 | ||
937 | /* | 978 | /* |
938 | * add firmware name into devres list so that we can auto cache | 979 | * add firmware name into devres list so that we can auto cache |
939 | * and uncache firmware for device. | 980 | * and uncache firmware for device. |
940 | * | 981 | * |
941 | * f_dev->parent may has been deleted already, but the problem | 982 | * device may has been deleted already, but the problem |
942 | * should be fixed in devres or driver core. | 983 | * should be fixed in devres or driver core. |
943 | */ | 984 | */ |
944 | if (!retval && f_dev->parent) | 985 | if (device) |
945 | fw_add_devm_name(f_dev->parent, buf->fw_id); | 986 | fw_add_devm_name(device, buf->fw_id); |
946 | 987 | ||
947 | /* | 988 | /* |
948 | * After caching firmware image is started, let it piggyback | 989 | * After caching firmware image is started, let it piggyback |
949 | * on request firmware. | 990 | * on request firmware. |
950 | */ | 991 | */ |
951 | if (!retval && fwc->state == FW_LOADER_START_CACHE) { | 992 | if (buf->fwc->state == FW_LOADER_START_CACHE) { |
952 | if (fw_cache_piggyback_on_request(buf->fw_id)) | 993 | if (fw_cache_piggyback_on_request(buf->fw_id)) |
953 | kref_get(&buf->ref); | 994 | kref_get(&buf->ref); |
954 | } | 995 | } |
955 | 996 | ||
956 | /* pass the pages buffer to driver at the last minute */ | 997 | /* pass the pages buffer to driver at the last minute */ |
957 | fw_set_page_data(buf, fw_priv->fw); | 998 | fw_set_page_data(buf, fw); |
958 | |||
959 | fw_priv->buf = NULL; | ||
960 | mutex_unlock(&fw_lock); | 999 | mutex_unlock(&fw_lock); |
1000 | return 0; | ||
1001 | } | ||
961 | 1002 | ||
962 | if (direct_load) | 1003 | /* called from request_firmware() and request_firmware_work_func() */ |
963 | goto err_put_dev; | 1004 | static int |
1005 | _request_firmware(const struct firmware **firmware_p, const char *name, | ||
1006 | struct device *device, bool uevent, bool nowait) | ||
1007 | { | ||
1008 | struct firmware *fw; | ||
1009 | long timeout; | ||
1010 | int ret; | ||
964 | 1011 | ||
965 | device_remove_file(f_dev, &dev_attr_loading); | 1012 | if (!firmware_p) |
966 | err_del_bin_attr: | 1013 | return -EINVAL; |
967 | device_remove_bin_file(f_dev, &firmware_attr_data); | 1014 | |
968 | err_del_dev: | 1015 | ret = _request_firmware_prepare(&fw, name, device); |
969 | device_del(f_dev); | 1016 | if (ret <= 0) /* error or already assigned */ |
970 | err_put_dev: | 1017 | goto out; |
971 | put_device(f_dev); | 1018 | |
972 | return retval; | 1019 | ret = 0; |
1020 | timeout = firmware_loading_timeout(); | ||
1021 | if (nowait) { | ||
1022 | timeout = usermodehelper_read_lock_wait(timeout); | ||
1023 | if (!timeout) { | ||
1024 | dev_dbg(device, "firmware: %s loading timed out\n", | ||
1025 | name); | ||
1026 | ret = -EBUSY; | ||
1027 | goto out; | ||
1028 | } | ||
1029 | } else { | ||
1030 | ret = usermodehelper_read_trylock(); | ||
1031 | if (WARN_ON(ret)) { | ||
1032 | dev_err(device, "firmware: %s will not be loaded\n", | ||
1033 | name); | ||
1034 | goto out; | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | if (!fw_get_filesystem_firmware(device, fw->priv)) | ||
1039 | ret = fw_load_from_user_helper(fw, name, device, | ||
1040 | uevent, nowait, timeout); | ||
1041 | if (!ret) | ||
1042 | ret = assign_firmware_buf(fw, device); | ||
1043 | |||
1044 | usermodehelper_read_unlock(); | ||
1045 | |||
1046 | out: | ||
1047 | if (ret < 0) { | ||
1048 | release_firmware(fw); | ||
1049 | fw = NULL; | ||
1050 | } | ||
1051 | |||
1052 | *firmware_p = fw; | ||
1053 | return ret; | ||
973 | } | 1054 | } |
974 | 1055 | ||
975 | /** | 1056 | /** |
@@ -996,26 +1077,7 @@ int | |||
996 | request_firmware(const struct firmware **firmware_p, const char *name, | 1077 | request_firmware(const struct firmware **firmware_p, const char *name, |
997 | struct device *device) | 1078 | struct device *device) |
998 | { | 1079 | { |
999 | struct firmware_priv *fw_priv; | 1080 | return _request_firmware(firmware_p, name, device, true, false); |
1000 | int ret; | ||
1001 | |||
1002 | fw_priv = _request_firmware_prepare(firmware_p, name, device, true, | ||
1003 | false); | ||
1004 | if (IS_ERR_OR_NULL(fw_priv)) | ||
1005 | return PTR_RET(fw_priv); | ||
1006 | |||
1007 | ret = usermodehelper_read_trylock(); | ||
1008 | if (WARN_ON(ret)) { | ||
1009 | dev_err(device, "firmware: %s will not be loaded\n", name); | ||
1010 | } else { | ||
1011 | ret = _request_firmware_load(fw_priv, true, | ||
1012 | firmware_loading_timeout()); | ||
1013 | usermodehelper_read_unlock(); | ||
1014 | } | ||
1015 | if (ret) | ||
1016 | _request_firmware_cleanup(firmware_p); | ||
1017 | |||
1018 | return ret; | ||
1019 | } | 1081 | } |
1020 | 1082 | ||
1021 | /** | 1083 | /** |
@@ -1046,33 +1108,13 @@ static void request_firmware_work_func(struct work_struct *work) | |||
1046 | { | 1108 | { |
1047 | struct firmware_work *fw_work; | 1109 | struct firmware_work *fw_work; |
1048 | const struct firmware *fw; | 1110 | const struct firmware *fw; |
1049 | struct firmware_priv *fw_priv; | ||
1050 | long timeout; | ||
1051 | int ret; | ||
1052 | 1111 | ||
1053 | fw_work = container_of(work, struct firmware_work, work); | 1112 | fw_work = container_of(work, struct firmware_work, work); |
1054 | fw_priv = _request_firmware_prepare(&fw, fw_work->name, fw_work->device, | ||
1055 | fw_work->uevent, true); | ||
1056 | if (IS_ERR_OR_NULL(fw_priv)) { | ||
1057 | ret = PTR_RET(fw_priv); | ||
1058 | goto out; | ||
1059 | } | ||
1060 | |||
1061 | timeout = usermodehelper_read_lock_wait(firmware_loading_timeout()); | ||
1062 | if (timeout) { | ||
1063 | ret = _request_firmware_load(fw_priv, fw_work->uevent, timeout); | ||
1064 | usermodehelper_read_unlock(); | ||
1065 | } else { | ||
1066 | dev_dbg(fw_work->device, "firmware: %s loading timed out\n", | ||
1067 | fw_work->name); | ||
1068 | ret = -EAGAIN; | ||
1069 | } | ||
1070 | if (ret) | ||
1071 | _request_firmware_cleanup(&fw); | ||
1072 | 1113 | ||
1073 | out: | 1114 | _request_firmware(&fw, fw_work->name, fw_work->device, |
1115 | fw_work->uevent, true); | ||
1074 | fw_work->cont(fw, fw_work->context); | 1116 | fw_work->cont(fw, fw_work->context); |
1075 | put_device(fw_work->device); | 1117 | put_device(fw_work->device); /* taken in request_firmware_nowait() */ |
1076 | 1118 | ||
1077 | module_put(fw_work->module); | 1119 | module_put(fw_work->module); |
1078 | kfree(fw_work); | 1120 | kfree(fw_work); |
@@ -1474,7 +1516,11 @@ static void __init fw_cache_init(void) | |||
1474 | static int __init firmware_class_init(void) | 1516 | static int __init firmware_class_init(void) |
1475 | { | 1517 | { |
1476 | fw_cache_init(); | 1518 | fw_cache_init(); |
1519 | #ifdef CONFIG_FW_LOADER_USER_HELPER | ||
1477 | return class_register(&firmware_class); | 1520 | return class_register(&firmware_class); |
1521 | #else | ||
1522 | return 0; | ||
1523 | #endif | ||
1478 | } | 1524 | } |
1479 | 1525 | ||
1480 | static void __exit firmware_class_exit(void) | 1526 | static void __exit firmware_class_exit(void) |
@@ -1483,7 +1529,9 @@ static void __exit firmware_class_exit(void) | |||
1483 | unregister_syscore_ops(&fw_syscore_ops); | 1529 | unregister_syscore_ops(&fw_syscore_ops); |
1484 | unregister_pm_notifier(&fw_cache.pm_notify); | 1530 | unregister_pm_notifier(&fw_cache.pm_notify); |
1485 | #endif | 1531 | #endif |
1532 | #ifdef CONFIG_FW_LOADER_USER_HELPER | ||
1486 | class_unregister(&firmware_class); | 1533 | class_unregister(&firmware_class); |
1534 | #endif | ||
1487 | } | 1535 | } |
1488 | 1536 | ||
1489 | fs_initcall(firmware_class_init); | 1537 | fs_initcall(firmware_class_init); |