public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "takahiro.akashi@linaro.org" <takahiro.akashi@linaro.org>
To: "Coelho, Luciano" <luciano.coelho@intel.com>
Cc: "gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>,
	"mcgrof@kernel.org" <mcgrof@kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"pjones@redhat.com" <pjones@redhat.com>,
	"moritz.fischer@ettus.com" <moritz.fischer@ettus.com>,
	"dhowells@redhat.com" <dhowells@redhat.com>,
	"pmladek@suse.com" <pmladek@suse.com>,
	"Berg, Johannes" <johannes.berg@intel.com>,
	"rjw@rjwysocki.net" <rjw@rjwysocki.net>,
	"yi1.li@linux.intel.com" <yi1.li@linux.intel.com>,
	"kvalo@codeaurora.org" <kvalo@codeaurora.org>,
	"luto@kernel.org" <luto@kernel.org>,
	"arend.vanspriel@broadcom.com" <arend.vanspriel@broadcom.com>,
	"rafal@milecki.pl" <rafal@milecki.pl>,
	"dwmw2@infradead.org" <dwmw2@infradead.org>,
	"wagi@monom.org" <wagi@monom.org>,
	"atull@opensource.altera.com" <atull@opensource.altera.com>,
	"Grumbach, Emmanuel" <emmanuel.grumbach@intel.com>
Subject: Re: [PATCH v6 2/5] firmware: add extensible driver data API
Date: Tue, 11 Apr 2017 17:01:51 +0900	[thread overview]
Message-ID: <20170411080149.GD15139@linaro.org> (raw)
In-Reply-To: <1491828162.31980.50.camel@intel.com>

On Mon, Apr 10, 2017 at 12:42:44PM +0000, Coelho, Luciano wrote:
> On Wed, 2017-03-29 at 20:25 -0700, Luis R. Rodriguez wrote:
> > The firmware API does not scale well: when new features are added we
> > either add a new exported symbol or extend the arguments of existing
> > routines. For the later case this means we need to traverse the kernel
> > with a slew of collateral evolutions to adjust old driver users. The
> > firmware API is also now being used for things outside of the scope of
> > what typically would be considered "firmware". There are other
> > subsystems which would like to make use of the firmware APIs for similar
> > things and its clearly not firmware, but have different requirements
> > and criteria which they'd like to be met for the requested file.
> > 
> > An extensible API is in order:
> > 
> > The driver data API accepts that there are only two types of requests:
> > 
> > a) synchronous requests
> > b) asynchronous requests
> > 
> > Both requests may have a different requirements which must be met. These
> > requirements can be described in the struct driver_data_req_params.
> > This struct is expected to be extended over time to support different
> > requirements as the kernel evolves.
> > 
> > After a bit of hard work the new interface has been wrapped onto the
> > functionality. The fallback mechanism has been kept out of the new API
> > currently because it requires just a bit more grooming and documentation
> > given new considerations and requirements.  Adding support for it will
> > be rather easy now that the new API sits ontop of the old one. The
> > request_firmware_into_buf() API also is not enabled on the new API but
> > it is rather easy to do so -- this call has no current existing users
> > upstream though. Support will be provided once we add a respective
> > series of test cases against it and find a proper upstream user for it.
> > 
> > The flexible API also adds a few new bells and whistles:
> > 
> > - By default the kernel will free the driver data file for you after
> >   your callbacks are called, you however are allowed to request that
> >   you wish to keep the driver data file on the requirements params. The
> >   new driver data API is able to free the driver data file for you by
> >   requiring a consumer callback for the driver data file.
> > - Allows both asynchronous and synchronous request to specify that
> >   driver data files are optional. With the old APIs we had added one
> >   full API call, request_firmware_direct() just for this purpose --
> >   the driver data request APIs allow for you to annotate that a driver
> >   data file is optional for both synchronous or asynchronous requests
> >   through the same two basic set of APIs.
> > - A firmware API framework is provided to enable daisy chaining a
> >   series of requests for firmware on a range of supported APIs.
> > 
> > Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> > ---
> >  Documentation/driver-api/firmware/driver_data.rst  |  77 +++++
> >  Documentation/driver-api/firmware/index.rst        |   1 +
> >  Documentation/driver-api/firmware/introduction.rst |  16 +
> >  MAINTAINERS                                        |   3 +-
> >  drivers/base/firmware_class.c                      | 357 +++++++++++++++++++++
> >  include/linux/driver_data.h                        | 202 +++++++++++-
> >  include/linux/firmware.h                           |   2 +
> >  7 files changed, 656 insertions(+), 2 deletions(-)
> >  create mode 100644 Documentation/driver-api/firmware/driver_data.rst
> > 
> > diff --git a/Documentation/driver-api/firmware/driver_data.rst b/Documentation/driver-api/firmware/driver_data.rst
> > new file mode 100644
> > index 000000000000..08407b7568fe
> > --- /dev/null
> > +++ b/Documentation/driver-api/firmware/driver_data.rst
> > @@ -0,0 +1,77 @@
> > +===============
> > +driver_data API
> > +===============
> > +
> > +Users of firmware request APIs has grown to include users which are not
> 
> Grammar.  Maybe "The usage of firmware..."

