Greg:

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).

Alan Stern



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

---

Index: usb-2.6/drivers/usb/core/hub.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/hub.c
+++ usb-2.6/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
@@ -3030,7 +2998,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) {
@@ -3044,18 +3013,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 */
Index: usb-2.6/include/linux/usb.h
===================================================================
--- usb-2.6.orig/include/linux/usb.h
+++ usb-2.6/include/linux/usb.h
@@ -347,6 +347,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 */
Index: usb-2.6/drivers/usb/core/usb.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/usb.c
+++ usb-2.6/drivers/usb/core/usb.c
@@ -436,6 +436,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);



-------------------------------------------------------
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_id=7637&alloc_id=16865&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