Message ID | 20210331105908.67066-6-heikki.krogerus@linux.intel.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | usb: Linking ports to their Type-C connectors | expand |
Hi Heikki, I love your patch! Yet something to improve: [auto build test ERROR on peter.chen-usb/for-usb-next] [also build test ERROR on linus/master v5.12-rc5 next-20210331] [cannot apply to usb/usb-testing balbi-usb/testing/next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Heikki-Krogerus/usb-Linking-ports-to-their-Type-C-connectors/20210331-190638 base: https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git for-usb-next config: sh-allmodconfig (attached as .config) compiler: sh4-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/067cb7efe925811fd52b7b9550578f88a20d2226 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Heikki-Krogerus/usb-Linking-ports-to-their-Type-C-connectors/20210331-190638 git checkout 067cb7efe925811fd52b7b9550578f88a20d2226 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=sh If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> drivers/usb/core/usb.c:439:5: error: redefinition of 'usb_for_each_port' 439 | int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) | ^~~~~~~~~~~~~~~~~ In file included from drivers/usb/core/usb.c:35: include/linux/usb.h:884:19: note: previous definition of 'usb_for_each_port' was here 884 | static inline int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) | ^~~~~~~~~~~~~~~~~ Kconfig warnings: (for reference only) WARNING: unmet direct dependencies detected for SND_ATMEL_SOC_PDC Depends on SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && HAS_DMA Selected by - SND_ATMEL_SOC_SSC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC - SND_ATMEL_SOC_SSC_PDC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && ATMEL_SSC vim +/usb_for_each_port +439 drivers/usb/core/usb.c 429 430 /** 431 * usb_for_each_port - interate over all USB ports in the system 432 * @data: data pointer that will be handed to the callback function 433 * @fn: callback function to be called for each USB port 434 * 435 * Iterate over all USB ports and call @fn for each, passing it @data. If it 436 * returns anything other than 0, we break the iteration prematurely and return 437 * that value. 438 */ > 439 int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) 440 { 441 struct each_hub_arg arg = {data, fn}; 442 443 return usb_for_each_dev(&arg, __each_hub); 444 } 445 EXPORT_SYMBOL_GPL(usb_for_each_port); 446 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On 3/31/21 3:59 AM, Heikki Krogerus wrote: > Introducing usb_for_each_port(). It works the same way as > usb_for_each_dev(), but instead of going through every USB > device in the system, it walks through the USB ports in the > system. > > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > Acked-by: Alan Stern <stern@rowland.harvard.edu> > --- > drivers/usb/core/usb.c | 46 ++++++++++++++++++++++++++++++++++++++++++ > include/linux/usb.h | 9 +++++++++ > 2 files changed, 55 insertions(+) > > diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c > index 2ce3667ec6fae..62368c4ed37af 100644 > --- a/drivers/usb/core/usb.c > +++ b/drivers/usb/core/usb.c > @@ -398,6 +398,52 @@ int usb_for_each_dev(void *data, int (*fn)(struct usb_device *, void *)) > } > EXPORT_SYMBOL_GPL(usb_for_each_dev); > > +struct each_hub_arg { > + void *data; > + int (*fn)(struct device *, void *); > +}; > + > +static int __each_hub(struct usb_device *hdev, void *data) > +{ > + struct each_hub_arg *arg = (struct each_hub_arg *)data; > + struct usb_hub *hub; > + int ret = 0; > + int i; > + > + hub = usb_hub_to_struct_hub(hdev); > + if (!hub) > + return 0; > + > + mutex_lock(&usb_port_peer_mutex); > + > + for (i = 0; i < hdev->maxchild; i++) { > + ret = arg->fn(&hub->ports[i]->dev, arg->data); > + if (ret) > + break; > + } > + > + mutex_unlock(&usb_port_peer_mutex); > + > + return ret; > +} > + > +/** > + * usb_for_each_port - interate over all USB ports in the system > + * @data: data pointer that will be handed to the callback function > + * @fn: callback function to be called for each USB port > + * > + * Iterate over all USB ports and call @fn for each, passing it @data. If it > + * returns anything other than 0, we break the iteration prematurely and return > + * that value. > + */ > +int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) > +{ > + struct each_hub_arg arg = {data, fn}; > + > + return usb_for_each_dev(&arg, __each_hub); > +} > +EXPORT_SYMBOL_GPL(usb_for_each_port); > + > /** > * usb_release_dev - free a usb device structure when all users of it are finished. > * @dev: device that's been disconnected > diff --git a/include/linux/usb.h b/include/linux/usb.h > index ddd2f5b2a2827..ebcd03d835d04 100644 > --- a/include/linux/usb.h > +++ b/include/linux/usb.h > @@ -882,6 +882,15 @@ extern struct usb_host_interface *usb_find_alt_setting( > unsigned int iface_num, > unsigned int alt_num); > > +#ifdef CONFIG_USB #if IS_ENABLED(CONFIG_USB) > +int usb_for_each_port(void *data, int (*fn)(struct device *, void *)); > +#else > +static inline int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) > +{ > + return 0; > +} > +#endif > + > /* port claiming functions */ > int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, > struct usb_dev_state *owner); >
On Wed, Mar 31, 2021 at 09:41:22AM -0700, Guenter Roeck wrote: > > diff --git a/include/linux/usb.h b/include/linux/usb.h > > index ddd2f5b2a2827..ebcd03d835d04 100644 > > --- a/include/linux/usb.h > > +++ b/include/linux/usb.h > > @@ -882,6 +882,15 @@ extern struct usb_host_interface *usb_find_alt_setting( > > unsigned int iface_num, > > unsigned int alt_num); > > > > +#ifdef CONFIG_USB > > #if IS_ENABLED(CONFIG_USB) Thanks Guenter. > > +int usb_for_each_port(void *data, int (*fn)(struct device *, void *)); > > +#else > > +static inline int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) > > +{ > > + return 0; > > +} > > +#endif > > + > > /* port claiming functions */ > > int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, > > struct usb_dev_state *owner); > >
On 3/31/21 11:37 PM, Heikki Krogerus wrote: > On Wed, Mar 31, 2021 at 09:41:22AM -0700, Guenter Roeck wrote: >>> diff --git a/include/linux/usb.h b/include/linux/usb.h >>> index ddd2f5b2a2827..ebcd03d835d04 100644 >>> --- a/include/linux/usb.h >>> +++ b/include/linux/usb.h >>> @@ -882,6 +882,15 @@ extern struct usb_host_interface *usb_find_alt_setting( >>> unsigned int iface_num, >>> unsigned int alt_num); >>> >>> +#ifdef CONFIG_USB >> >> #if IS_ENABLED(CONFIG_USB) > Note that IS_REACHABLE(), as you ended up using, has a slightly different semantics. With IS_ENABLED(), one still has to ensure, via config file dependencies, that the code using the API is reachable. That would be something like depends on USB || USB=n This dependency ensures that the code using the API code is not built into the kernel if USB is built as module. In most cases this reflects the intended use case. IS_REACHABLE(), on the other side, will disable the API if USB is built as module and the calling code is built into the kernel. This can have unexpected results and should be used with caution. Thanks, Guenter > Thanks Guenter. > >>> +int usb_for_each_port(void *data, int (*fn)(struct device *, void *)); >>> +#else >>> +static inline int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) >>> +{ >>> + return 0; >>> +} >>> +#endif >>> + >>> /* port claiming functions */ >>> int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, >>> struct usb_dev_state *owner); >>> >
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2ce3667ec6fae..62368c4ed37af 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -398,6 +398,52 @@ int usb_for_each_dev(void *data, int (*fn)(struct usb_device *, void *)) } EXPORT_SYMBOL_GPL(usb_for_each_dev); +struct each_hub_arg { + void *data; + int (*fn)(struct device *, void *); +}; + +static int __each_hub(struct usb_device *hdev, void *data) +{ + struct each_hub_arg *arg = (struct each_hub_arg *)data; + struct usb_hub *hub; + int ret = 0; + int i; + + hub = usb_hub_to_struct_hub(hdev); + if (!hub) + return 0; + + mutex_lock(&usb_port_peer_mutex); + + for (i = 0; i < hdev->maxchild; i++) { + ret = arg->fn(&hub->ports[i]->dev, arg->data); + if (ret) + break; + } + + mutex_unlock(&usb_port_peer_mutex); + + return ret; +} + +/** + * usb_for_each_port - interate over all USB ports in the system + * @data: data pointer that will be handed to the callback function + * @fn: callback function to be called for each USB port + * + * Iterate over all USB ports and call @fn for each, passing it @data. If it + * returns anything other than 0, we break the iteration prematurely and return + * that value. + */ +int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) +{ + struct each_hub_arg arg = {data, fn}; + + return usb_for_each_dev(&arg, __each_hub); +} +EXPORT_SYMBOL_GPL(usb_for_each_port); + /** * usb_release_dev - free a usb device structure when all users of it are finished. * @dev: device that's been disconnected diff --git a/include/linux/usb.h b/include/linux/usb.h index ddd2f5b2a2827..ebcd03d835d04 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -882,6 +882,15 @@ extern struct usb_host_interface *usb_find_alt_setting( unsigned int iface_num, unsigned int alt_num); +#ifdef CONFIG_USB +int usb_for_each_port(void *data, int (*fn)(struct device *, void *)); +#else +static inline int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) +{ + return 0; +} +#endif + /* port claiming functions */ int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, struct usb_dev_state *owner);