aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-10-29 07:36:02 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:24:52 -0500
commit9ebfbd45f9d4ee9cd72529cf99e5f300eb398e67 (patch)
tree6ad661c4b38d0fad8a88c4a0d28997e9303632f2 /drivers
parent03d673e6af6490371aaf64dfe1f84c658c48b71d (diff)
firmware_class: make request_firmware_nowait more useful
Unfortunately, one cannot hold on to the struct firmware that request_firmware_nowait() hands off, which is needed in some cases. Allow this by requiring the callback to free it (via release_firmware). Additionally, give it a gfp_t parameter -- all the current users call it from a GFP_KERNEL context so the GFP_ATOMIC isn't necessary. This also marks an API break which is useful in a sense, although that is obviously not the primary purpose of this change. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Marcel Holtmann <marcel@holtmann.org> Cc: Ming Lei <tom.leiming@gmail.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: David Woodhouse <David.Woodhouse@intel.com> Cc: Pavel Roskin <proski@gnu.org> Cc: Abhay Salunke <abhay_salunke@dell.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/firmware_class.c14
-rw-r--r--drivers/firmware/dell_rbu.c9
-rw-r--r--drivers/serial/ucc_uart.c8
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c5
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c5
-rw-r--r--drivers/usb/atm/ueagle-atm.c7
6 files changed, 30 insertions, 18 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 7376367bcb80..a95024166b66 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -601,12 +601,9 @@ request_firmware_work_func(void *arg)
601 } 601 }
602 ret = _request_firmware(&fw, fw_work->name, fw_work->device, 602 ret = _request_firmware(&fw, fw_work->name, fw_work->device,
603 fw_work->uevent); 603 fw_work->uevent);
604 if (ret < 0) 604
605 fw_work->cont(NULL, fw_work->context); 605 fw_work->cont(fw, fw_work->context);
606 else { 606
607 fw_work->cont(fw, fw_work->context);
608 release_firmware(fw);
609 }
610 module_put(fw_work->module); 607 module_put(fw_work->module);
611 kfree(fw_work); 608 kfree(fw_work);
612 return ret; 609 return ret;
@@ -619,6 +616,7 @@ request_firmware_work_func(void *arg)
619 * is non-zero else the firmware copy must be done manually. 616 * is non-zero else the firmware copy must be done manually.
620 * @name: name of firmware file 617 * @name: name of firmware file
621 * @device: device for which firmware is being loaded 618 * @device: device for which firmware is being loaded
619 * @gfp: allocation flags
622 * @context: will be passed over to @cont, and 620 * @context: will be passed over to @cont, and
623 * @fw may be %NULL if firmware request fails. 621 * @fw may be %NULL if firmware request fails.
624 * @cont: function will be called asynchronously when the firmware 622 * @cont: function will be called asynchronously when the firmware
@@ -631,12 +629,12 @@ request_firmware_work_func(void *arg)
631int 629int
632request_firmware_nowait( 630request_firmware_nowait(
633 struct module *module, int uevent, 631 struct module *module, int uevent,
634 const char *name, struct device *device, void *context, 632 const char *name, struct device *device, gfp_t gfp, void *context,
635 void (*cont)(const struct firmware *fw, void *context)) 633 void (*cont)(const struct firmware *fw, void *context))
636{ 634{
637 struct task_struct *task; 635 struct task_struct *task;
638 struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), 636 struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
639 GFP_ATOMIC); 637 gfp);
640 638
641 if (!fw_work) 639 if (!fw_work)
642 return -ENOMEM; 640 return -ENOMEM;
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index b4704e150b28..b3a0cf57442e 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -544,9 +544,12 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
544{ 544{
545 rbu_data.entry_created = 0; 545 rbu_data.entry_created = 0;
546 546
547 if (!fw || !fw->size) 547 if (!fw)
548 return; 548 return;
549 549
550 if (!fw->size)
551 goto out;
552
550 spin_lock(&rbu_data.lock); 553 spin_lock(&rbu_data.lock);
551 if (!strcmp(image_type, "mono")) { 554 if (!strcmp(image_type, "mono")) {
552 if (!img_update_realloc(fw->size)) 555 if (!img_update_realloc(fw->size))
@@ -568,6 +571,8 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
568 } else 571 } else
569 pr_debug("invalid image type specified.\n"); 572 pr_debug("invalid image type specified.\n");
570 spin_unlock(&rbu_data.lock); 573 spin_unlock(&rbu_data.lock);
574 out:
575 release_firmware(fw);
571} 576}
572 577
573static ssize_t read_rbu_image_type(struct kobject *kobj, 578static ssize_t read_rbu_image_type(struct kobject *kobj,
@@ -615,7 +620,7 @@ static ssize_t write_rbu_image_type(struct kobject *kobj,
615 spin_unlock(&rbu_data.lock); 620 spin_unlock(&rbu_data.lock);
616 req_firm_rc = request_firmware_nowait(THIS_MODULE, 621 req_firm_rc = request_firmware_nowait(THIS_MODULE,
617 FW_ACTION_NOHOTPLUG, "dell_rbu", 622 FW_ACTION_NOHOTPLUG, "dell_rbu",
618 &rbu_device->dev, &context, 623 &rbu_device->dev, GFP_KERNEL, &context,
619 callbackfn_rbu); 624 callbackfn_rbu);
620 if (req_firm_rc) { 625 if (req_firm_rc) {
621 printk(KERN_ERR 626 printk(KERN_ERR
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index 46de564aaea0..465f2fae1025 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -1179,16 +1179,18 @@ static void uart_firmware_cont(const struct firmware *fw, void *context)
1179 1179
1180 if (firmware->header.length != fw->size) { 1180 if (firmware->header.length != fw->size) {
1181 dev_err(dev, "invalid firmware\n"); 1181 dev_err(dev, "invalid firmware\n");
1182 return; 1182 goto out;
1183 } 1183 }
1184 1184
1185 ret = qe_upload_firmware(firmware); 1185 ret = qe_upload_firmware(firmware);
1186 if (ret) { 1186 if (ret) {
1187 dev_err(dev, "could not load firmware\n"); 1187 dev_err(dev, "could not load firmware\n");
1188 return; 1188 goto out;
1189 } 1189 }
1190 1190
1191 firmware_loaded = 1; 1191 firmware_loaded = 1;
1192 out:
1193 release_firmware(fw);
1192} 1194}
1193 1195
1194static int ucc_uart_probe(struct of_device *ofdev, 1196static int ucc_uart_probe(struct of_device *ofdev,
@@ -1247,7 +1249,7 @@ static int ucc_uart_probe(struct of_device *ofdev,
1247 */ 1249 */
1248 ret = request_firmware_nowait(THIS_MODULE, 1250 ret = request_firmware_nowait(THIS_MODULE,
1249 FW_ACTION_HOTPLUG, filename, &ofdev->dev, 1251 FW_ACTION_HOTPLUG, filename, &ofdev->dev,
1250 &ofdev->dev, uart_firmware_cont); 1252 GFP_KERNEL, &ofdev->dev, uart_firmware_cont);
1251 if (ret) { 1253 if (ret) {
1252 dev_err(&ofdev->dev, 1254 dev_err(&ofdev->dev,
1253 "could not load firmware %s\n", 1255 "could not load firmware %s\n",
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index cca4e869f0ec..dfcd12bec86b 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -2327,9 +2327,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
2327 if (ret) { 2327 if (ret) {
2328 dev_err(&usbdev->dev, 2328 dev_err(&usbdev->dev,
2329 "Could not upload firmware (err=%d)\n", ret); 2329 "Could not upload firmware (err=%d)\n", ret);
2330 return; 2330 goto out;
2331 } 2331 }
2332 comedi_usb_auto_config(usbdev, BOARDNAME); 2332 comedi_usb_auto_config(usbdev, BOARDNAME);
2333 out:
2334 release_firmware(fw);
2333} 2335}
2334 2336
2335/* allocate memory for the urbs and initialise them */ 2337/* allocate memory for the urbs and initialise them */
@@ -2580,6 +2582,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
2580 FW_ACTION_HOTPLUG, 2582 FW_ACTION_HOTPLUG,
2581 "usbdux_firmware.bin", 2583 "usbdux_firmware.bin",
2582 &udev->dev, 2584 &udev->dev,
2585 GFP_KERNEL,
2583 usbduxsub + index, 2586 usbduxsub + index,
2584 usbdux_firmware_request_complete_handler); 2587 usbdux_firmware_request_complete_handler);
2585 2588
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index d143222579c2..2e675cce7dbf 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -1451,10 +1451,12 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware
1451 if (ret) { 1451 if (ret) {
1452 dev_err(&usbdev->dev, 1452 dev_err(&usbdev->dev,
1453 "Could not upload firmware (err=%d)\n", ret); 1453 "Could not upload firmware (err=%d)\n", ret);
1454 return; 1454 goto out;
1455 } 1455 }
1456 1456
1457 comedi_usb_auto_config(usbdev, BOARDNAME); 1457 comedi_usb_auto_config(usbdev, BOARDNAME);
1458 out:
1459 release_firmware(fw);
1458} 1460}
1459 1461
1460/* 1462/*
@@ -1569,6 +1571,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
1569 FW_ACTION_HOTPLUG, 1571 FW_ACTION_HOTPLUG,
1570 "usbduxfast_firmware.bin", 1572 "usbduxfast_firmware.bin",
1571 &udev->dev, 1573 &udev->dev,
1574 GFP_KERNEL,
1572 usbduxfastsub + index, 1575 usbduxfastsub + index,
1573 usbduxfast_firmware_request_complete_handler); 1576 usbduxfast_firmware_request_complete_handler);
1574 1577
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index bba4d3eabe0f..c5395246886d 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -667,12 +667,12 @@ static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *conte
667 else 667 else
668 uea_info(usb, "firmware uploaded\n"); 668 uea_info(usb, "firmware uploaded\n");
669 669
670 uea_leaves(usb); 670 goto err;
671 return;
672 671
673err_fw_corrupted: 672err_fw_corrupted:
674 uea_err(usb, "firmware is corrupted\n"); 673 uea_err(usb, "firmware is corrupted\n");
675err: 674err:
675 release_firmware(fw_entry);
676 uea_leaves(usb); 676 uea_leaves(usb);
677} 677}
678 678
@@ -705,7 +705,8 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
705 break; 705 break;
706 } 706 }
707 707
708 ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); 708 ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
709 GFP_KERNEL, usb, uea_upload_pre_firmware);
709 if (ret) 710 if (ret)
710 uea_err(usb, "firmware %s is not available\n", fw_name); 711 uea_err(usb, "firmware %s is not available\n", fw_name);
711 else 712 else