Thread (14 messages) 14 messages, 4 authors, 2021-03-25

Re: [PATCH 1/6] usb: Iterator for ports

From: Alan Stern <stern@rowland.harvard.edu>
Date: 2021-03-25 15:32:41
Also in: lkml

On Thu, Mar 25, 2021 at 05:14:42PM +0200, Heikki Krogerus wrote:
On Thu, Mar 25, 2021 at 10:41:09AM -0400, Alan Stern wrote:
quoted
On Thu, Mar 25, 2021 at 03:29:21PM +0300, Heikki Krogerus wrote:
quoted
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>
This has a couple of nasty errors.
quoted
---
 drivers/usb/core/usb.c | 43 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/usb.h    |  1 +
 2 files changed, 44 insertions(+)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 2ce3667ec6fae..6d49db9a1b208 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -398,6 +398,49 @@ 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 device *dev, void *data)
+{
+	struct each_hub_arg *arg = (struct each_hub_arg *)data;
+	struct usb_device *hdev = to_usb_device(dev);
to_usb_device() won't work properly if the struct device isn't embedded 
in an actual usb_device structure.  And that will happen, since the USB 
bus type holds usb_interface structures as well as usb_devices.
OK, so I need to filter them out.
quoted
In fact, you should use usb_for_each_dev here; it already does what you 
want.
Unfortunately I can't use usb_for_each_dev here, because it deals with
struct usb_device while I need to deal with struct device in the
callback.
I see; the prototypes of arg->fn are different.  Oh well, it's a shame 
the code can't be reused.  In any case, you should copy what 
usb.c:__each_dev() does.

Alan Stern
quoted
quoted
+	struct usb_hub *hub;
+	int ret;
+	int i;
+
+	hub = usb_hub_to_struct_hub(hdev);
+	if (!hub)
+		return 0;
+
+	for (i = 0; i < hdev->maxchild; i++) {
+		ret = arg->fn(&hub->ports[i]->dev, arg->data);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
Don't you need some sort of locking or refcounting here?  What would 
happen if this hub got removed while the routine was running?
I'll use a lock then.

thanks,

-- 
heikki
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help