Or, Users of ... have grown in number, including ...
> 
> > +looking for "firmware", but instead general driver data files which have
> > +been kept oustide of the kernel. The driver data APIs addresses rebranding
> > +of firmware as generic driver data files, and provides a flexible API which
> > +mitigates collateral evolutions on the kernel as new functionality is
> > +introduced.
> 
> This looks more like a commit message than an introduction to the
> feature.  In the future, we won't care why this was introduced, but  we
> want to know what it is and how it can be used.
> 
> 
> > +
> > +Driver data modes of operation
> > +==============================
> > +
> > +There are only two types of modes of operation for driver data requests:
> 
> "only" seems irrelevant here.
> 
> 
> > +
> > +  * synchronous  - driver_data_request()
> > +  * asynchronous - driver_data_request_async()
> > +
> > +Synchronous requests expect requests to be done immediately, asynchronous
> > +requests enable requests to be scheduled for a later time.
> > +
> > +Driver data request parameters
> > +==============================
> > +
> > +Variations of types of driver data requests are specified by a driver data
> > +request parameter data structure. This data structure is expected to grow as
> > +new requirements grow.
> 
> Again, not sure it's relevant to know that it can grow.  For
> documentation purposes, the important is the *now*.

There seem to be a couple of new features/parameters.
Why not list them now:
  * optional
  * keep
  * API versioning

I will add 'data(firmware) signing' here afterward.

