From patchwork Thu Feb 23 18:30:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 9588789 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C23D060578 for ; Thu, 23 Feb 2017 18:37:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B4C4828448 for ; Thu, 23 Feb 2017 18:37:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A6CF328475; Thu, 23 Feb 2017 18:37:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 390DE1FFB7 for ; Thu, 23 Feb 2017 18:37:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751289AbdBWShD (ORCPT ); Thu, 23 Feb 2017 13:37:03 -0500 Received: from mail-lf0-f66.google.com ([209.85.215.66]:32971 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750828AbdBWShB (ORCPT ); Thu, 23 Feb 2017 13:37:01 -0500 Received: by mail-lf0-f66.google.com with SMTP id j2so1724471lfe.0; Thu, 23 Feb 2017 10:37:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=j0RKkKGeQdNNkJTGv0JL2CN8HHtI35plYJOy15mlGhc=; b=JkE7b9BuLFtIcjUxgmx8jSrsjbjay8pfQrS/Cd5He0AvzIC4wk6kSmXSilnicQtwkp /G1MHT/vwo5yUaFvdBGvYKQAccWHIQUhPOFYJve8YpHtMWxjZyHYvj7cg/G3iTYO2Fmu iDskhmGNbvF6/B2iY5WDDUFpc8lwT+XPfMKCtaACO2cVl9DozxcxPoPGLzlxIsCuHvo0 MnHbHzAWDY4fm9BxcX9u5K6zPDe59WlFucLqYkQPocQeMWFlQ/FKKvs6ikD6GlMrZdw8 e4Yg3dD9t+/9Gx2XXNLsAwACVH9QyIUw+xwA1XO+Ly5LW6TL8ELwT/Yi0CJkwg5LoOSP uq2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=j0RKkKGeQdNNkJTGv0JL2CN8HHtI35plYJOy15mlGhc=; b=XHjPyGt8Us0jT2egG43Qpy6F6iNDpKTMvrd96qWW+PRwH2gMiE/To+/cXQpPNO2lUH FMRNhGwbjCoSIGbVvUuJoWViB0Wsdtho5X3O+S95n0w2ZFj+RkvJKYz5CkzExxA5mIHL hpFoskaJzPUR+p5DI4Zk20eWc4ENbvubWZa1vmqwabkH7OgSKdbrG81m+GUHc9Bu2BrQ w1x7FQzpv7p0W7ojyqNGPxgnpbAJWbpauwcDmJ+kbakdAaHUy1JGDbwo6og1AlckDjQn XPrUxqBHVqG6nnzH1Awzgfmgl2aJ0nZav2HAo4pASXvXNX5WO5IQqR9NPV8kkMkn2HGX wQgQ== X-Gm-Message-State: AMke39keV7dmf78IaHnSneUYWPpQAuOUXHxciDmL7PB8Z3GmaAml9G+FZJqvCE36EHVUvQ== X-Received: by 10.46.69.137 with SMTP id s131mr10293162lja.71.1487874627307; Thu, 23 Feb 2017 10:30:27 -0800 (PST) Received: from linux-samsung.lan (ip-194-187-74-233.konfederacka.maverick.com.pl. [194.187.74.233]) by smtp.gmail.com with ESMTPSA id 25sm8110499lju.56.2017.02.23.10.30.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 23 Feb 2017 10:30:26 -0800 (PST) From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= To: Ming Lei , "Luis R . Rodriguez" , Greg KH , Linux Kernel Mailing List Cc: Kalle Valo , Arend van Spriel , linux-wireless@vger.kernel.org, brcm80211-dev-list.pdl@broadcom.com, =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Subject: [PATCH V4 1/2] firmware: add more flexible request_firmware_async function Date: Thu, 23 Feb 2017 19:30:17 +0100 Message-Id: <20170223183018.16704-1-zajec5@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170221094754.15406-1-zajec5@gmail.com> References: <20170221094754.15406-1-zajec5@gmail.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Rafał Miłecki So far we got only one function for loading firmware asynchronously: request_firmware_nowait. It didn't allow much customization of firmware loading process - there is only one bool uevent argument. Moreover this bool also controls user helper in an unclear way. Resolve this problem by adding one internally shared function that allows specifying any flags manually. This implementation: 1) Allows keeping old request_firmware_nowait API unchanged 2) Doesn't require adjusting / rewriting current drivers 3) Minimizes risk of regressions 4) Adds new function for drivers that need more control over loading a firmware. The new function takes options struct pointer as an argument to make further improvements possible (without any big reworks). Signed-off-by: Rafał Miłecki --- V3: Don't expose all FW_OPT_* flags. As Luis noted we want a struct so add struct firmware_opts for real flexibility. Thank you Luis for your review! Ming/Luis/Greg: assuming this gets a positive review, could someone of you pick this patchset? --- drivers/base/firmware_class.c | 43 ++++++++++++++++++++++++++++++++++--------- include/linux/firmware.h | 15 ++++++++++++++- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index d05be1732c8b..b67b294eb31a 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -1356,7 +1356,7 @@ static void request_firmware_work_func(struct work_struct *work) _request_firmware(&fw, fw_work->name, fw_work->device, NULL, 0, fw_work->opt_flags); fw_work->cont(fw, fw_work->context); - put_device(fw_work->device); /* taken in request_firmware_nowait() */ + put_device(fw_work->device); /* taken in __request_firmware_nowait() */ module_put(fw_work->module); kfree_const(fw_work->name); @@ -1364,10 +1364,9 @@ static void request_firmware_work_func(struct work_struct *work) } /** - * request_firmware_nowait - asynchronous version of request_firmware + * __request_firmware_nowait - asynchronous version of request_firmware * @module: module requesting the firmware - * @uevent: sends uevent to copy the firmware image if this flag - * is non-zero else the firmware copy must be done manually. + * @opt_flags: flags that control firmware loading process, see FW_OPT_* * @name: name of firmware file * @device: device for which firmware is being loaded * @gfp: allocation flags @@ -1386,9 +1385,9 @@ static void request_firmware_work_func(struct work_struct *work) * * - can't sleep at all if @gfp is GFP_ATOMIC. **/ -int -request_firmware_nowait( - struct module *module, bool uevent, +static int +__request_firmware_nowait( + struct module *module, unsigned int opt_flags, const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)) { @@ -1407,8 +1406,7 @@ request_firmware_nowait( fw_work->device = device; fw_work->context = context; fw_work->cont = cont; - fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK | - (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER); + fw_work->opt_flags = FW_OPT_NOWAIT | opt_flags; if (!try_module_get(module)) { kfree_const(fw_work->name); @@ -1421,8 +1419,35 @@ request_firmware_nowait( schedule_work(&fw_work->work); return 0; } + +int request_firmware_nowait(struct module *module, bool uevent, + const char *name, struct device *device, gfp_t gfp, + void *context, + void (*cont)(const struct firmware *fw, void *context)) +{ + unsigned int opt_flags = FW_OPT_FALLBACK | + (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER); + + return __request_firmware_nowait(module, opt_flags, name, device, gfp, + context, cont); +} EXPORT_SYMBOL(request_firmware_nowait); +int __request_firmware_async(struct module *module, const char *name, + struct firmware_opts *fw_opts, struct device *dev, + void *context, + void (*cont)(const struct firmware *fw, void *context)) +{ + unsigned int opt_flags = FW_OPT_UEVENT; + + if (fw_opts->optional) + opt_flags |= FW_OPT_NO_WARN; + + return __request_firmware_nowait(module, opt_flags, name, dev, + GFP_KERNEL, context, cont); +} +EXPORT_SYMBOL(__request_firmware_async); + #ifdef CONFIG_PM_SLEEP static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain); diff --git a/include/linux/firmware.h b/include/linux/firmware.h index b1f9f0ccb8ac..a32b6e67462d 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -82,6 +82,19 @@ static inline int request_firmware_into_buf(const struct firmware **firmware_p, { return -EINVAL; } - #endif + +struct firmware_opts { + bool optional; +}; + +int __request_firmware_async(struct module *module, const char *name, + struct firmware_opts *fw_opts, struct device *dev, + void *context, + void (*cont)(const struct firmware *fw, void *context)); + +#define request_firmware_async(name, fw_opts, dev, context, cont) \ + __request_firmware_async(THIS_MODULE, name, fw_opts, dev, \ + context, cont) + #endif