From patchwork Sat Dec 24 16:52:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 9488081 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 85E9C601D3 for ; Sat, 24 Dec 2016 16:57:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7674920952 for ; Sat, 24 Dec 2016 16:57:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6B2D2212D8; Sat, 24 Dec 2016 16:57:33 +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=ham 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 01B40212DA for ; Sat, 24 Dec 2016 16:57:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755215AbcLXQ50 (ORCPT ); Sat, 24 Dec 2016 11:57:26 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:35861 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753533AbcLXQ5T (ORCPT ); Sat, 24 Dec 2016 11:57:19 -0500 Received: by mail-wm0-f65.google.com with SMTP id m203so46915594wma.3; Sat, 24 Dec 2016 08:54:06 -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=bHmqkd9jW/Ls82KSuZG9wP1ClRCAvh3se2joZDdW1xg=; b=H2pBTL3YuP0TzwQygvKcniFsV0wSVxTerS6dDqQq2Iq2pLmwVEY6NKUW8C/Zb3idSB WXyHic7kEpXKENt/vlM1jNgEVPwugshIZZOmHEwMfZzjv20GM8g+EbMFUfQeSWJX9mpn kigJ53aXmNMj3CwVtIZzAnRsYdvnFWbJrcSf1pvOd2UQu8AUSCOH5R7G1mU3GiBlcguB jL/qHa/vYKHnhBFq5tJ1qy7UjEtYLjmVIlySvDBS4umz4+SOPNK/lGIqbc0WOg25Hd8+ LBaqv0yBwu4FpwENV01VkS4BmOs0Cm1S8my6QowmP49jBkZ9qaO5vDqshAjfjuTnxORX nTag== 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=bHmqkd9jW/Ls82KSuZG9wP1ClRCAvh3se2joZDdW1xg=; b=kmOxqn36mDheQhQnykJAfHIyzh0WzXmgTkaVAAUUBH9K7FhvDdY76k1bG2xcOcLUEA /Nwk0yBZqcU4b1auXIi6m/X4xrHTgfWeqRgq0QJKwtNyh3mT3P9N7oWZrpoDfnsmYCQW Jz6kTNxDi8RWWKMAmzXscgH2o7Wmn20wCCYzRMkbG8VFc4zp84aWrwrl66/ZOtcHrlcB U+92u7oTtvsIYOWaTov2ejNbTZR7hjvSJ5Fj7niEPyIDSoumBtpi+E9Mi13u4zjA3XB2 E9q1kOIv7Itj57MYnoc/VG0b2dvbgsFclTIS8qac82whUijgvld/jXRNmFbm/gHaOW7/ BmMQ== X-Gm-Message-State: AIkVDXLTCb2ij4FBtXOaJA5fyu/UuvQIqHUMgcpKW8bONXtu2+OPjXhDiRohUy9yzWv9ew== X-Received: by 10.28.66.194 with SMTP id k63mr21144785wmi.140.1482598445520; Sat, 24 Dec 2016 08:54:05 -0800 (PST) Received: from localhost.localdomain (ip-88-212-34-237.antik.sk. [88.212.34.237]) by smtp.gmail.com with ESMTPSA id b15sm42736940wma.5.2016.12.24.08.54.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 24 Dec 2016 08:54:04 -0800 (PST) From: =?UTF-8?q?Pali=20Roh=C3=A1r?= To: Ming Lei , "Luis R. Rodriguez" , Greg Kroah-Hartman , Kalle Valo , David Gnedt , Michal Kazior , Daniel Wagner , Tony Lindgren , Sebastian Reichel , Pavel Machek , Ivaylo Dimitrov , Aaro Koskinen , Grazvydas Ignotas Cc: linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org, =?UTF-8?q?Pali=20Roh=C3=A1r?= Subject: [PATCH 1/6] firmware: Add request_firmware_prefer_user() function Date: Sat, 24 Dec 2016 17:52:56 +0100 Message-Id: <1482598381-16513-2-git-send-email-pali.rohar@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1482598381-16513-1-git-send-email-pali.rohar@gmail.com> References: <1482598381-16513-1-git-send-email-pali.rohar@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 This function works pretty much like request_firmware(), but it prefer usermode helper. If usermode helper fails then it fallback to direct access. Useful for dynamic or model specific firmware data. Signed-off-by: Pali Rohár --- drivers/base/firmware_class.c | 45 +++++++++++++++++++++++++++++++++++++++-- include/linux/firmware.h | 9 +++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 22d1760..6a8c261 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -119,6 +119,11 @@ static inline long firmware_loading_timeout(void) #endif #define FW_OPT_NO_WARN (1U << 3) #define FW_OPT_NOCACHE (1U << 4) +#ifdef CONFIG_FW_LOADER_USER_HELPER +#define FW_OPT_PREFER_USER (1U << 5) +#else +#define FW_OPT_PREFER_USER 0 +#endif struct firmware_cache { /* firmware_buf instance will be added into the below list */ @@ -1169,13 +1174,26 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device, } } - ret = fw_get_filesystem_firmware(device, fw->priv); + if (opt_flags & FW_OPT_PREFER_USER) { + ret = fw_load_from_user_helper(fw, name, device, opt_flags, timeout); + if (ret && !(opt_flags & FW_OPT_NO_WARN)) { + dev_warn(device, + "User helper firmware load for %s failed with error %d\n", + name, ret); + dev_warn(device, "Falling back to direct firmware load\n"); + } + } else { + ret = -EINVAL; + } + + if (ret) + ret = fw_get_filesystem_firmware(device, fw->priv); if (ret) { if (!(opt_flags & FW_OPT_NO_WARN)) dev_warn(device, "Direct firmware load for %s failed with error %d\n", name, ret); - if (opt_flags & FW_OPT_USERHELPER) { + if ((opt_flags & FW_OPT_USERHELPER) && !(opt_flags & FW_OPT_PREFER_USER)) { dev_warn(device, "Falling back to user helper\n"); ret = fw_load_from_user_helper(fw, name, device, opt_flags, timeout); @@ -1287,6 +1305,29 @@ int request_firmware_direct(const struct firmware **firmware_p, EXPORT_SYMBOL(request_firmware_into_buf); /** + * request_firmware_prefer_user: - prefer usermode helper for loading firmware + * @firmware_p: pointer to firmware image + * @name: name of firmware file + * @device: device for which firmware is being loaded + * + * This function works pretty much like request_firmware(), but it prefer + * usermode helper. If usermode helper fails then it fallback to direct access. + * Useful for dynamic or model specific firmware data. + **/ +int request_firmware_prefer_user(const struct firmware **firmware_p, + const char *name, struct device *device) +{ + int ret; + + __module_get(THIS_MODULE); + ret = _request_firmware(firmware_p, name, device, NULL, 0, + FW_OPT_UEVENT | FW_OPT_PREFER_USER); + module_put(THIS_MODULE); + return ret; +} +EXPORT_SYMBOL_GPL(request_firmware_prefer_user); + +/** * release_firmware: - release the resource associated with a firmware image * @fw: firmware resource to release **/ diff --git a/include/linux/firmware.h b/include/linux/firmware.h index b1f9f0c..01f7a85 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -47,6 +47,8 @@ int request_firmware_nowait( void (*cont)(const struct firmware *fw, void *context)); int request_firmware_direct(const struct firmware **fw, const char *name, struct device *device); +int request_firmware_prefer_user(const struct firmware **fw, const char *name, + struct device *device); int request_firmware_into_buf(const struct firmware **firmware_p, const char *name, struct device *device, void *buf, size_t size); @@ -77,6 +79,13 @@ static inline int request_firmware_direct(const struct firmware **fw, return -EINVAL; } +static inline int request_firmware_prefer_user(const struct firmware **fw, + const char *name, + struct device *device) +{ + return -EINVAL; +} + static inline int request_firmware_into_buf(const struct firmware **firmware_p, const char *name, struct device *device, void *buf, size_t size) {