diff mbox

[linux,dev-4.7,v2] drivers/fsi: Remove hub devices during master unregister

Message ID 20170307164610.78174-1-cbostic@linux.vnet.ibm.com
State Accepted, archived
Headers show

Commit Message

Christopher Bostic March 7, 2017, 4:46 p.m. UTC
All hub devices must be removed when the primary FSI master
is being unregistered.  This ensures that the system is in
a clean state when another scan is attempted.  Failure to do so
will result in duplicate /sys device name errors.

Signed-off-by: Christopher Bostic <cbostic@linux.vnet.ibm.com>
---
v2: Fix missing return in non void function warning
---
 drivers/fsi/fsi-core.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Eddie James March 8, 2017, 3:06 p.m. UTC | #1
On 03/07/2017 10:46 AM, Christopher Bostic wrote:

> All hub devices must be removed when the primary FSI master
> is being unregistered.  This ensures that the system is in
> a clean state when another scan is attempted.  Failure to do so
> will result in duplicate /sys device name errors.
>
> Signed-off-by: Christopher Bostic <cbostic@linux.vnet.ibm.com>
> ---
> v2: Fix missing return in non void function warning
> ---
>   drivers/fsi/fsi-core.c | 18 ++++++++++++++++++
>   1 file changed, 18 insertions(+)
>
> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
> index bd57b41..bbdf6b8 100644
> --- a/drivers/fsi/fsi-core.c
> +++ b/drivers/fsi/fsi-core.c
> @@ -84,6 +84,7 @@ struct fsi_master_hub {
>   #define to_fsi_master_hub(d) container_of(d, struct fsi_master_hub, master)
>   #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev)
>
> +static void fsi_master_unscan(struct fsi_master *master);
>   static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr,
>   		void *val, size_t size);
>   static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr,
> @@ -441,6 +442,7 @@ static int fsi_slave_scan(struct fsi_slave *slave)
>   			hub->dev.release = hub_master_release;
>   			hub->master.dev = &hub->dev;
>   			hub->master.dev->parent = &slave->dev;
> +			dev_set_drvdata(&hub->dev, hub);
>   			rc = device_add(&hub->dev);
>   			if (rc)
>   				return rc;
> @@ -739,6 +741,20 @@ static int fsi_master_scan(struct fsi_master *master)
>   	return 0;
>   }
>
> +static int fsi_unregister_hubs(struct device *dev, void *data)
> +{
> +	struct fsi_master_hub *hub =
> +				(struct fsi_master_hub *)dev_get_drvdata(dev);
> +
> +	if (!hub)
> +		return 0;
> +
> +	device_del(dev);
> +	fsi_master_unscan(&hub->master);
> +
> +	return 0;
> +}
> +
>   static void fsi_master_unscan(struct fsi_master *master)
>   {
>   	struct fsi_slave *slave, *slave_tmp;
> @@ -756,6 +772,8 @@ static void fsi_master_unscan(struct fsi_master *master)
>   			device_del(&fsi_dev->dev);
>   			put_device(&fsi_dev->dev);
>   		}
> +		/* Remove any hub masters */
> +		device_for_each_child(&slave->dev, NULL, fsi_unregister_hubs);
>   		device_unregister(&slave->dev);
>   	}
>   	master->slave_list = false;

Looks good.

