Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754994AbcJEU1z (ORCPT ); Wed, 5 Oct 2016 16:27:55 -0400 Received: from mx2.suse.de ([195.135.220.15]:48651 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751569AbcJEU1x (ORCPT ); Wed, 5 Oct 2016 16:27:53 -0400 Date: Wed, 5 Oct 2016 22:27:50 +0200 From: "Luis R. Rodriguez" To: Daniel Wagner Cc: "Luis R . Rodriguez" , Daniel Wagner , linux-kernel@vger.kernel.org, Ming Lei , Greg Kroah-Hartman , "Srivatsa S . Bhat" , "Rafael J . Wysocki" , Daniel Vetter , Takashi Iwai , Bjorn Andersson , Arend van Spriel Subject: Re: [PATCH v5 2/5] firmware: encapsulate firmware loading status Message-ID: <20161005202750.GF3296@wotan.suse.de> References: <1473423144-21734-1-git-send-email-wagi@monom.org> <1473423144-21734-3-git-send-email-wagi@monom.org> <3484559b-bc77-d056-0775-481233d51fc0@bmw-carit.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <3484559b-bc77-d056-0775-481233d51fc0@bmw-carit.de> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3737 Lines: 135 On Tue, Sep 13, 2016 at 11:47:08AM +0200, Daniel Wagner wrote: > Hi Luis, > > > On 09/09/2016 02:12 PM, Daniel Wagner wrote: > >The firmware user helper code tracks the current state of the loading > >process via unsigned long status and a complection in struct > >firmware_buf. We only need this for the usermode helper as such we can > >encapsulate all this data into its own data structure. > > I don't think we are able to move the completion code into a > CONFIG_FW_LOADER_HELPER section. The direct loading path uses > completion as well. Where? > >+#ifdef CONFIG_FW_LOADER_USER_HELPER > >+ > >+enum { > >+ FW_UMH_UNKNOWN, > >+ FW_UMH_LOADING, > >+ FW_UMH_DONE, > >+ FW_UMH_ABORTED, > >+}; > > The direct loading path just uses two states, LOADING and DONE. > ABORTED is not used. > > >+struct fw_umh { > >+ struct completion completion; > >+ unsigned long status; > >+}; > >+ > >+static void fw_umh_init(struct fw_umh *fw_umh) > >+{ > >+ init_completion(&fw_umh->completion); > >+ fw_umh->status = FW_UMH_UNKNOWN; > >+} > >+ > >+static int __fw_umh_check(struct fw_umh *fw_umh, unsigned long status) > >+{ > >+ return test_bit(status, &fw_umh->status); > >+} > >+ > >+static int fw_umh_wait_timeout(struct fw_umh *fw_umh, long timeout) > >+{ > >+ int ret; > >+ > >+ ret = wait_for_completion_interruptible_timeout(&fw_umh->completion, > >+ timeout); > >+ if (ret != 0 && test_bit(FW_UMH_ABORTED, &fw_umh->status)) > >+ return -ENOENT; > >+ > >+ return ret; > >+} > >+ > >+static void __fw_umh_set(struct fw_umh *fw_umh, > >+ unsigned long status) > >+{ > >+ set_bit(status, &fw_umh->status); > >+ > >+ if (status == FW_UMH_DONE || status == FW_UMH_ABORTED) { > >+ clear_bit(FW_UMH_LOADING, &fw_umh->status); > >+ complete_all(&fw_umh->completion); > >+ } > >+} > >+ > >+#define fw_umh_start(fw_umh) \ > >+ __fw_umh_set(fw_umh, FW_UMH_LOADING) > >+#define fw_umh_done(fw_umh) \ > >+ __fw_umh_set(fw_umh, FW_UMH_DONE) > >+#define fw_umh_aborted(fw_umh) \ > >+ __fw_umh_set(fw_umh, FW_UMH_ABORTED) > >+#define fw_umh_is_loading(fw_umh) \ > >+ __fw_umh_check(fw_umh, FW_UMH_LOADING) > >+#define fw_umh_is_done(fw_umh) \ > >+ __fw_umh_check(fw_umh, FW_UMH_DONE) > >+#define fw_umh_is_aborted(fw_umh) \ > >+ __fw_umh_check(fw_umh, FW_UMH_ABORTED) > >+ > >+#else /* CONFIG_FW_LOADER_USER_HELPER */ > >+ > >+#define fw_umh_wait_timeout(fw_st, long) 0 > >+ > >+#define fw_umh_done(fw_st) > >+#define fw_umh_is_done(fw_st) true > >+#define fw_umh_is_aborted(fw_st) false > > We still need the implementation for fw_umh_wait_timeout() and > fw_umh_start(), fw_umh_done() etc. Why? > fw_umh_is_aborted() is not > needed. > > > >@@ -309,8 +373,7 @@ static void fw_finish_direct_load(struct device *device, > > struct firmware_buf *buf) > > { > > mutex_lock(&fw_lock); > >- set_bit(FW_STATUS_DONE, &buf->status); > >- complete_all(&buf->completion); > >+ fw_umh_done(&buf->fw_umh); > > mutex_unlock(&fw_lock); > > } > > Here we signal that we have loaded the firmware The struct firmware_buf is only used for the sysfs stuff no? > > /* wait until the shared firmware_buf becomes ready (or error) */ > > static int sync_cached_firmware_buf(struct firmware_buf *buf) > > { > > int ret = 0; > > > > mutex_lock(&fw_lock); > >- while (!test_bit(FW_STATUS_DONE, &buf->status)) { > >- if (is_fw_load_aborted(buf)) { > >+ while (!fw_umh_is_done(&buf->fw_umh)) { > >+ if (fw_umh_is_aborted(&buf->fw_umh)) { > > ret = -ENOENT; > > break; > > } > > mutex_unlock(&fw_lock); > >- ret = wait_for_completion_interruptible(&buf->completion); > >+ ret = fw_umh_wait_timeout(&buf->fw_umh, 0); > > mutex_lock(&fw_lock); > > } > > and here we here we wait for it. Likewise. Luis