> 
> > +
> > +Reference counting and releasing the driver data file
> > +=====================================================
> > +
> > +As with the old firmware API both the device and module are bumped with
> > +reference counts during the driver data requests. This prevents removal
> > +of the device and module making the driver data request call until the
> > +driver data request callbacks have completed, either synchronously or
> > +asynchronously.
> > +
> > +The old firmware APIs refcounted the firmware_class module for synchronous
> > +requests, meanwhile asynchronous requests refcounted the caller's module.
> > +The driver data request API currently mimics this behaviour, for synchronous
> > +requests the firmware_class module is refcounted through the use of
> > +dfl_sync_reqs. In the future we may enable the ability to also refcount the
> > +caller's module as well. Likewise in the future we may enable asynchronous
> > +calls to refcount the firmware_class module.
> 
> Ditto.  Maybe you could move all the "future" references to the
> "Tracking development enhancements and ideas" section?
> 
> [...]
> 
> > diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
> > index f702566554e1..cc3c2247980c 100644
> > --- a/drivers/base/firmware_class.c
> > +++ b/drivers/base/firmware_class.c
> 
> [...]
> 
> > @@ -1460,6 +1471,128 @@ void release_firmware(const struct firmware *fw)
> >  }
> >  EXPORT_SYMBOL(release_firmware);
> >  
> > +static int _driver_data_request_api(struct driver_data_params *params,
> > +				    struct device *device,
> > +				    const char *name)
> > +{
> > +	struct driver_data_priv_params *priv_params = &params->priv_params;
> > +	const struct driver_data_req_params *req_params = &params->req_params;
> > +	int ret;
> > +	char *try_name;
> > +	u8 api_max;
> > +
> > +	if (priv_params->retry_api) {
> > +		if (!priv_params->api)
> > +			return -ENOENT;
> > +		api_max = priv_params->api - 1;
> > +	} else
> > +		api_max = req_params->api_max;
> 
> Braces.
> 
> 
> > +	for (priv_params->api = api_max;
> > +	     priv_params->api >= req_params->api_min;
> > +	     priv_params->api--) {
> > +		if (req_params->api_name_postfix)
> > +			try_name = kasprintf(GFP_KERNEL, "%s%d%s",
> > +					     name,
> > +					     priv_params->api,
> > +					     req_params->api_name_postfix);
> > +		else
> > +			try_name = kasprintf(GFP_KERNEL, "%s%d",
> > +					     name,
> > +					     priv_params->api);
> > +		if (!try_name)
> > +			return -ENOMEM;
> > +		ret = _request_firmware(&params->driver_data, try_name,
> > +					params, device);
> > +		kfree(try_name);
> > +
> > +		if (!ret)
> > +			break;
> > +
> > +		release_firmware(params->driver_data);
> > +
> > +		/*
> > +		 * Only chug on with the API revision hunt if the file we
> > +		 * looked for really was not present. In case of memory issues
> > +		 * or other related system issues we want to bail right away
> > +		 * to not put strain on the system.
> > +		 */
> > +		if (ret != -ENOENT)
> > +			break;
> > +
> > +		if (!priv_params->api)
> > +			break;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +/**
> > + * driver_data_request - synchronous request for a driver data file

driver_data_request_sync

> > + * @name: name of the driver data file
> > + * @params: driver data parameters, it provides all the requirements

req_params

> > + *	parameters which must be met for the file being requested.
> > + * @device: device for which firmware is being loaded
> > + *
> > + * This performs a synchronous driver data lookup with the requirements
> > + * specified on @params, if the file was found meeting the criteria requested
> > + * 0 is returned. Access to the driver data data can be accessed through
> > + * an optional callback set on the @desc.
> 
> Huh? This last sentence seems wrong, I don't even see a @desc anywhere.
> 
> 
> >  If the driver data is optional
> > + * you must specify that on @params and if set you may provide an alternative
> > + * callback which if set would be run if the driver data was not found.
> > + *
> > + * The driver data passed to the callbacks will be NULL unless it was
> > + * found matching all the criteria on @params. 0 is always returned if the file
> > + * was found unless a callback was provided, in which case the callback's
> > + * return value will be passed. Unless the params->keep was set the kernel will
> > + * release the driver data for you after your callbacks were processed.
> > + *
> > + * Reference counting is used during the duration of this call on both the
> > + * device and module that made the request. This prevents any callers from
> > + * freeing either the device or module prior to completion of this call.
> > + */
> > +int driver_data_request_sync(const char *name,
> > +			     const struct driver_data_req_params *req_params,
> > +			     struct device *device)
> > +{
> > +	const struct firmware *driver_data;
> > +	const struct driver_data_reqs *sync_reqs;
> > +	struct driver_data_params params = {
> > +		.req_params = *req_params,
> > +	};
> > +	int ret;
> > +
> > +	if (!device || !req_params || !name || name[0] == '\0')
> > +		return -EINVAL;
> > +
> > +	if (req_params->sync_reqs.mode != DRIVER_DATA_SYNC)
> > +		return -EINVAL;
> 
> Why do you need to check this here? If the caller is calling _sync(),
> it's because that's what it needs.  This mode value here seems
> redundant.
> 
> OTOH, if you do have a reason for this value, then you could use
> driver_data_request_sync() in this if.

I think two functions, driver_data_request_[a]sync(), can be
unified into one:
int driver_data_request(const char *name,
		        const struct driver_data_req_params *req_params,
		        struct device *device)

Thanks,
-Takahiro AKASHI

> 
> > +/**
> > + * driver_data_request_async - asynchronous request for a driver data file
> > + * @name: name of the driver data file
> > + * @req_params: driver data file request parameters, it provides all the
> > + *	requirements which must be met for the file being requested.
> > + * @device: device for which firmware is being loaded
> > + *
> > + * This performs an asynchronous driver data file lookup with the requirements
> > + * specified on @req_params. The request for the actual driver data file lookup
> > + * will be scheduled with schedule_work() to be run at a later time. 0 is
> > + * returned if we were able to asynchronously schedlue your work to be run.
> > + *
> > + * Reference counting is used during the duration of this scheduled call on
> > + * both the device and module that made the request. This prevents any callers
> > + * from freeing either the device or module prior to completion of the
> > + * scheduled work.
> > + *
> > + * Access to the driver data file data can be accessed through an optional
> > + * callback set on the @req_params. If the driver data file is optional you
> > + * must specify that on @req_params and if set you may provide an alternative
> > + * callback which if set would be run if the driver data file was not found.
> > + *
> > + * The driver data file passed to the callbacks will always be NULL unless it
> > + * was found matching all the criteria on @req_params. Unless the desc->keep
> > + * was set the kernel will release the driver data file for you after your
> > + * callbacks were processed on the scheduled work.
> > + */
> > +int driver_data_request_async(const char *name,
> > +			      const struct driver_data_req_params *req_params,
> > +			      struct device *device)
> > +{
> > +	struct firmware_work *driver_work;
> > +	const struct driver_data_reqs *sync_reqs;
> > +	struct firmware_work driver_work_stack = {
> > +		.data_params.req_params = *req_params,
> > +		//.device = device,
> > +		//.name = name,
> > +	};
> > +
> > +	if (!device || !req_params || !name || name[0] == '\0')
> > +		return -EINVAL;
> > +
> > +	if (req_params->sync_reqs.mode != DRIVER_DATA_ASYNC)
> > +		return -EINVAL;
> 
> Same here.
> 
> --
> Luca.

  reply	other threads:[~2017-04-11  7:58 UTC|newest]

Thread overview: 98+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-30  3:25 [PATCH v6 0/5] firmware: add driver data API Luis R. Rodriguez
2017-03-30  3:25 ` [PATCH v6 1/5] firmware: add extensible driver data params Luis R. Rodriguez
2017-04-06  7:26   ` Luca Coelho
2017-04-27  2:05     ` Luis R. Rodriguez
2017-03-30  3:25 ` [PATCH v6 2/5] firmware: add extensible driver data API Luis R. Rodriguez
2017-04-10 12:42   ` Coelho, Luciano
2017-04-11  8:01     ` takahiro.akashi [this message]
2017-04-27  3:23       ` Luis R. Rodriguez
2017-04-27  3:16     ` Luis R. Rodriguez
2017-04-27  5:44       ` Luca Coelho
2017-04-27  8:04         ` Luis R. Rodriguez
2017-04-27  6:09       ` Luca Coelho
2017-04-27 10:31         ` Luis R. Rodriguez
2017-04-13  9:36   ` AKASHI Takahiro
2017-04-28  0:51     ` Luis R. Rodriguez
2017-04-28  3:19       ` AKASHI Takahiro
2017-04-29  4:36         ` Luis R. Rodriguez
2017-03-30  3:25 ` [PATCH v6 3/5] test: add new driver_data load tester Luis R. Rodriguez
2017-04-11  8:32   ` AKASHI Takahiro
2017-04-28  1:45     ` Luis R. Rodriguez
2017-05-11 10:46       ` AKASHI Takahiro
2017-05-11 17:11         ` Luis R. Rodriguez
2017-05-17 22:45           ` Li, Yi
2017-05-19 18:31             ` Luis R. Rodriguez
2017-05-11 18:12         ` Luis R. Rodriguez
2017-05-11 18:26         ` Luis R. Rodriguez
2017-05-11 18:32           ` Luis R. Rodriguez
2017-05-12  0:28             ` AKASHI Takahiro
2017-05-12 15:59               ` Luis R. Rodriguez
2017-05-17  9:08                 ` AKASHI Takahiro
2017-05-17 15:38                   ` Luis R. Rodriguez
2017-05-12  0:20           ` AKASHI Takahiro
2017-05-12 15:52             ` Luis R. Rodriguez
2017-05-13 18:46               ` Luis R. Rodriguez
2017-03-30  3:25 ` [PATCH v6 4/5] iwlwifi: convert to use driver data API Luis R. Rodriguez
2017-04-10 13:19   ` Luca Coelho
2017-04-28  0:56     ` Luis R. Rodriguez
2017-04-28 12:17       ` Luca Coelho
2017-03-30  3:25 ` [PATCH v6 5/5] brcmfmac: don't warn user if requested nvram fails Luis R. Rodriguez
2017-04-27  0:49   ` Luis R. Rodriguez
2017-05-02  8:49 ` [PATCH v7 0/5] firmware: add driver data API Luis R. Rodriguez
2017-05-02  8:49   ` [PATCH v7 1/5] firmware: add extensible driver data params Luis R. Rodriguez
2017-05-11 18:17     ` Li, Yi
2017-05-11 18:28       ` Luis R. Rodriguez
2017-05-02  8:49   ` [PATCH v7 2/5] firmware: add extensible driver data API Luis R. Rodriguez
2017-05-02  8:49   ` [PATCH v7 3/5] test: add new driver_data load tester Luis R. Rodriguez
2017-05-11 10:10     ` AKASHI Takahiro
2017-05-11 17:00       ` Luis R. Rodriguez
2017-05-15 18:23     ` [PATCH v8] " Luis R. Rodriguez
2017-05-02  8:49   ` [PATCH v7 4/5] firmware: document the extensible driver data API Luis R. Rodriguez
2017-05-02  8:49   ` [PATCH v7 5/5] iwlwifi: convert to use " Luis R. Rodriguez
2017-05-19 19:10   ` [PATCH v8 0/5] firmware: add " Luis R. Rodriguez
2017-05-19 19:10     ` [PATCH v8 1/5] firmware: add extensible driver data params Luis R. Rodriguez
2017-05-19 19:10     ` [PATCH v8 2/5] firmware: add extensible driver data API Luis R. Rodriguez
2017-05-19 19:10     ` [PATCH v8 3/5] test: add new driver_data load tester Luis R. Rodriguez
2017-05-19 19:10     ` [PATCH v8 4/5] firmware: document the extensible driver data API Luis R. Rodriguez
2017-05-19 19:10     ` [PATCH v8 5/5] iwlwifi: convert to use " Luis R. Rodriguez
2017-06-05 21:33     ` [PATCH v8 0/5] firmware: add " Luis R. Rodriguez
2017-06-05 21:39       ` [PATCH v9 " Luis R. Rodriguez
2017-06-05 21:39         ` [PATCH v9 1/5] firmware: add extensible driver data params Luis R. Rodriguez
2017-06-13  9:05           ` Greg KH
2017-06-13 10:31             ` Rafał Miłecki
2017-06-13 13:17               ` Greg KH
2017-06-13 14:12                 ` Rafał Miłecki
2017-06-13 15:32                 ` Luis R. Rodriguez
2017-06-13 15:50                   ` Greg KH
2017-06-13 19:40             ` Luis R. Rodriguez
2017-06-14 15:57               ` Li, Yi
2017-06-17 19:38               ` Greg KH
2017-06-19  7:33                 ` Johannes Berg
2017-06-19 19:41                   ` Luis R. Rodriguez
2017-06-20  1:26                     ` AKASHI Takahiro
2017-06-19 19:35                 ` Luis R. Rodriguez
2017-06-23 15:51                   ` Greg KH
2017-06-23 22:43                     ` Luis R. Rodriguez
2017-06-23 23:09                       ` Linus Torvalds
2017-06-24  0:48                         ` Luis R. Rodriguez
2017-06-24 12:39                           ` Greg KH
2017-06-26 17:33                             ` Luis R. Rodriguez
2017-06-26 18:19                               ` Rafał Miłecki
2017-06-26 21:29                                 ` Luis R. Rodriguez
2017-06-27  2:28                               ` Vikram Mulukutla
2017-06-27 17:25                                 ` Luis R. Rodriguez
2017-06-24 12:40                       ` Greg KH
2017-06-26 15:50                         ` Luis R. Rodriguez
2017-06-23 15:59                   ` Greg KH
2017-06-23 22:47                     ` Luis R. Rodriguez
2017-06-19 22:51                 ` Li, Yi
2017-06-20  1:48                   ` AKASHI Takahiro
2017-06-20 15:20                     ` Li, Yi
2017-06-20 16:27                 ` Vikram Mulukutla
2017-06-20 17:22                   ` Luis R. Rodriguez
2017-06-21  0:49                     ` AKASHI Takahiro
2017-06-23 16:33                       ` Luis R. Rodriguez
2017-06-05 21:39         ` [PATCH v9 2/5] firmware: add extensible driver data API Luis R. Rodriguez
2017-06-05 21:39         ` [PATCH v9 3/5] test: add new driver_data load tester Luis R. Rodriguez
2017-06-05 21:39         ` [PATCH v9 4/5] firmware: document the extensible driver data API Luis R. Rodriguez
2017-06-05 21:39         ` [PATCH v9 5/5] iwlwifi: convert to use " Luis R. Rodriguez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170411080149.GD15139@linaro.org \
    --to=takahiro.akashi@linaro.org \
    --cc=arend.vanspriel@broadcom.com \
    --cc=atull@opensource.altera.com \
    --cc=dhowells@redhat.com \
    --cc=dwmw2@infradead.org \
    --cc=emmanuel.grumbach@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=johannes.berg@intel.com \
    --cc=kvalo@codeaurora.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luciano.coelho@intel.com \
    --cc=luto@kernel.org \
    --cc=mcgrof@kernel.org \
    --cc=moritz.fischer@ettus.com \
    --cc=pjones@redhat.com \
    --cc=pmladek@suse.com \
    --cc=rafal@milecki.pl \
    --cc=rjw@rjwysocki.net \
    --cc=wagi@monom.org \
    --cc=yi1.li@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox