All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kent Gibson <warthog618@gmail.com>
To: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Linus Walleij <linus.walleij@linaro.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	linux-gpio@vger.kernel.org
Subject: Re: [libgpiod][RFC v2] core: implement v2.0 API
Date: Thu, 27 May 2021 19:27:05 +0800	[thread overview]
Message-ID: <20210527112705.GA20965@sol> (raw)
In-Reply-To: <20210518191855.12647-1-brgl@bgdev.pl>

On Tue, May 18, 2021 at 09:18:55PM +0200, Bartosz Golaszewski wrote:
> This is the second shot at the v2.0 C API for libgpiod.
> 
> Special thanks go out to Kent for his valuable advice and suggestions.
> 
> The biggest changes are:
> 
> The concept of attributes has been removed - instead the translation from
> configuration options to kernel request happens at the time of the line
> request call and can only fail at this stage - the config mutators no
> longer return any value.
> 
> If the caller has passed a config that is too complicated, the request
> function will set errno to E2BIG which stands for: "Argument list too
> long".
> 
> The direction and edge options have been split from the former
> request_type.
> 
> The objects are no longer reference counted and no longer can be the
> responsibility for their lifetime shared.
> 
> There are many other minor tweaks everywhere.
> 
> One thing I've been contemplating is whether we should expose some
> functions allowing callers to check if the line config has already
> become too complex or values passed are invalid. This would allow
> languages that have exceptions throw them before we actually make the
> request call. Does this make sense?
> 

Wrt passing invalid values, I suggested error-less mutators on the
assumption they wouldn't have parameters that require range checking.
e.g. my Go library has AsInput() and AsOutput(value)
Your equivalents are:
    gpiod_line_config_set_direction(cfg, GPIOD_LINE_CONFIG_DIRECTION_INPUT)
and
    gpiod_line_config_set_direction(cfg, GPIOD_LINE_CONFIG_DIRECTION_OUTPUT)

If you need to perform range checking on the parameters then the mutator
should return an error code.

OTOH, for the active level you provide two error-less mutators,
gpiod_line_config_set_active_low() and
gpiod_line_config_set_active_high(), which is fine.

Wrt exposing complexity validation functions, I don't see the benefit.
The config may transition through complex states, so long as at the time
the gpiod_chip_request_lines() or gpiod_line_request_reconfigure_lines()
is called it isn't too complex and so can be translated to the uAPI.
The check has to be performed as part of those functions either way, and
validating a transitional config doesn't prove anything.

> This time the new API is in one big patch for easier review. This
> changeset doesn't modify the bindings or tests but the tools compile
> and pass all tests.
> 
> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
> ---
>  include/gpiod.h            | 1222 ++++++++++++++++++-----------------
>  lib/Makefile.am            |   13 +-
>  lib/chip.c                 |  216 +++++++
>  lib/core.c                 | 1240 ------------------------------------
>  lib/edge-event.c           |  184 ++++++
>  lib/helpers.c              |  302 ---------
>  lib/info-event.c           |   83 +++
>  lib/internal.c             |   58 ++
>  lib/internal.h             |   28 +
>  lib/line-config.c          |  674 ++++++++++++++++++++
>  lib/line-info.c            |  164 +++++
>  lib/line-request.c         |  192 ++++++
>  lib/misc.c                 |   63 ++
>  lib/request-config.c       |   98 +++
>  tools/gpio-tools-test.bats |   12 +-
>  tools/gpiodetect.c         |   13 +-
>  tools/gpiofind.c           |    3 +-
>  tools/gpioget.c            |   66 +-
>  tools/gpioinfo.c           |   60 +-
>  tools/gpiomon.c            |  133 ++--
>  tools/gpioset.c            |   75 ++-
>  tools/tools-common.c       |    8 +-
>  tools/tools-common.h       |    2 +-
>  23 files changed, 2607 insertions(+), 2302 deletions(-)
>  create mode 100644 lib/chip.c
>  delete mode 100644 lib/core.c
>  create mode 100644 lib/edge-event.c
>  delete mode 100644 lib/helpers.c
>  create mode 100644 lib/info-event.c
>  create mode 100644 lib/internal.c
>  create mode 100644 lib/line-config.c
>  create mode 100644 lib/line-info.c
>  create mode 100644 lib/line-request.c
>  create mode 100644 lib/request-config.c
> 
> diff --git a/include/gpiod.h b/include/gpiod.h
> index a4ce01f..bd4689f 100644
> --- a/include/gpiod.h
> +++ b/include/gpiod.h
> @@ -1,12 +1,12 @@
>  /* SPDX-License-Identifier: LGPL-2.1-or-later */
>  /* SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com> */
> +/* SPDX-FileCopyrightText: 2021 Bartosz Golaszewski <brgl@bgdev.pl> */


