aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-03-28 17:29:55 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-03-28 17:29:55 -0400
commit811fa4004485dec8977176bf605a5b0508ee206c (patch)
treeafa0924a75f217a27f7438e34758747413ba635a /drivers/base
parentfe2e39d8782d885755139304d8dba0b3e5bfa878 (diff)
firmware_class: Split _request_firmware() into three functions, v2
Split _request_firmware() into three functions, _request_firmware_prepare() doing preparatory work that need not be done under umhelper_sem, _request_firmware_cleanup() doing the post-error cleanup and _request_firmware() carrying out the remaining operations. This change is requisite for moving the acquisition of umhelper_sem from _request_firmware() to the callers, which is going to be done subsequently. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/firmware_class.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index deee871e509c..60290671f04a 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -435,7 +435,7 @@ static void firmware_class_timeout(u_long data)
435} 435}
436 436
437static struct firmware_priv * 437static struct firmware_priv *
438fw_create_instance(struct firmware *firmware, const char *fw_name, 438fw_create_instance(const struct firmware *firmware, const char *fw_name,
439 struct device *device, bool uevent, bool nowait) 439 struct device *device, bool uevent, bool nowait)
440{ 440{
441 struct firmware_priv *fw_priv; 441 struct firmware_priv *fw_priv;
@@ -449,7 +449,7 @@ fw_create_instance(struct firmware *firmware, const char *fw_name,
449 goto err_out; 449 goto err_out;
450 } 450 }
451 451
452 fw_priv->fw = firmware; 452 fw_priv->fw = (struct firmware *)firmware;
453 fw_priv->nowait = nowait; 453 fw_priv->nowait = nowait;
454 strcpy(fw_priv->fw_id, fw_name); 454 strcpy(fw_priv->fw_id, fw_name);
455 init_completion(&fw_priv->completion); 455 init_completion(&fw_priv->completion);
@@ -510,13 +510,10 @@ static void fw_destroy_instance(struct firmware_priv *fw_priv)
510 device_unregister(f_dev); 510 device_unregister(f_dev);
511} 511}
512 512
513static int _request_firmware(const struct firmware **firmware_p, 513static int _request_firmware_prepare(const struct firmware **firmware_p,
514 const char *name, struct device *device, 514 const char *name, struct device *device)
515 bool uevent, bool nowait)
516{ 515{
517 struct firmware_priv *fw_priv;
518 struct firmware *firmware; 516 struct firmware *firmware;
519 int retval = 0;
520 517
521 if (!firmware_p) 518 if (!firmware_p)
522 return -EINVAL; 519 return -EINVAL;
@@ -533,10 +530,26 @@ static int _request_firmware(const struct firmware **firmware_p,
533 return 0; 530 return 0;
534 } 531 }
535 532
533 return 1;
534}
535
536static void _request_firmware_cleanup(const struct firmware **firmware_p)
537{
538 release_firmware(*firmware_p);
539 *firmware_p = NULL;
540}
541
542static int _request_firmware(const struct firmware *firmware,
543 const char *name, struct device *device,
544 bool uevent, bool nowait)
545{
546 struct firmware_priv *fw_priv;
547 int retval;
548
536 retval = usermodehelper_read_trylock(); 549 retval = usermodehelper_read_trylock();
537 if (WARN_ON(retval)) { 550 if (WARN_ON(retval)) {
538 dev_err(device, "firmware: %s will not be loaded\n", name); 551 dev_err(device, "firmware: %s will not be loaded\n", name);
539 goto out_nolock; 552 return retval;
540 } 553 }
541 554
542 if (uevent) 555 if (uevent)
@@ -572,13 +585,6 @@ static int _request_firmware(const struct firmware **firmware_p,
572 585
573out: 586out:
574 usermodehelper_read_unlock(); 587 usermodehelper_read_unlock();
575
576out_nolock:
577 if (retval) {
578 release_firmware(firmware);
579 *firmware_p = NULL;
580 }
581
582 return retval; 588 return retval;
583} 589}
584 590
@@ -601,7 +607,17 @@ int
601request_firmware(const struct firmware **firmware_p, const char *name, 607request_firmware(const struct firmware **firmware_p, const char *name,
602 struct device *device) 608 struct device *device)
603{ 609{
604 return _request_firmware(firmware_p, name, device, true, false); 610 int ret;
611
612 ret = _request_firmware_prepare(firmware_p, name, device);
613 if (ret <= 0)
614 return ret;
615
616 ret = _request_firmware(*firmware_p, name, device, true, false);
617 if (ret)
618 _request_firmware_cleanup(firmware_p);
619
620 return ret;
605} 621}
606 622
607/** 623/**
@@ -639,8 +655,16 @@ static int request_firmware_work_func(void *arg)
639 return 0; 655 return 0;
640 } 656 }
641 657
642 ret = _request_firmware(&fw, fw_work->name, fw_work->device, 658 ret = _request_firmware_prepare(&fw, fw_work->name, fw_work->device);
659 if (ret <= 0)
660 goto out;
661
662 ret = _request_firmware(fw, fw_work->name, fw_work->device,
643 fw_work->uevent, true); 663 fw_work->uevent, true);
664 if (ret)
665 _request_firmware_cleanup(&fw);
666
667 out:
644 fw_work->cont(fw, fw_work->context); 668 fw_work->cont(fw, fw_work->context);
645 669
646 module_put(fw_work->module); 670 module_put(fw_work->module);