Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751422AbdFEVkO (ORCPT ); Mon, 5 Jun 2017 17:40:14 -0400 Received: from mail.kernel.org ([198.145.29.99]:34286 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751268AbdFEVjp (ORCPT ); Mon, 5 Jun 2017 17:39:45 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4538E23A36 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=mcgrof@kernel.org From: "Luis R. Rodriguez" To: gregkh@linuxfoundation.org Cc: wagi@monom.org, dwmw2@infradead.org, rafal@milecki.pl, arend.vanspriel@broadcom.com, rjw@rjwysocki.net, yi1.li@linux.intel.com, atull@opensource.altera.com, moritz.fischer@ettus.com, pmladek@suse.com, johannes.berg@intel.com, emmanuel.grumbach@intel.com, luciano.coelho@intel.com, kvalo@codeaurora.org, luto@kernel.org, torvalds@linux-foundation.org, keescook@chromium.org, takahiro.akashi@linaro.org, dhowells@redhat.com, pjones@redhat.com, hdegoede@redhat.com, alan@linux.intel.com, tytso@mit.edu, linux-kernel@vger.kernel.org, "Luis R. Rodriguez" Subject: [PATCH v9 5/5] iwlwifi: convert to use driver data API Date: Mon, 5 Jun 2017 14:39:37 -0700 Message-Id: <20170605213937.26215-6-mcgrof@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170605213937.26215-1-mcgrof@kernel.org> References: <20170605213314.GR8951@wotan.suse.de> <20170605213937.26215-1-mcgrof@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5565 Lines: 178 The driver data API provides support for looking for firmware from a specific set of API ranges, so just use that. Since we free the firmware on the callback immediately after consuming it, this also takes avantage of that feature. Signed-off-by: Luis R. Rodriguez --- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 91 ++++++++++------------------ 1 file changed, 31 insertions(+), 60 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 5cfacb0bca84..028854d31f55 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -66,7 +66,7 @@ *****************************************************************************/ #include #include -#include +#include #include #include @@ -206,58 +206,34 @@ static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, return 0; } -static void iwl_req_fw_callback(const struct firmware *ucode_raw, - void *context); +static int iwl_req_fw_callback(const struct firmware *ucode_raw, void *context, + int unused_error); -static int iwl_request_firmware(struct iwl_drv *drv, bool first) +static const char *iwl_get_fw_name_pre(struct iwl_drv *drv) { - const struct iwl_cfg *cfg = drv->trans->cfg; - char tag[8]; const char *fw_pre_name; if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000 && CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_B_STEP) - fw_pre_name = cfg->fw_name_pre_next_step; + fw_pre_name = drv->trans->cfg->fw_name_pre_next_step; else - fw_pre_name = cfg->fw_name_pre; - - if (first) { - drv->fw_index = cfg->ucode_api_max; - sprintf(tag, "%d", drv->fw_index); - } else { - drv->fw_index--; - sprintf(tag, "%d", drv->fw_index); - } - - if (drv->fw_index < cfg->ucode_api_min) { - IWL_ERR(drv, "no suitable firmware found!\n"); - - if (cfg->ucode_api_min == cfg->ucode_api_max) { - IWL_ERR(drv, "%s%d is required\n", fw_pre_name, - cfg->ucode_api_max); - } else { - IWL_ERR(drv, "minimum version required: %s%d\n", - fw_pre_name, - cfg->ucode_api_min); - IWL_ERR(drv, "maximum version supported: %s%d\n", - fw_pre_name, - cfg->ucode_api_max); - } - - IWL_ERR(drv, - "check git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git\n"); - return -ENOENT; - } + fw_pre_name = drv->trans->cfg->fw_name_pre; - snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode", - fw_pre_name, tag); - - IWL_DEBUG_INFO(drv, "attempting to load firmware '%s'\n", - drv->firmware_name); + return fw_pre_name; +} - return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, - drv->trans->dev, - GFP_KERNEL, drv, iwl_req_fw_callback); +static int iwl_request_firmware(struct iwl_drv *drv) +{ + const char *name_pre = iwl_get_fw_name_pre(drv); + const struct iwl_cfg *cfg = drv->trans->cfg; + const struct driver_data_req_params req_params = { + DRIVER_DATA_API_CB(iwl_req_fw_callback, drv), + DRIVER_DATA_API(cfg->ucode_api_min, cfg->ucode_api_max, ".ucode"), + }; + + return driver_data_request_async(name_pre, + &req_params, + drv->trans->dev); } struct fw_img_parsing { @@ -1259,7 +1235,8 @@ static void _iwl_op_mode_stop(struct iwl_drv *drv) * If loaded successfully, copies the firmware into buffers * for the card to fetch (via DMA). */ -static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) +static int iwl_req_fw_callback(const struct firmware *ucode_raw, void *context, + int unused_error) { struct iwl_drv *drv = context; struct iwl_fw *fw = &drv->fw; @@ -1282,10 +1259,12 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) pieces = kzalloc(sizeof(*pieces), GFP_KERNEL); if (!pieces) - goto out_free_fw; + return -ENOMEM; - if (!ucode_raw) - goto try_again; + if (!ucode_raw) { + err = -ENOENT; + goto free; + } IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", drv->firmware_name, ucode_raw->size); @@ -1448,9 +1427,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) fw->ucode_capa.standard_phy_calibration_size = IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; - /* We have our copies now, allow OS release its copies */ - release_firmware(ucode_raw); - mutex_lock(&iwlwifi_opmode_table_mtx); switch (fw->type) { case IWL_FW_DVM: @@ -1505,15 +1481,11 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) goto free; try_again: - /* try next, if any */ - release_firmware(ucode_raw); - if (iwl_request_firmware(drv, false)) - goto out_unbind; + err = -EAGAIN; goto free; out_free_fw: iwl_dealloc_ucode(drv); - release_firmware(ucode_raw); out_unbind: complete(&drv->request_firmware_complete); device_release_driver(drv->trans->dev); @@ -1524,6 +1496,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) kfree(pieces->dbg_mem_tlv); kfree(pieces); } + return err; } struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) @@ -1564,11 +1537,9 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) } #endif - ret = iwl_request_firmware(drv, true); - if (ret) { - IWL_ERR(trans, "Couldn't request the fw\n"); + ret = iwl_request_firmware(drv); + if (ret) goto err_fw; - } return drv; -- 2.11.0