linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: Drew Fustini <drew@beagleboard.org>
Cc: Linus Walleij <linus.walleij@linaro.org>,
	linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
	Tony Lindgren <tony@atomide.com>,
	Andy Shevchenko <andy.shevchenko@gmail.com>,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Pantelis Antoniou <pantelis.antoniou@konsulko.com>,
	Jason Kridner <jkridner@beagleboard.org>,
	Robert Nelson <robertcnelson@beagleboard.org>,
	Joe Perches <joe@perches.com>
Subject: Re: [PATCH v4 2/2] pinctrl: pinmux: Add pinmux-select debugfs file
Date: Thu, 11 Feb 2021 15:00:51 +0300	[thread overview]
Message-ID: <20210211120051.GN20820@kadam> (raw)
In-Reply-To: <20210210222851.232374-3-drew@beagleboard.org>

On Wed, Feb 10, 2021 at 02:28:54PM -0800, Drew Fustini wrote:
> Add "pinmux-select" to debugfs which will activate a function and group
> when "<function-name group-name>" are written to the file. The write
> operation pinmux_select() handles this by checking that the names map to
> valid selectors and then calling ops->set_mux().
> 
> The existing "pinmux-functions" debugfs file lists the pin functions
> registered for the pin controller. For example:
> 
> function: pinmux-uart0, groups = [ pinmux-uart0-pins ]
> function: pinmux-mmc0, groups = [ pinmux-mmc0-pins ]
> function: pinmux-mmc1, groups = [ pinmux-mmc1-pins ]
> function: pinmux-i2c0, groups = [ pinmux-i2c0-pins ]
> function: pinmux-i2c1, groups = [ pinmux-i2c1-pins ]
> function: pinmux-spi1, groups = [ pinmux-spi1-pins ]
> 
> To activate function pinmux-i2c1 and group pinmux-i2c1-pins:
> 
> echo "pinmux-i2c1 pinmux-i2c1-pins" > pinmux-select
> 
> Signed-off-by: Drew Fustini <drew@beagleboard.org>
> ---
>  drivers/pinctrl/pinmux.c | 107 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 107 insertions(+)
> 
> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
> index c651b2db0925..23fa32f0a067 100644
> --- a/drivers/pinctrl/pinmux.c
> +++ b/drivers/pinctrl/pinmux.c
> @@ -673,6 +673,111 @@ void pinmux_show_setting(struct seq_file *s,
>  DEFINE_SHOW_ATTRIBUTE(pinmux_functions);
>  DEFINE_SHOW_ATTRIBUTE(pinmux_pins);
>  
> +#define PINMUX_MAX_NAME 64
> +static ssize_t pinmux_select(struct file *file, const char __user *user_buf,
> +				   size_t len, loff_t *ppos)
> +{
> +	struct seq_file *sfile = file->private_data;
> +	struct pinctrl_dev *pctldev = sfile->private;
> +	const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
> +	const char *const *groups;
> +	char *buf, *fname, *gname;
> +	unsigned int num_groups;
> +	int fsel, gsel, ret;
> +
> +	if (len > (PINMUX_MAX_NAME * 2)) {
> +		dev_err(pctldev->dev, "write too big for buffer");
> +		return -EINVAL;
> +	}
> +
> +	buf = kzalloc(PINMUX_MAX_NAME * 2, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	fname = kzalloc(PINMUX_MAX_NAME, GFP_KERNEL);
> +	if (!fname) {
> +		ret = -ENOMEM;
> +		goto free_buf;
> +	}
> +
> +	gname = kzalloc(PINMUX_MAX_NAME, GFP_KERNEL);
> +	if (!buf) {
> +		ret = -ENOMEM;
> +		goto free_fname;
> +	}
> +
> +	ret = strncpy_from_user(buf, user_buf, PINMUX_MAX_NAME * 2);
> +	if (ret < 0) {
> +		dev_err(pctldev->dev, "failed to copy buffer from userspace");
> +		goto free_gname;
> +	}
> +	buf[len-1] = '\0';
> +
> +	ret = sscanf(buf, "%s %s", fname, gname);
> +	if (ret != 2) {
> +		dev_err(pctldev->dev, "expected format: <function-name> <group-name>");
> +		goto free_gname;
> +	}
> +
> +	fsel = pinmux_func_name_to_selector(pctldev, fname);
> +	if (fsel < 0) {
> +		dev_err(pctldev->dev, "invalid function %s in map table\n", fname);
> +		ret = -EINVAL;
> +		goto free_gname;
> +	}
> +
> +	ret = pmxops->get_function_groups(pctldev, fsel, &groups, &num_groups);
> +	if (ret) {
> +		dev_err(pctldev->dev, "no groups for function %d (%s)", fsel, fname);
> +		goto free_gname;
> +
> +	}
> +
> +	ret = match_string(groups, num_groups, gname);
> +	if (ret < 0) {
> +		dev_err(pctldev->dev, "invalid group %s", gname);
> +		goto free_gname;
> +	}
> +
> +	ret = pinctrl_get_group_selector(pctldev, gname);
> +	if (ret < 0) {
> +		dev_err(pctldev->dev, "failed to get group selectorL %s", gname);
> +		goto free_gname;
> +	}
> +	gsel = ret;
> +
> +	ret = pmxops->set_mux(pctldev, fsel, gsel);
> +	if (ret) {
> +		dev_err(pctldev->dev, "set_mux() failed: %d", ret);
> +		goto free_gname;
> +	}
> +
> +	return len;
> +
> +free_gname:
> +	devm_kfree(pctldev->dev, gname);
> +free_fname:
> +	devm_kfree(pctldev->dev, fname);
> +free_buf:
> +	devm_kfree(pctldev->dev, buf);

Ugh...  I honestly thought Smatch was supposed to print a warning when
you used devm_kfree() on kzalloc()ed memory, but I guess the warning is
only the other way around.

Smatch does complain about it as a leak because it was expecting a
regular free.

drivers/pinctrl/pinmux.c:330 pinmux_func_name_to_selector() warn: potential NULL parameter dereference 'fname'
drivers/pinctrl/pinmux.c:764 pinmux_select() warn: possible memory leak of 'gname'
drivers/pinctrl/pinmux.c:764 pinmux_select() warn: sscanf doesn't return error codes
drivers/pinctrl/pinmux.c:764 pinmux_select() warn: returning success when sscanf failed

And what about the success path?  Shouldn't we free these on the success
path as well?

regards,
dan carpenter


  parent reply	other threads:[~2021-02-11 12:04 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-10 22:28 [PATCH v4 0/2] pinctrl: pinmux: Add pinmux-select debugfs file Drew Fustini
2021-02-10 22:28 ` [PATCH v4 1/2] pinctrl: use to octal permissions for debugfs files Drew Fustini
2021-02-11  7:36   ` Joe Perches
2021-02-11  7:52     ` Drew Fustini
2021-02-10 22:28 ` [PATCH v4 2/2] pinctrl: pinmux: Add pinmux-select debugfs file Drew Fustini
2021-02-11  7:11   ` Dan Carpenter
2021-02-11  7:24     ` Joe Perches
2021-02-11  7:39       ` Dan Carpenter
2021-02-12  3:35         ` Drew Fustini
2021-02-17  8:18           ` Dan Carpenter
2021-02-11  8:09   ` Geert Uytterhoeven
2021-02-11  9:53     ` Andy Shevchenko
2021-02-12  3:39       ` Drew Fustini
2021-02-12  3:37     ` Drew Fustini
2021-02-11 12:00   ` Dan Carpenter [this message]
2021-02-12  3:41     ` Drew Fustini

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=20210211120051.GN20820@kadam \
    --to=dan.carpenter@oracle.com \
    --cc=alexandre.belloni@bootlin.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=drew@beagleboard.org \
    --cc=geert@linux-m68k.org \
    --cc=jkridner@beagleboard.org \
    --cc=joe@perches.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pantelis.antoniou@konsulko.com \
    --cc=robertcnelson@beagleboard.org \
    --cc=tony@atomide.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;
as well as URLs for NNTP newsgroup(s).