I'm only going to look at the header here - I'm assuming the other changes
just follow from the API changes.

<snip>

>  /**
> - * @brief Get the handle to the GPIO line at given offset.
> - * @param chip The GPIO chip object.
> + * @brief Get the current snapshot of information about the line at given
> + *        offset.
> + * @param chip GPIO chip object.
>   * @param offset The offset of the GPIO line.
> - * @return Pointer to the GPIO line handle or NULL if an error occured.
> - */
> -struct gpiod_line *
> -gpiod_chip_get_line(struct gpiod_chip *chip, unsigned int offset);
> -
> -/**
> - * @brief Retrieve a set of lines and store them in a line bulk object.
> - * @param chip The GPIO chip object.
> - * @param offsets Array of offsets of lines to retrieve.
> - * @param num_offsets Number of lines to retrieve.
> - * @return New line bulk object or NULL on error.
> + * @return New GPIO line info object or NULL if an error occurred.
>   */
> -struct gpiod_line_bulk *
> -gpiod_chip_get_lines(struct gpiod_chip *chip, unsigned int *offsets,
> -		     unsigned int num_offsets);
> +struct gpiod_line_info *gpiod_chip_get_line_info(struct gpiod_chip *chip,
> +						 unsigned int offset);
>  

Caller takes ownership of the gpiod_line_info, or are we peeking into
the gpiod_chip internals?  Either way, needs a comment.

<snip>

>  /**
> - * @brief Get the handle to the GPIO chip controlling this line.
> - * @param line The GPIO line object.
> - * @return Pointer to the GPIO chip handle controlling this line.
> + * @brief Get the pointer to the line-info object associated with this event.
> + * @param event Line info event object.
> + * @return Returns a pointer to the line-info object associated with this event
> + *         whose lifetime is tied to the event object. It must not be freed by
> + *         the caller.
>   */
> -struct gpiod_chip *gpiod_line_get_chip(struct gpiod_line *line);
> +struct gpiod_line_info *
> +gpiod_info_event_peek_line_info(struct gpiod_info_event *event);
> +

Rather than the peek/copy you use here, I would rename the peek to
get...

> +/**
> + * @brief Get a copy of the line-info object associated with this event.
> + * @param event Line info event object.
> + * @return Returns a copy of the line-info object associated with this event or
> + *         NULL on error. The lifetime of the returned object must be managed
> + *         by the caller and the line-info object must be freed using
> + *         ::gpiod_line_info_free.
> + */
>  
> +struct gpiod_line_info *
> +gpiod_info_event_copy_line_info(struct gpiod_info_event *event);

... and change this to 

 +struct gpiod_line_info *
 +gpiod_line_info_copy(struct gpiod_line_info *info);

as that is more generally useful.

Similarly elsewhere you use the peek/copy pattern.

<snip>

> +/**
> + * @brief Set the output value for a single offset.
> + * @param config Line config object.
> + * @param offset Offset of the line.
> + * @param value Output value to set.
> + */
> +void gpiod_line_config_set_output_value(struct gpiod_line_config *config,
> +					unsigned int offset, int value);
> +

I would rename this to gpiod_line_config_set_output() and have it set
the direction (to GPIOD_LINE_CONFIG_DIRECTION_OUTPUT of course) as well
as the value.

And maybe add a gpiod_line_config_set_input()?

<snip>

Those are the only things that jump out at me at the moment.
I much prefer this version over the previous.
Sorry I haven't had a chance to look at it earlier.

Cheers,
Kent.

  reply	other threads:[~2021-05-27 11:27 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-18 19:18 [libgpiod][RFC v2] core: implement v2.0 API Bartosz Golaszewski
2021-05-27 11:27 ` Kent Gibson [this message]
2021-05-28 13:51   ` Bartosz Golaszewski
2021-05-28 23:23     ` Kent Gibson
2021-05-29  5:10       ` Kent Gibson
2021-05-29 18:19       ` Bartosz Golaszewski
2021-05-30  0:45         ` Kent Gibson
2021-06-01 19:57           ` Bartosz Golaszewski
2021-06-02  3:12             ` Kent Gibson
2021-06-02  8:36               ` Bartosz Golaszewski
2021-06-02 10:43                 ` Kent Gibson
2021-05-30  1:27         ` Kent Gibson

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=20210527112705.GA20965@sol \
    --to=warthog618@gmail.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=brgl@bgdev.pl \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.