aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-03-29 11:57:20 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-21 12:37:30 -0400
commite9045f9178f3e3445a3a5b85206f8681b3869562 (patch)
tree90de949ea1585ebd42112121570a00a2ea3c5708
parent1704f47b50b5d9e1b825e43e1baaf2c5897baf03 (diff)
firmware class: export nowait to userspace
When we use request_firmware_nowait(), userspace may not want to answer negatively right away when for example it is answering from an initrd only, but with request_firmware() it has to in order to not delay the kernel boot until the request times out. This allows userspace to differentiate between the two in order to be able to reply negatively to async requests only when all filesystems have been mounted and have been checked for the requested firmware file. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/base/firmware_class.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 8e6c62b4f512..d45d1e1c40a4 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -50,6 +50,7 @@ struct firmware_priv {
50 int page_array_size; 50 int page_array_size;
51 const char *vdata; 51 const char *vdata;
52 struct timer_list timeout; 52 struct timer_list timeout;
53 bool nowait;
53}; 54};
54 55
55#ifdef CONFIG_FW_LOADER 56#ifdef CONFIG_FW_LOADER
@@ -112,6 +113,8 @@ static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
112 return -ENOMEM; 113 return -ENOMEM;
113 if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout)) 114 if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout))
114 return -ENOMEM; 115 return -ENOMEM;
116 if (add_uevent_var(env, "ASYNC=%d", fw_priv->nowait))
117 return -ENOMEM;
115 118
116 return 0; 119 return 0;
117} 120}
@@ -441,7 +444,7 @@ error_kfree:
441 444
442static int fw_setup_device(struct firmware *fw, struct device **dev_p, 445static int fw_setup_device(struct firmware *fw, struct device **dev_p,
443 const char *fw_name, struct device *device, 446 const char *fw_name, struct device *device,
444 int uevent) 447 int uevent, bool nowait)
445{ 448{
446 struct device *f_dev; 449 struct device *f_dev;
447 struct firmware_priv *fw_priv; 450 struct firmware_priv *fw_priv;
@@ -457,6 +460,8 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
457 460
458 fw_priv = dev_get_drvdata(f_dev); 461 fw_priv = dev_get_drvdata(f_dev);
459 462
463 fw_priv->nowait = nowait;
464
460 fw_priv->fw = fw; 465 fw_priv->fw = fw;
461 sysfs_bin_attr_init(&fw_priv->attr_data); 466 sysfs_bin_attr_init(&fw_priv->attr_data);
462 retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data); 467 retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
@@ -484,7 +489,7 @@ out:
484 489
485static int 490static int
486_request_firmware(const struct firmware **firmware_p, const char *name, 491_request_firmware(const struct firmware **firmware_p, const char *name,
487 struct device *device, int uevent) 492 struct device *device, int uevent, bool nowait)
488{ 493{
489 struct device *f_dev; 494 struct device *f_dev;
490 struct firmware_priv *fw_priv; 495 struct firmware_priv *fw_priv;
@@ -516,7 +521,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
516 if (uevent) 521 if (uevent)
517 dev_dbg(device, "firmware: requesting %s\n", name); 522 dev_dbg(device, "firmware: requesting %s\n", name);
518 523
519 retval = fw_setup_device(firmware, &f_dev, name, device, uevent); 524 retval = fw_setup_device(firmware, &f_dev, name, device,
525 uevent, nowait);
520 if (retval) 526 if (retval)
521 goto error_kfree_fw; 527 goto error_kfree_fw;
522 528
@@ -573,7 +579,7 @@ request_firmware(const struct firmware **firmware_p, const char *name,
573 struct device *device) 579 struct device *device)
574{ 580{
575 int uevent = 1; 581 int uevent = 1;
576 return _request_firmware(firmware_p, name, device, uevent); 582 return _request_firmware(firmware_p, name, device, uevent, false);
577} 583}
578 584
579/** 585/**
@@ -619,7 +625,7 @@ request_firmware_work_func(void *arg)
619 return 0; 625 return 0;
620 } 626 }
621 ret = _request_firmware(&fw, fw_work->name, fw_work->device, 627 ret = _request_firmware(&fw, fw_work->name, fw_work->device,
622 fw_work->uevent); 628 fw_work->uevent, true);
623 629
624 fw_work->cont(fw, fw_work->context); 630 fw_work->cont(fw, fw_work->context);
625 631