[PATCH] USB: Store port number in usb_device

This patch (as610) adds a field to struct usb_device to store the device's
port number.  This allows us to remove several loops in the hub driver
(searching for a particular device among all the entries in the parent's
array of children).

Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>

---
commit 12c3da346eb81b6a281031f62eda3bca993dff5a
tree 428ac85a5ebf1564aa4254dcf625174ef36452d9
parent 55c527187c9d78f840b284d596a0b298bc1493af
author Alan Stern <[EMAIL PROTECTED]> Wed, 23 Nov 2005 12:09:52 -0500
committer Greg Kroah-Hartman <[EMAIL PROTECTED]> Wed, 04 Jan 2006 13:48:35 -0800

 drivers/usb/core/hub.c |   79 +++++++++++-------------------------------------
 drivers/usb/core/usb.c |    1 +
 include/linux/usb.h    |    1 +
 3 files changed, 20 insertions(+), 61 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b311005..a523c8f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -946,24 +946,21 @@ static int locktree(struct usb_device *u
        t = locktree(hdev);
        if (t < 0)
                return t;
-       for (t = 0; t < hdev->maxchild; t++) {
-               if (hdev->children[t] == udev) {
-                       /* everything is fail-fast once disconnect
-                        * processing starts
-                        */
-                       if (udev->state == USB_STATE_NOTATTACHED)
-                               break;
 
-                       /* when everyone grabs locks top->bottom,
-                        * non-overlapping work may be concurrent
-                        */
-                       usb_lock_device(udev);
-                       usb_unlock_device(hdev);
-                       return t + 1;
-               }
+       /* everything is fail-fast once disconnect
+        * processing starts
+        */
+       if (udev->state == USB_STATE_NOTATTACHED) {
+               usb_unlock_device(hdev);
+               return -ENODEV;
        }
+
+       /* when everyone grabs locks top->bottom,
+        * non-overlapping work may be concurrent
+        */
+       usb_lock_device(udev);
        usb_unlock_device(hdev);
-       return -ENODEV;
+       return udev->portnum;
 }
 
 static void recursively_mark_NOTATTACHED(struct usb_device *udev)
@@ -1335,15 +1332,9 @@ int usb_new_device(struct usb_device *ud
                                        
le16_to_cpu(udev->config[0].desc.wTotalLength),
                                        USB_DT_OTG, (void **) &desc) == 0) {
                        if (desc->bmAttributes & USB_OTG_HNP) {
-                               unsigned                port1;
+                               unsigned                port1 = udev->portnum;
                                struct usb_device       *root = udev->parent;
                                
-                               for (port1 = 1; port1 <= root->maxchild;
-                                               port1++) {
-                                       if (root->children[port1-1] == udev)
-                                               break;
-                               }
-
                                dev_info(&udev->dev,
                                        "Dual-Role OTG device on %sHNP port\n",
                                        (port1 == bus->otg_port)
@@ -1720,22 +1711,9 @@ static int __usb_suspend_device (struct 
 int usb_suspend_device(struct usb_device *udev)
 {
 #ifdef CONFIG_USB_SUSPEND
-       int     port1;
-
        if (udev->state == USB_STATE_NOTATTACHED)
                return -ENODEV;
-       if (!udev->parent)
-               port1 = 0;
-       else {
-               for (port1 = udev->parent->maxchild; port1 > 0; --port1) {
-                       if (udev->parent->children[port1-1] == udev)
-                               break;
-               }
-               if (port1 == 0)
-                       return -ENODEV;
-       }
-
-       return __usb_suspend_device(udev, port1);
+       return __usb_suspend_device(udev, udev->portnum);
 #else
        /* NOTE:  udev->state unchanged, it's not lying ... */
        udev->dev.power.power_state = PMSG_SUSPEND;
@@ -1893,20 +1871,10 @@ hub_port_resume(struct usb_hub *hub, int
  */
 int usb_resume_device(struct usb_device *udev)
 {
-       int     port1, status;
+       int     status;
 
        if (udev->state == USB_STATE_NOTATTACHED)
                return -ENODEV;
-       if (!udev->parent)
-               port1 = 0;
-       else {
-               for (port1 = udev->parent->maxchild; port1 > 0; --port1) {
-                       if (udev->parent->children[port1-1] == udev)
-                               break;
-               }
-               if (port1 == 0)
-                       return -ENODEV;
-       }
 
 #ifdef CONFIG_USB_SUSPEND
        /* selective resume of one downstream hub-to-device port */
@@ -1915,7 +1883,7 @@ int usb_resume_device(struct usb_device 
                        // NOTE swsusp may bork us, device state being wrong...
                        // NOTE this fails if parent is also suspended...
                        status = hub_port_resume(hdev_to_hub(udev->parent),
-                                       port1, udev);
+                                       udev->portnum, udev);
                } else
                        status = 0;
        } else
@@ -3029,7 +2997,8 @@ int usb_reset_device(struct usb_device *
        struct usb_hub                  *parent_hub;
        struct usb_device_descriptor    descriptor = udev->descriptor;
        struct usb_hub                  *hub = NULL;
-       int                             i, ret = 0, port1 = -1;
+       int                             i, ret = 0;
+       int                             port1 = udev->portnum;
 
        if (udev->state == USB_STATE_NOTATTACHED ||
                        udev->state == USB_STATE_SUSPENDED) {
@@ -3043,18 +3012,6 @@ int usb_reset_device(struct usb_device *
                dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__);
                return -EISDIR;
        }
-
-       for (i = 0; i < parent_hdev->maxchild; i++)
-               if (parent_hdev->children[i] == udev) {
-                       port1 = i + 1;
-                       break;
-               }
-
-       if (port1 < 0) {
-               /* If this ever happens, it's very bad */
-               dev_err(&udev->dev, "Can't locate device's port!\n");
-               return -ENOENT;
-       }
        parent_hub = hdev_to_hub(parent_hdev);
 
        /* If we're resetting an active hub, take some special actions */
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index fcfda21..39e6b61 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -439,6 +439,7 @@ usb_alloc_dev(struct usb_device *parent,
                /* hub driver sets up TT records */
        }
 
+       dev->portnum = port1;
        dev->bus = bus;
        dev->parent = parent;
        INIT_LIST_HEAD(&dev->filelist);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 27575e6..e59d1bd 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -348,6 +348,7 @@ struct usb_device {
        char **rawdescriptors;          /* Raw descriptors for each config */
 
        unsigned short bus_mA;          /* Current available from the bus */
+       u8 portnum;                     /* Parent port number (origin 1) */
 
        int have_langid;                /* whether string_langid is valid */
        int string_langid;              /* language ID for strings */



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_idv37&alloc_id865&op=click
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to