Acked-by: Eddie James <eajames@linux.vnet.ibm.com>
Joel Stanley March 9, 2017, 10:54 a.m. UTC | #2
On Wed, Mar 8, 2017 at 3:16 AM, Christopher Bostic
<cbostic@linux.vnet.ibm.com> wrote:
> All hub devices must be removed when the primary FSI master
> is being unregistered.  This ensures that the system is in
> a clean state when another scan is attempted.  Failure to do so
> will result in duplicate /sys device name errors.
>
> Signed-off-by: Christopher Bostic <cbostic@linux.vnet.ibm.com>
> ---
> v2: Fix missing return in non void function warning
> ---
>  drivers/fsi/fsi-core.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
> index bd57b41..bbdf6b8 100644
> --- a/drivers/fsi/fsi-core.c
> +++ b/drivers/fsi/fsi-core.c
> @@ -84,6 +84,7 @@ struct fsi_master_hub {
>  #define to_fsi_master_hub(d) container_of(d, struct fsi_master_hub, master)
>  #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev)
>
> +static void fsi_master_unscan(struct fsi_master *master);
>  static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr,
>                 void *val, size_t size);
>  static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr,
> @@ -441,6 +442,7 @@ static int fsi_slave_scan(struct fsi_slave *slave)
>                         hub->dev.release = hub_master_release;
>                         hub->master.dev = &hub->dev;
>                         hub->master.dev->parent = &slave->dev;
> +                       dev_set_drvdata(&hub->dev, hub);
>                         rc = device_add(&hub->dev);
>                         if (rc)
>                                 return rc;
> @@ -739,6 +741,20 @@ static int fsi_master_scan(struct fsi_master *master)
>         return 0;
>  }
>
> +static int fsi_unregister_hubs(struct device *dev, void *data)
> +{
> +       struct fsi_master_hub *hub =
> +                               (struct fsi_master_hub *)dev_get_drvdata(dev);

dev_get_drvdata returns a void *, so there is no need to cast.

I fixed this up when applying.

> +       if (!hub)
> +               return 0;

Is this expected? Should it return an error?

> +
> +       device_del(dev);
> +       fsi_master_unscan(&hub->master);
> +
> +       return 0;
> +}
> +
>  static void fsi_master_unscan(struct fsi_master *master)
>  {
>         struct fsi_slave *slave, *slave_tmp;
> @@ -756,6 +772,8 @@ static void fsi_master_unscan(struct fsi_master *master)
>                         device_del(&fsi_dev->dev);
>                         put_device(&fsi_dev->dev);
>                 }
> +               /* Remove any hub masters */
> +               device_for_each_child(&slave->dev, NULL, fsi_unregister_hubs);
>                 device_unregister(&slave->dev);
>         }
>         master->slave_list = false;
> --
> 1.8.2.2
>
Christopher Bostic March 9, 2017, 2:04 p.m. UTC | #3
On 3/9/17 4:54 AM, Joel Stanley wrote:
> On Wed, Mar 8, 2017 at 3:16 AM, Christopher Bostic
> <cbostic@linux.vnet.ibm.com> wrote:
>> All hub devices must be removed when the primary FSI master
>> is being unregistered.  This ensures that the system is in
>> a clean state when another scan is attempted.  Failure to do so
>> will result in duplicate /sys device name errors.
>>
>> Signed-off-by: Christopher Bostic <cbostic@linux.vnet.ibm.com>
>> ---
>> v2: Fix missing return in non void function warning
>> ---
>>   drivers/fsi/fsi-core.c | 18 ++++++++++++++++++
>>   1 file changed, 18 insertions(+)
>>
>> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
>> index bd57b41..bbdf6b8 100644
>> --- a/drivers/fsi/fsi-core.c
>> +++ b/drivers/fsi/fsi-core.c
>> @@ -84,6 +84,7 @@ struct fsi_master_hub {
>>   #define to_fsi_master_hub(d) container_of(d, struct fsi_master_hub, master)
>>   #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev)
>>
>> +static void fsi_master_unscan(struct fsi_master *master);
>>   static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr,
>>                  void *val, size_t size);
>>   static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr,
>> @@ -441,6 +442,7 @@ static int fsi_slave_scan(struct fsi_slave *slave)
>>                          hub->dev.release = hub_master_release;
>>                          hub->master.dev = &hub->dev;
>>                          hub->master.dev->parent = &slave->dev;
>> +                       dev_set_drvdata(&hub->dev, hub);
>>                          rc = device_add(&hub->dev);
>>                          if (rc)
>>                                  return rc;
>> @@ -739,6 +741,20 @@ static int fsi_master_scan(struct fsi_master *master)
>>          return 0;
>>   }
>>
>> +static int fsi_unregister_hubs(struct device *dev, void *data)
>> +{
>> +       struct fsi_master_hub *hub =
>> +                               (struct fsi_master_hub *)dev_get_drvdata(dev);
> dev_get_drvdata returns a void *, so there is no need to cast.
>
> I fixed this up when applying.
>
>> +       if (!hub)
>> +               return 0;
> Is this expected? Should it return an error?
Hi Joel,

Yes it would be expected in cases where the child dev being processed is 
not a hub.  Only hub master has its driver data set. In effect !hub 
means this child is not a hub master.

Thanks
-Chris
>> +
>> +       device_del(dev);
>> +       fsi_master_unscan(&hub->master);
>> +
>> +       return 0;
>> +}
>> +
>>   static void fsi_master_unscan(struct fsi_master *master)
>>   {
>>          struct fsi_slave *slave, *slave_tmp;
>> @@ -756,6 +772,8 @@ static void fsi_master_unscan(struct fsi_master *master)
>>                          device_del(&fsi_dev->dev);
>>                          put_device(&fsi_dev->dev);
>>                  }
>> +               /* Remove any hub masters */
>> +               device_for_each_child(&slave->dev, NULL, fsi_unregister_hubs);
>>                  device_unregister(&slave->dev);
>>          }
>>          master->slave_list = false;
>> --
>> 1.8.2.2
>>
diff mbox

Patch

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index bd57b41..bbdf6b8 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -84,6 +84,7 @@  struct fsi_master_hub {
 #define to_fsi_master_hub(d) container_of(d, struct fsi_master_hub, master)
 #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev)
 
+static void fsi_master_unscan(struct fsi_master *master);
 static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr,
 		void *val, size_t size);
 static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr,
@@ -441,6 +442,7 @@  static int fsi_slave_scan(struct fsi_slave *slave)
 			hub->dev.release = hub_master_release;
 			hub->master.dev = &hub->dev;
 			hub->master.dev->parent = &slave->dev;
+			dev_set_drvdata(&hub->dev, hub);
 			rc = device_add(&hub->dev);
 			if (rc)
 				return rc;
@@ -739,6 +741,20 @@  static int fsi_master_scan(struct fsi_master *master)
 	return 0;
 }
 
+static int fsi_unregister_hubs(struct device *dev, void *data)
+{
+	struct fsi_master_hub *hub =
+				(struct fsi_master_hub *)dev_get_drvdata(dev);
+
+	if (!hub)
+		return 0;
+
+	device_del(dev);
+	fsi_master_unscan(&hub->master);
+
+	return 0;
+}
+
 static void fsi_master_unscan(struct fsi_master *master)
 {
 	struct fsi_slave *slave, *slave_tmp;
@@ -756,6 +772,8 @@  static void fsi_master_unscan(struct fsi_master *master)
 			device_del(&fsi_dev->dev);
 			put_device(&fsi_dev->dev);
 		}
+		/* Remove any hub masters */
+		device_for_each_child(&slave->dev, NULL, fsi_unregister_hubs);
 		device_unregister(&slave->dev);
 	}
 	master->slave_list = false;