diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2005-11-23 12:09:52 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-04 16:48:35 -0500 |
commit | 12c3da346eb81b6a281031f62eda3bca993dff5a (patch) | |
tree | 428ac85a5ebf1564aa4254dcf625174ef36452d9 | |
parent | 55c527187c9d78f840b284d596a0b298bc1493af (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.c | 79 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 1 | ||||
-rw-r--r-- | 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 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 | ||
969 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) | 966 | static 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) | |||
1720 | int usb_suspend_device(struct usb_device *udev) | 1711 | int 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 | */ |
1894 | int usb_resume_device(struct usb_device *udev) | 1872 | int 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 */ |