aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_class.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 21:34:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 21:34:04 -0400
commit29b88e23a9212136d39b0161a39afe587d0170a5 (patch)
tree48d9f857b137222e35f853004973e12a515314f5 /drivers/base/firmware_class.c
parent2521129a6d2fd8a81f99cf95055eddea3df914ff (diff)
parent4e3a25b0274b8474f5ad46215a270785dd18265e (diff)
Merge tag 'driver-core-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH: "Here's the big driver-core pull request for 3.17-rc1. Largest thing in here is the dma-buf rework and fence code, that touched many different subsystems so it was agreed it should go through this tree to handle merge issues. There's also some firmware loading updates, as well as tests added, and a few other tiny changes, the changelog has the details. All have been in linux-next for a long time" * tag 'driver-core-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (32 commits) ARM: imx: Remove references to platform_bus in mxc code firmware loader: Fix _request_firmware_load() return val for fw load abort platform: Remove most references to platform_bus device test: add firmware_class loader test doc: fix minor typos in firmware_class README staging: android: Cleanup style issues Documentation: devres: Sort managed interfaces Documentation: devres: Add devm_kmalloc() et al fs: debugfs: remove trailing whitespace kernfs: kernel-doc warning fix debugfs: Fix corrupted loop in debugfs_remove_recursive stable_kernel_rules: Add pointer to netdev-FAQ for network patches driver core: platform: add device binding path 'driver_override' driver core/platform: remove unused implicit padding in platform_object firmware loader: inform direct failure when udev loader is disabled firmware: replace ALIGN(PAGE_SIZE) by PAGE_ALIGN firmware: read firmware size using i_size_read() firmware loader: allow disabling of udev as firmware loader reservation: add suppport for read-only access using rcu reservation: update api and add some helpers ... Conflicts: drivers/base/platform.c
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r--drivers/base/firmware_class.c47
1 files changed, 22 insertions, 25 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index d276e33880be..da77791793f1 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -100,10 +100,16 @@ static inline long firmware_loading_timeout(void)
100#define FW_OPT_UEVENT (1U << 0) 100#define FW_OPT_UEVENT (1U << 0)
101#define FW_OPT_NOWAIT (1U << 1) 101#define FW_OPT_NOWAIT (1U << 1)
102#ifdef CONFIG_FW_LOADER_USER_HELPER 102#ifdef CONFIG_FW_LOADER_USER_HELPER
103#define FW_OPT_FALLBACK (1U << 2) 103#define FW_OPT_USERHELPER (1U << 2)
104#else 104#else
105#define FW_OPT_FALLBACK 0 105#define FW_OPT_USERHELPER 0
106#endif 106#endif
107#ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK
108#define FW_OPT_FALLBACK FW_OPT_USERHELPER
109#else
110#define FW_OPT_FALLBACK 0
111#endif
112#define FW_OPT_NO_WARN (1U << 3)
107 113
108struct firmware_cache { 114struct firmware_cache {
109 /* firmware_buf instance will be added into the below list */ 115 /* firmware_buf instance will be added into the below list */
@@ -279,26 +285,15 @@ static const char * const fw_path[] = {
279module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); 285module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
280MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); 286MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path");
281 287
282/* Don't inline this: 'struct kstat' is biggish */
283static noinline_for_stack int fw_file_size(struct file *file)
284{
285 struct kstat st;
286 if (vfs_getattr(&file->f_path, &st))
287 return -1;
288 if (!S_ISREG(st.mode))
289 return -1;
290 if (st.size != (int)st.size)
291 return -1;
292 return st.size;
293}
294
295static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) 288static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
296{ 289{
297 int size; 290 int size;
298 char *buf; 291 char *buf;
299 int rc; 292 int rc;
300 293
301 size = fw_file_size(file); 294 if (!S_ISREG(file_inode(file)->i_mode))
295 return -EINVAL;
296 size = i_size_read(file_inode(file));
302 if (size <= 0) 297 if (size <= 0)
303 return -EINVAL; 298 return -EINVAL;
304 buf = vmalloc(size); 299 buf = vmalloc(size);
@@ -718,7 +713,7 @@ out:
718static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) 713static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
719{ 714{
720 struct firmware_buf *buf = fw_priv->buf; 715 struct firmware_buf *buf = fw_priv->buf;
721 int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT; 716 int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT;
722 717
723 /* If the array of pages is too small, grow it... */ 718 /* If the array of pages is too small, grow it... */
724 if (buf->page_array_size < pages_needed) { 719 if (buf->page_array_size < pages_needed) {
@@ -911,7 +906,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv,
911 wait_for_completion(&buf->completion); 906 wait_for_completion(&buf->completion);
912 907
913 cancel_delayed_work_sync(&fw_priv->timeout_work); 908 cancel_delayed_work_sync(&fw_priv->timeout_work);
914 if (!buf->data) 909 if (is_fw_load_aborted(buf))
910 retval = -EAGAIN;
911 else if (!buf->data)
915 retval = -ENOMEM; 912 retval = -ENOMEM;
916 913
917 device_remove_file(f_dev, &dev_attr_loading); 914 device_remove_file(f_dev, &dev_attr_loading);
@@ -1111,10 +1108,11 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
1111 1108
1112 ret = fw_get_filesystem_firmware(device, fw->priv); 1109 ret = fw_get_filesystem_firmware(device, fw->priv);
1113 if (ret) { 1110 if (ret) {
1114 if (opt_flags & FW_OPT_FALLBACK) { 1111 if (!(opt_flags & FW_OPT_NO_WARN))
1115 dev_warn(device, 1112 dev_warn(device,
1116 "Direct firmware load failed with error %d\n", 1113 "Direct firmware load for %s failed with error %d\n",
1117 ret); 1114 name, ret);
1115 if (opt_flags & FW_OPT_USERHELPER) {
1118 dev_warn(device, "Falling back to user helper\n"); 1116 dev_warn(device, "Falling back to user helper\n");
1119 ret = fw_load_from_user_helper(fw, name, device, 1117 ret = fw_load_from_user_helper(fw, name, device,
1120 opt_flags, timeout); 1118 opt_flags, timeout);
@@ -1171,7 +1169,6 @@ request_firmware(const struct firmware **firmware_p, const char *name,
1171} 1169}
1172EXPORT_SYMBOL(request_firmware); 1170EXPORT_SYMBOL(request_firmware);
1173 1171
1174#ifdef CONFIG_FW_LOADER_USER_HELPER
1175/** 1172/**
1176 * request_firmware: - load firmware directly without usermode helper 1173 * request_firmware: - load firmware directly without usermode helper
1177 * @firmware_p: pointer to firmware image 1174 * @firmware_p: pointer to firmware image
@@ -1188,12 +1185,12 @@ int request_firmware_direct(const struct firmware **firmware_p,
1188{ 1185{
1189 int ret; 1186 int ret;
1190 __module_get(THIS_MODULE); 1187 __module_get(THIS_MODULE);
1191 ret = _request_firmware(firmware_p, name, device, FW_OPT_UEVENT); 1188 ret = _request_firmware(firmware_p, name, device,
1189 FW_OPT_UEVENT | FW_OPT_NO_WARN);
1192 module_put(THIS_MODULE); 1190 module_put(THIS_MODULE);
1193 return ret; 1191 return ret;
1194} 1192}
1195EXPORT_SYMBOL_GPL(request_firmware_direct); 1193EXPORT_SYMBOL_GPL(request_firmware_direct);
1196#endif
1197 1194
1198/** 1195/**
1199 * release_firmware: - release the resource associated with a firmware image 1196 * release_firmware: - release the resource associated with a firmware image
@@ -1277,7 +1274,7 @@ request_firmware_nowait(
1277 fw_work->context = context; 1274 fw_work->context = context;
1278 fw_work->cont = cont; 1275 fw_work->cont = cont;
1279 fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK | 1276 fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK |
1280 (uevent ? FW_OPT_UEVENT : 0); 1277 (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER);
1281 1278
1282 if (!try_module_get(module)) { 1279 if (!try_module_get(module)) {
1283 kfree(fw_work); 1280 kfree(fw_work);