[PATCH] fsi/core: Fix error paths on CFAM init
Benjamin Herrenschmidt
benh at kernel.crashing.org
Fri Jun 28 18:12:42 AEST 2019
On Fri, 2019-06-28 at 14:41 +0800, Jeremy Kerr wrote:
> Change d1dcd67825 re-worked the struct fsi_slave initialisation in
> fsi_slave_init, but introduced a few inconsitencies: the slave->dev
> is
> now registered through cdev_device_add, but we may kfree() the device
> out from underneath the cdev registration. We may also leave an IDA
> allocated.
>
> This change fixes the error paths, so that we kfree() only before the
> device is registered with the core code. We also move the smode write
> to
> before we start creating proper devices, as it's the most likely to
> fail. We also remove the IDA-allocated minor on error, and properly
> clean up the of_node.
>
> Fixes: d1dcd678257603e71cf3f3d84c70e2b6f0f14bb8
> Reported-by: Lei YU <mine260309 at gmail.com>
> Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
> ---
You want to take maintainership of drivers/fsi ? :-)
>
> Lei: Can you test this on your hardware? Thanks!
>
> ---
> drivers/fsi/fsi-core.c | 34 +++++++++++++++++++++-------------
> 1 file changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
> index 1d83f3ba478b..9ba5e19d1c42 100644
> --- a/drivers/fsi/fsi-core.c
> +++ b/drivers/fsi/fsi-core.c
> @@ -1029,6 +1029,14 @@ static int fsi_slave_init(struct fsi_master
> *master, int link, uint8_t id)
>
> }
>
> + rc = fsi_slave_set_smode(slave);
> + if (rc) {
> + dev_warn(&master->dev,
> + "can't set smode on slave:%02x:%02x
> %d\n",
> + link, id, rc);
> + goto err_free;
> + }
> +
> /* Allocate a minor in the FSI space */
> rc = __fsi_get_new_minor(slave, fsi_dev_cfam, &slave->dev.devt,
> &slave->cdev_idx);
> @@ -1040,17 +1048,14 @@ static int fsi_slave_init(struct fsi_master
> *master, int link, uint8_t id)
> rc = cdev_device_add(&slave->cdev, &slave->dev);
> if (rc) {
> dev_err(&slave->dev, "Error %d creating slave
> device\n", rc);
> - goto err_free;
> + goto err_free_ida;
> }
>
> - rc = fsi_slave_set_smode(slave);
> - if (rc) {
> - dev_warn(&master->dev,
> - "can't set smode on slave:%02x:%02x
> %d\n",
> - link, id, rc);
> - kfree(slave);
> - return -ENODEV;
> - }
> + /* Now that we have the cdev registered with the core, any
> fatal
> + * failures beyond this point will need to clean up through
> + * cdev_device_del(). Fortunately though, nothing past here is
> fatal.
> + */
> +
> if (master->link_config)
> master->link_config(master, link,
> slave->t_send_delay,
> @@ -1067,11 +1072,14 @@ static int fsi_slave_init(struct fsi_master
> *master, int link, uint8_t id)
> dev_dbg(&master->dev, "failed during slave scan with:
> %d\n",
> rc);
>
> - return rc;
> + return 0;
>
> - err_free:
> - put_device(&slave->dev);
> - return rc;
> +err_free_ida:
> + fsi_free_minor(slave->dev.devt);
> +err_free:
> + of_node_put(slave->dev.of_node);
> + kfree(slave);
> + return rc
> }
>
> /* FSI master support */
More information about the openbmc
mailing list