aboutsummaryrefslogtreecommitdiff
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 13:48:35 -0800
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 b311005ff1a..a523c8f20b5 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -946,24 +946,21 @@ static int locktree(struct usb_device *udev)
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 *udev)
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 usb_device *udev, int port1)
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 port1, struct usb_device *udev)
*/
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 *udev)
// 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 *udev)
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 *udev)
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 fcfda21be49..39e6b61b898 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)
/* 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 27575e678a7..e59d1bd52d4 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 */