aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-11-23 12:09:52 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-04 16:48:35 -0500
commit12c3da346eb81b6a281031f62eda3bca993dff5a (patch)
tree428ac85a5ebf1564aa4254dcf625174ef36452d9
parent55c527187c9d78f840b284d596a0b298bc1493af (diff)
[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 <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/core/hub.c79
-rw-r--r--drivers/usb/core/usb.c1
-rw-r--r--include/linux/usb.h1
3 files changed, 20 insertions, 61 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b311005ff1a6..a523c8f20b5d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -946,24 +946,21 @@ static int locktree(struct usb_device *udev)
946 t = locktree(hdev); 946 t = locktree(hdev);
947 if (t < 0) 947 if (t < 0)
948 return t; 948 return t;
949 for (t = 0; t < hdev->maxchild; t++) {
950 if (hdev->children[t] == udev) {
951 /* everything is fail-fast once disconnect
952 * processing starts
953 */
954 if (udev->state == USB_STATE_NOTATTACHED)
955 break;
956 949
957 /* when everyone grabs locks top->bottom, 950 /* everything is fail-fast once disconnect
958 * non-overlapping work may be concurrent 951 * processing starts
959 */ 952 */
960 usb_lock_device(udev); 953 if (udev->state == USB_STATE_NOTATTACHED) {
961 usb_unlock_device(hdev); 954 usb_unlock_device(hdev);
962 return t + 1; 955 return -ENODEV;
963 }
964 } 956 }
957
958 /* when everyone grabs locks top->bottom,
959 * non-overlapping work may be concurrent
960 */
961 usb_lock_device(udev);
965 usb_unlock_device(hdev); 962 usb_unlock_device(hdev);
966 return -ENODEV; 963 return udev->portnum;
967} 964}
968 965
969static void recursively_mark_NOTATTACHED(struct usb_device *udev) 966static void recursively_mark_NOTATTACHED(struct usb_device *udev)
@@ -1335,15 +1332,9 @@ int usb_new_device(struct usb_device *udev)
1335 le16_to_cpu(udev->config[0].desc.wTotalLength), 1332 le16_to_cpu(udev->config[0].desc.wTotalLength),
1336 USB_DT_OTG, (void **) &desc) == 0) { 1333 USB_DT_OTG, (void **) &desc) == 0) {
1337 if (desc->bmAttributes & USB_OTG_HNP) { 1334 if (desc->bmAttributes & USB_OTG_HNP) {
1338 unsigned port1; 1335 unsigned port1 = udev->portnum;
1339 struct usb_device *root = udev->parent; 1336 struct usb_device *root = udev->parent;
1340 1337
1341 for (port1 = 1; port1 <= root->maxchild;
1342 port1++) {
1343 if (root->children[port1-1] == udev)
1344 break;
1345 }
1346
1347 dev_info(&udev->dev, 1338 dev_info(&udev->dev,
1348 "Dual-Role OTG device on %sHNP port\n", 1339 "Dual-Role OTG device on %sHNP port\n",
1349 (port1 == bus->otg_port) 1340 (port1 == bus->otg_port)
@@ -1720,22 +1711,9 @@ static int __usb_suspend_device (struct usb_device *udev, int port1)
1720int usb_suspend_device(struct usb_device *udev) 1711int usb_suspend_device(struct usb_device *udev)
1721{ 1712{
1722#ifdef CONFIG_USB_SUSPEND 1713#ifdef CONFIG_USB_SUSPEND
1723 int port1;
1724
1725 if (udev->state == USB_STATE_NOTATTACHED) 1714 if (udev->state == USB_STATE_NOTATTACHED)
1726 return -ENODEV; 1715 return -ENODEV;
1727 if (!udev->parent) 1716 return __usb_suspend_device(udev, udev->portnum);
1728 port1 = 0;
1729 else {
1730 for (port1 = udev->parent->maxchild; port1 > 0; --port1) {
1731 if (udev->parent->children[port1-1] == udev)
1732 break;
1733 }
1734 if (port1 == 0)
1735 return -ENODEV;
1736 }
1737
1738 return __usb_suspend_device(udev, port1);
1739#else 1717#else
1740 /* NOTE: udev->state unchanged, it's not lying ... */ 1718 /* NOTE: udev->state unchanged, it's not lying ... */
1741 udev->dev.power.power_state = PMSG_SUSPEND; 1719 udev->dev.power.power_state = PMSG_SUSPEND;
@@ -1893,20 +1871,10 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
1893 */ 1871 */
1894int usb_resume_device(struct usb_device *udev) 1872int usb_resume_device(struct usb_device *udev)
1895{ 1873{
1896 int port1, status; 1874 int status;
1897 1875
1898 if (udev->state == USB_STATE_NOTATTACHED) 1876 if (udev->state == USB_STATE_NOTATTACHED)
1899 return -ENODEV; 1877 return -ENODEV;
1900 if (!udev->parent)
1901 port1 = 0;
1902 else {
1903 for (port1 = udev->parent->maxchild; port1 > 0; --port1) {
1904 if (udev->parent->children[port1-1] == udev)
1905 break;
1906 }
1907 if (port1 == 0)
1908 return -ENODEV;
1909 }
1910 1878
1911#ifdef CONFIG_USB_SUSPEND 1879#ifdef CONFIG_USB_SUSPEND
1912 /* selective resume of one downstream hub-to-device port */ 1880 /* selective resume of one downstream hub-to-device port */
@@ -1915,7 +1883,7 @@ int usb_resume_device(struct usb_device *udev)
1915 // NOTE swsusp may bork us, device state being wrong... 1883 // NOTE swsusp may bork us, device state being wrong...
1916 // NOTE this fails if parent is also suspended... 1884 // NOTE this fails if parent is also suspended...
1917 status = hub_port_resume(hdev_to_hub(udev->parent), 1885 status = hub_port_resume(hdev_to_hub(udev->parent),
1918 port1, udev); 1886 udev->portnum, udev);
1919 } else 1887 } else
1920 status = 0; 1888 status = 0;
1921 } else 1889 } else
@@ -3029,7 +2997,8 @@ int usb_reset_device(struct usb_device *udev)
3029 struct usb_hub *parent_hub; 2997 struct usb_hub *parent_hub;
3030 struct usb_device_descriptor descriptor = udev->descriptor; 2998 struct usb_device_descriptor descriptor = udev->descriptor;
3031 struct usb_hub *hub = NULL; 2999 struct usb_hub *hub = NULL;
3032 int i, ret = 0, port1 = -1; 3000 int i, ret = 0;
3001 int port1 = udev->portnum;
3033 3002
3034 if (udev->state == USB_STATE_NOTATTACHED || 3003 if (udev->state == USB_STATE_NOTATTACHED ||
3035 udev->state == USB_STATE_SUSPENDED) { 3004 udev->state == USB_STATE_SUSPENDED) {
@@ -3043,18 +3012,6 @@ int usb_reset_device(struct usb_device *udev)
3043 dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__); 3012 dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__);
3044 return -EISDIR; 3013 return -EISDIR;
3045 } 3014 }
3046
3047 for (i = 0; i < parent_hdev->maxchild; i++)
3048 if (parent_hdev->children[i] == udev) {
3049 port1 = i + 1;
3050 break;
3051 }
3052
3053 if (port1 < 0) {
3054 /* If this ever happens, it's very bad */
3055 dev_err(&udev->dev, "Can't locate device's port!\n");
3056 return -ENOENT;
3057 }
3058 parent_hub = hdev_to_hub(parent_hdev); 3015 parent_hub = hdev_to_hub(parent_hdev);
3059 3016
3060 /* If we're resetting an active hub, take some special actions */ 3017 /* 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 fcfda21be499..39e6b61b898a 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -439,6 +439,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
439 /* hub driver sets up TT records */ 439 /* hub driver sets up TT records */
440 } 440 }
441 441
442 dev->portnum = port1;
442 dev->bus = bus; 443 dev->bus = bus;
443 dev->parent = parent; 444 dev->parent = parent;
444 INIT_LIST_HEAD(&dev->filelist); 445 INIT_LIST_HEAD(&dev->filelist);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 27575e678a7c..e59d1bd52d4f 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -348,6 +348,7 @@ struct usb_device {
348 char **rawdescriptors; /* Raw descriptors for each config */ 348 char **rawdescriptors; /* Raw descriptors for each config */
349 349
350 unsigned short bus_mA; /* Current available from the bus */ 350 unsigned short bus_mA; /* Current available from the bus */
351 u8 portnum; /* Parent port number (origin 1) */
351 352
352 int have_langid; /* whether string_langid is valid */ 353 int have_langid; /* whether string_langid is valid */
353 int string_langid; /* language ID for strings */ 354 int string_langid; /* language ID for strings */