aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-01-31 05:13:56 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-02-03 20:57:40 -0500
commitcd7239fab7d32e56909027bfb5a6c2d7d3d862f8 (patch)
treed951829a1bf1461ced3e763c766310b78c6a4a7d
parent7b1269f778782d2f42994a74bf4014d0cbebbf9f (diff)
firmware: Reduce ifdef CONFIG_FW_LOADER_USER_HELPER
By shuffling the code, reduce a few ifdefs in firmware_class.c. Also, firmware_buf fmt field is changed to is_pages_buf boolean for simplification. Acked-by: Ming Lei <ming.lei@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/base/firmware_class.c313
1 files changed, 151 insertions, 162 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 84b1c8d0ea56..51e62ca1d574 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -88,13 +88,6 @@ enum {
88 FW_STATUS_ABORT, 88 FW_STATUS_ABORT,
89}; 89};
90 90
91#ifdef CONFIG_FW_LOADER_USER_HELPER
92enum fw_buf_fmt {
93 VMALLOC_BUF, /* used in direct loading */
94 PAGE_BUF, /* used in loading via userspace */
95};
96#endif /* CONFIG_FW_LOADER_USER_HELPER */
97
98static int loading_timeout = 60; /* In seconds */ 91static int loading_timeout = 60; /* In seconds */
99 92
100static inline long firmware_loading_timeout(void) 93static inline long firmware_loading_timeout(void)
@@ -133,7 +126,7 @@ struct firmware_buf {
133 void *data; 126 void *data;
134 size_t size; 127 size_t size;
135#ifdef CONFIG_FW_LOADER_USER_HELPER 128#ifdef CONFIG_FW_LOADER_USER_HELPER
136 enum fw_buf_fmt fmt; 129 bool is_paged_buf;
137 struct page **pages; 130 struct page **pages;
138 int nr_pages; 131 int nr_pages;
139 int page_array_size; 132 int page_array_size;
@@ -146,16 +139,6 @@ struct fw_cache_entry {
146 char name[]; 139 char name[];
147}; 140};
148 141
149#ifdef CONFIG_FW_LOADER_USER_HELPER
150struct firmware_priv {
151 struct delayed_work timeout_work;
152 bool nowait;
153 struct device dev;
154 struct firmware_buf *buf;
155 struct firmware *fw;
156};
157#endif
158
159struct fw_name_devm { 142struct fw_name_devm {
160 unsigned long magic; 143 unsigned long magic;
161 char name[]; 144 char name[];
@@ -188,9 +171,6 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name,
188 strcpy(buf->fw_id, fw_name); 171 strcpy(buf->fw_id, fw_name);
189 buf->fwc = fwc; 172 buf->fwc = fwc;
190 init_completion(&buf->completion); 173 init_completion(&buf->completion);
191#ifdef CONFIG_FW_LOADER_USER_HELPER
192 buf->fmt = VMALLOC_BUF;
193#endif
194 174
195 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);
196 176
@@ -256,9 +236,8 @@ static void __fw_free_buf(struct kref *ref)
256 list_del(&buf->list); 236 list_del(&buf->list);
257 spin_unlock(&fwc->lock); 237 spin_unlock(&fwc->lock);
258 238
259
260#ifdef CONFIG_FW_LOADER_USER_HELPER 239#ifdef CONFIG_FW_LOADER_USER_HELPER
261 if (buf->fmt == PAGE_BUF) { 240 if (buf->is_paged_buf) {
262 int i; 241 int i;
263 vunmap(buf->data); 242 vunmap(buf->data);
264 for (i = 0; i < buf->nr_pages; i++) 243 for (i = 0; i < buf->nr_pages; i++)
@@ -378,7 +357,89 @@ static void firmware_free_data(const struct firmware *fw)
378 fw_free_buf(fw->priv); 357 fw_free_buf(fw->priv);
379} 358}
380 359
360/* store the pages buffer info firmware from buf */
361static 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
376static 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
385static 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
394static 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 */
405static 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
425static 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 */
381#ifdef CONFIG_FW_LOADER_USER_HELPER 435#ifdef CONFIG_FW_LOADER_USER_HELPER
436struct 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};
382 443
383static struct firmware_priv *to_firmware_priv(struct device *dev) 444static struct firmware_priv *to_firmware_priv(struct device *dev)
384{ 445{
@@ -477,7 +538,7 @@ static ssize_t firmware_loading_show(struct device *dev,
477/* one pages buffer should be mapped/unmapped only once */ 538/* one pages buffer should be mapped/unmapped only once */
478static int fw_map_pages_buf(struct firmware_buf *buf) 539static int fw_map_pages_buf(struct firmware_buf *buf)
479{ 540{
480 if (buf->fmt != PAGE_BUF) 541 if (!buf->is_paged_buf)
481 return 0; 542 return 0;
482 543
483 if (buf->data) 544 if (buf->data)
@@ -749,78 +810,89 @@ fw_create_instance(struct firmware *firmware, const char *fw_name,
749exit: 810exit:
750 return fw_priv; 811 return fw_priv;
751} 812}
752#endif /* CONFIG_FW_LOADER_USER_HELPER */
753 813
754/* store the pages buffer info firmware from buf */ 814/* load a firmware via user helper */
755static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) 815static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
816 long timeout)
756{ 817{
757 fw->priv = buf; 818 int retval = 0;
758#ifdef CONFIG_FW_LOADER_USER_HELPER 819 struct device *f_dev = &fw_priv->dev;
759 fw->pages = buf->pages; 820 struct firmware_buf *buf = fw_priv->buf;
760#endif
761 fw->size = buf->size;
762 fw->data = buf->data;
763 821
764 pr_debug("%s: fw-%s buf=%p data=%p size=%u\n", 822 /* fall back on userspace loading */
765 __func__, buf->fw_id, buf, buf->data, 823 buf->is_paged_buf = true;
766 (unsigned int)buf->size);
767}
768 824
769#ifdef CONFIG_PM_SLEEP 825 dev_set_uevent_suppress(f_dev, true);
770static void fw_name_devm_release(struct device *dev, void *res)
771{
772 struct fw_name_devm *fwn = res;
773 826
774 if (fwn->magic == (unsigned long)&fw_cache) 827 /* Need to pin this module until class device is destroyed */
775 pr_debug("%s: fw_name-%s devm-%p released\n", 828 __module_get(THIS_MODULE);
776 __func__, fwn->name, res);
777}
778 829
779static int fw_devm_match(struct device *dev, void *res, 830 retval = device_add(f_dev);
780 void *match_data) 831 if (retval) {
781{ 832 dev_err(f_dev, "%s: device_register failed\n", __func__);
782 struct fw_name_devm *fwn = res; 833 goto err_put_dev;
834 }
783 835
784 return (fwn->magic == (unsigned long)&fw_cache) && 836 retval = device_create_bin_file(f_dev, &firmware_attr_data);
785 !strcmp(fwn->name, match_data); 837 if (retval) {
786} 838 dev_err(f_dev, "%s: sysfs_create_bin_file failed\n", __func__);
839 goto err_del_dev;
840 }
787 841
788static struct fw_name_devm *fw_find_devm_name(struct device *dev, 842 retval = device_create_file(f_dev, &dev_attr_loading);
789 const char *name) 843 if (retval) {
790{ 844 dev_err(f_dev, "%s: device_create_file failed\n", __func__);
791 struct fw_name_devm *fwn; 845 goto err_del_bin_attr;
846 }
792 847
793 fwn = devres_find(dev, fw_name_devm_release, 848 if (uevent) {
794 fw_devm_match, (void *)name); 849 dev_set_uevent_suppress(f_dev, false);
795 return fwn; 850 dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id);
796} 851 if (timeout != MAX_SCHEDULE_TIMEOUT)
852 schedule_delayed_work(&fw_priv->timeout_work, timeout);
797 853
798/* add firmware name into devres list */ 854 kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
799static int fw_add_devm_name(struct device *dev, const char *name) 855 }
800{
801 struct fw_name_devm *fwn;
802 856
803 fwn = fw_find_devm_name(dev, name); 857 wait_for_completion(&buf->completion);
804 if (fwn)
805 return 1;
806 858
807 fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm) + 859 cancel_delayed_work_sync(&fw_priv->timeout_work);
808 strlen(name) + 1, GFP_KERNEL);
809 if (!fwn)
810 return -ENOMEM;
811 860
812 fwn->magic = (unsigned long)&fw_cache; 861 fw_priv->buf = NULL;
813 strcpy(fwn->name, name);
814 devres_add(dev, fwn);
815 862
816 return 0; 863 device_remove_file(f_dev, &dev_attr_loading);
864err_del_bin_attr:
865 device_remove_bin_file(f_dev, &firmware_attr_data);
866err_del_dev:
867 device_del(f_dev);
868err_put_dev:
869 put_device(f_dev);
870 return retval;
817} 871}
818#else 872
819static int fw_add_devm_name(struct device *dev, const char *name) 873static int fw_load_from_user_helper(struct firmware *firmware,
874 const char *name, struct device *device,
875 bool uevent, bool nowait, long timeout)
820{ 876{
821 return 0; 877 struct firmware_priv *fw_priv;
878
879 fw_priv = fw_create_instance(firmware, name, device, uevent, nowait);
880 if (IS_ERR(fw_priv))
881 return PTR_ERR(fw_priv);
882
883 fw_priv->buf = firmware->priv;
884 return _request_firmware_load(fw_priv, uevent, timeout);
822} 885}
823#endif 886#else /* CONFIG_FW_LOADER_USER_HELPER */
887static inline int
888fw_load_from_user_helper(struct firmware *firmware, const char *name,
889 struct device *device, bool uevent, bool nowait,
890 long timeout)
891{
892 return -ENOENT;
893}
894#endif /* CONFIG_FW_LOADER_USER_HELPER */
895
824 896
825/* wait until the shared firmware_buf becomes ready (or error) */ 897/* wait until the shared firmware_buf becomes ready (or error) */
826static int sync_cached_firmware_buf(struct firmware_buf *buf) 898static int sync_cached_firmware_buf(struct firmware_buf *buf)
@@ -921,89 +993,6 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device)
921 return 0; 993 return 0;
922} 994}
923 995
924#ifdef CONFIG_FW_LOADER_USER_HELPER
925/* load a firmware via user helper */
926static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
927 long timeout)
928{
929 int retval = 0;
930 struct device *f_dev = &fw_priv->dev;
931 struct firmware_buf *buf = fw_priv->buf;
932
933 /* fall back on userspace loading */
934 buf->fmt = PAGE_BUF;
935
936 dev_set_uevent_suppress(f_dev, true);
937
938 /* Need to pin this module until class device is destroyed */
939 __module_get(THIS_MODULE);
940
941 retval = device_add(f_dev);
942 if (retval) {
943 dev_err(f_dev, "%s: device_register failed\n", __func__);
944 goto err_put_dev;
945 }
946
947 retval = device_create_bin_file(f_dev, &firmware_attr_data);
948 if (retval) {
949 dev_err(f_dev, "%s: sysfs_create_bin_file failed\n", __func__);
950 goto err_del_dev;
951 }
952
953 retval = device_create_file(f_dev, &dev_attr_loading);
954 if (retval) {
955 dev_err(f_dev, "%s: device_create_file failed\n", __func__);
956 goto err_del_bin_attr;
957 }
958
959 if (uevent) {
960 dev_set_uevent_suppress(f_dev, false);
961 dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id);
962 if (timeout != MAX_SCHEDULE_TIMEOUT)
963 schedule_delayed_work(&fw_priv->timeout_work, timeout);
964
965 kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
966 }
967
968 wait_for_completion(&buf->completion);
969
970 cancel_delayed_work_sync(&fw_priv->timeout_work);
971
972 fw_priv->buf = NULL;
973
974 device_remove_file(f_dev, &dev_attr_loading);
975err_del_bin_attr:
976 device_remove_bin_file(f_dev, &firmware_attr_data);
977err_del_dev:
978 device_del(f_dev);
979err_put_dev:
980 put_device(f_dev);
981 return retval;
982}
983
984static int fw_load_from_user_helper(struct firmware *firmware,
985 const char *name, struct device *device,
986 bool uevent, bool nowait, long timeout)
987{
988 struct firmware_priv *fw_priv;
989
990 fw_priv = fw_create_instance(firmware, name, device, uevent, nowait);
991 if (IS_ERR(fw_priv))
992 return PTR_ERR(fw_priv);
993
994 fw_priv->buf = firmware->priv;
995 return _request_firmware_load(fw_priv, uevent, timeout);
996}
997#else /* CONFIG_FW_LOADER_USER_HELPER */
998static inline int
999fw_load_from_user_helper(struct firmware *firmware, const char *name,
1000 struct device *device, bool uevent, bool nowait,
1001 long timeout)
1002{
1003 return -ENOENT;
1004}
1005#endif /* CONFIG_FW_LOADER_USER_HELPER */
1006
1007/* called from request_firmware() and request_firmware_work_func() */ 996/* called from request_firmware() and request_firmware_work_func() */
1008static int 997static int
1009_request_firmware(const struct firmware **firmware_p, const char *name, 998_request_firmware(const struct firmware **firmware_p, const char *name,