lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 25 Aug 2020 06:26:01 +0000 From: Parshuram Raju Thombare <pthombar@...ence.com> To: Parshuram Raju Thombare <pthombar@...ence.com>, "bbrezillon@...nel.org" <bbrezillon@...nel.org>, "vitor.soares@...opsys.com" <vitor.soares@...opsys.com> CC: Przemyslaw Gaj <pgaj@...ence.com>, "linux-i3c@...ts.infradead.org" <linux-i3c@...ts.infradead.org>, "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>, Milind Parab <mparab@...ence.com>, "praneeth@...com" <praneeth@...com> Subject: RE: [PATCH v5] i3c: master: fix for SETDASA and DAA process Please ignore this patch. Regards, Parshuram Thombare >-----Original Message----- >From: Parshuram Thombare <pthombar@...ence.com> >Sent: Tuesday, August 25, 2020 11:51 AM >To: bbrezillon@...nel.org; vitor.soares@...opsys.com >Cc: Przemyslaw Gaj <pgaj@...ence.com>; linux-i3c@...ts.infradead.org; linux- >kernel@...r.kernel.org; Milind Parab <mparab@...ence.com>; >praneeth@...com; Parshuram Raju Thombare <pthombar@...ence.com> >Subject: [PATCH v5] i3c: master: fix for SETDASA and DAA process > >This patch fixes the following issue. >Controller slots blocked for the devices with only static_addr >or init_dyn_addr may limit the number of I3C devices >on the bus which gets dynamic address in DAA. So >instead of attaching all the devices with static_addr, >now we only attach the devices which successfully >complete SETDASA. Similarly, for the devices with only >init_dyn_addr, init_dyn_addr are reserved, and after DAA >i3c_master_add_i3c_dev_locked() will try to set the requested >dynamic address. > >Signed-off-by: Parshuram Thombare <pthombar@...ence.com> >--- >Changes between v4 and v5 are: >1. Modifications in comments and labels. > >Changes between v3 and v4 are: >1. Code rectoring and removed Fixes tag. > >Changes between v2 and v3 are: >1. Keeping init_dyn_addr reserved. >2. Code refactoring and changes in comments. > >Changes between v1 and v2 are: >1. Added boardinfo attach fix. >2. Removed reattach issue related fix. >3. Reserve init_dyn_addr initially, so that it will not > be used in DAA and attempt can be made to set those > firmware requested dynamic address after DAA. >--- > drivers/i3c/master.c | 128 +++++++++++++++++++++++++++++-------------------- > 1 files changed, 76 insertions(+), 52 deletions(-) > >diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c >index 3d995f2..ccf9b4e 100644 >--- a/drivers/i3c/master.c >+++ b/drivers/i3c/master.c >@@ -1367,7 +1367,9 @@ static int i3c_master_reattach_i3c_dev(struct >i3c_dev_desc *dev, > enum i3c_addr_slot_status status; > int ret; > >- if (dev->info.dyn_addr != old_dyn_addr) { >+ if (dev->info.dyn_addr != old_dyn_addr && >+ (!dev->boardinfo || >+ dev->info.dyn_addr != dev->boardinfo->init_dyn_addr)) { > status = i3c_bus_get_addr_slot_status(&master->bus, > dev->info.dyn_addr); > if (status != I3C_ADDR_SLOT_FREE) >@@ -1426,33 +1428,49 @@ static void i3c_master_detach_i2c_dev(struct >i2c_dev_desc *dev) > master->ops->detach_i2c_dev(dev); > } > >-static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev) >+static int i3c_master_early_i3c_dev_add(struct i3c_master_controller *master, >+ struct i3c_dev_boardinfo *boardinfo) > { >- struct i3c_master_controller *master = i3c_dev_get_master(dev); >+ struct i3c_device_info info = { >+ .static_addr = boardinfo->static_addr, >+ }; >+ struct i3c_dev_desc *i3cdev; > int ret; > >- if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr || >- !dev->boardinfo->static_addr) >- return; >+ i3cdev = i3c_master_alloc_i3c_dev(master, &info); >+ if (IS_ERR(i3cdev)) >+ return -ENOMEM; >+ >+ i3cdev->boardinfo = boardinfo; > >- ret = i3c_master_setdasa_locked(master, dev->info.static_addr, >- dev->boardinfo->init_dyn_addr); >+ ret = i3c_master_attach_i3c_dev(master, i3cdev); > if (ret) >- return; >+ goto err_free_dev; >+ >+ ret = i3c_master_setdasa_locked(master, i3cdev->info.static_addr, >+ i3cdev->boardinfo->init_dyn_addr); >+ if (ret) >+ goto err_detach_dev; > >- dev->info.dyn_addr = dev->boardinfo->init_dyn_addr; >- ret = i3c_master_reattach_i3c_dev(dev, 0); >+ i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr; >+ ret = i3c_master_reattach_i3c_dev(i3cdev, 0); > if (ret) > goto err_rstdaa; > >- ret = i3c_master_retrieve_dev_info(dev); >+ ret = i3c_master_retrieve_dev_info(i3cdev); > if (ret) > goto err_rstdaa; > >- return; >+ return 0; > > err_rstdaa: >- i3c_master_rstdaa_locked(master, dev->boardinfo->init_dyn_addr); >+ i3c_master_rstdaa_locked(master, i3cdev->boardinfo->init_dyn_addr); >+err_detach_dev: >+ i3c_master_detach_i3c_dev(i3cdev); >+err_free_dev: >+ i3c_master_free_i3c_dev(i3cdev); >+ >+ return ret; > } > > static void >@@ -1619,8 +1637,8 @@ static void i3c_master_detach_free_devs(struct >i3c_master_controller *master) > * This function is following all initialisation steps described in the I3C > * specification: > * >- * 1. Attach I2C and statically defined I3C devs to the master so that the >- * master can fill its internal device table appropriately >+ * 1. Attach I2C devs to the master so that the master can fill its internal >+ * device table appropriately > * > * 2. Call &i3c_master_controller_ops->bus_init() method to initialize > * the master controller. That's usually where the bus mode is selected >@@ -1632,11 +1650,14 @@ static void i3c_master_detach_free_devs(struct >i3c_master_controller *master) > * > * 4. Disable all slave events. > * >- * 5. Pre-assign dynamic addresses requested by the FW with SETDASA for I3C >- * devices that have a static address >+ * 5. Reserve address slots for I3C devices with init_dyn_addr. And if devices >+ * also have static_addr, try to pre-assign dynamic addresses requested by >+ * the FW with SETDASA and attach corresponding statically defined I3C >+ * devices to the master. > * > * 6. Do a DAA (Dynamic Address Assignment) to assign dynamic addresses to all >- * remaining I3C devices >+ * remaining I3C devices and attach them to the master if the dynamic address >+ * assignment succeeds > * > * Once this is done, all I3C and I2C devices should be usable. > * >@@ -1647,7 +1668,6 @@ static int i3c_master_bus_init(struct >i3c_master_controller *master) > enum i3c_addr_slot_status status; > struct i2c_dev_boardinfo *i2cboardinfo; > struct i3c_dev_boardinfo *i3cboardinfo; >- struct i3c_dev_desc *i3cdev; > struct i2c_dev_desc *i2cdev; > int ret; > >@@ -1679,34 +1699,6 @@ static int i3c_master_bus_init(struct >i3c_master_controller *master) > goto err_detach_devs; > } > } >- list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) { >- struct i3c_device_info info = { >- .static_addr = i3cboardinfo->static_addr, >- }; >- >- if (i3cboardinfo->init_dyn_addr) { >- status = i3c_bus_get_addr_slot_status(&master->bus, >- i3cboardinfo->init_dyn_addr); >- if (status != I3C_ADDR_SLOT_FREE) { >- ret = -EBUSY; >- goto err_detach_devs; >- } >- } >- >- i3cdev = i3c_master_alloc_i3c_dev(master, &info); >- if (IS_ERR(i3cdev)) { >- ret = PTR_ERR(i3cdev); >- goto err_detach_devs; >- } >- >- i3cdev->boardinfo = i3cboardinfo; >- >- ret = i3c_master_attach_i3c_dev(master, i3cdev); >- if (ret) { >- i3c_master_free_i3c_dev(i3cdev); >- goto err_detach_devs; >- } >- } > > /* > * Now execute the controller specific ->bus_init() routine, which >@@ -1743,11 +1735,43 @@ static int i3c_master_bus_init(struct >i3c_master_controller *master) > goto err_bus_cleanup; > > /* >- * Pre-assign dynamic address and retrieve device information if >- * needed. >+ * Reserve init_dyn_addr first, and then try to pre-assign dynamic >+ * address and retrieve device information if needed. >+ * In case pre-assign dynamic address fails, setting dynamic address to >+ * the requested init_dyn_addr is retried after DAA is done in >+ * i3c_master_add_i3c_dev_locked(). > */ >- i3c_bus_for_each_i3cdev(&master->bus, i3cdev) >- i3c_master_pre_assign_dyn_addr(i3cdev); >+ list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) { >+ >+ /* >+ * We don't reserve a dynamic address for devices that >+ * don't explicitly request one. >+ */ >+ if (!i3cboardinfo->init_dyn_addr) >+ continue; >+ >+ ret = i3c_bus_get_addr_slot_status(&master->bus, >+ i3cboardinfo->init_dyn_addr); >+ if (ret != I3C_ADDR_SLOT_FREE) { >+ ret = -EBUSY; >+ goto err_rstdaa; >+ } >+ >+ i3c_bus_set_addr_slot_status(&master->bus, >+ i3cboardinfo->init_dyn_addr, >+ I3C_ADDR_SLOT_I3C_DEV); >+ >+ /* >+ * Only try to create/attach devices that have a static >+ * address. Other devices will be created/attached when >+ * DAA happens, and the requested dynamic address will >+ * be set using SETNEWDA once those devices become >+ * addressable. >+ */ >+ >+ if (i3cboardinfo->static_addr) >+ i3c_master_early_i3c_dev_add(master, i3cboardinfo); >+ } > > ret = i3c_master_do_daa(master); > if (ret) >-- >1.7.1
Powered by blists - more mailing lists