diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-07-30 17:08:43 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:55:01 -0400 |
commit | 4326ed0be93574dac5b5e475713015159108bd88 (patch) | |
tree | 9d8ab9c40dc5909267f1c2c68a5e13c81be8e8e0 /drivers/usb | |
parent | 5e60a16139c2a48b9876b0ff910671eee5fb32ec (diff) |
USB: address-0 handling during device initialization
This patch (as947) changes the device initialization and enumeration
code in hub.c; now udev->devnum will be set to 0 while the device is
being accessed at address 0. Until now this wasn't needed because the
address value was passed as part of urb->pipe; without that field the
device address must be stored elsewhere.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/hub.c | 21 | ||||
-rw-r--r-- | drivers/usb/core/urb.c | 4 |
2 files changed, 14 insertions, 11 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index c8a01f66df7..34be27a6cbb 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1481,6 +1481,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
1481 | case 0: | 1481 | case 0: |
1482 | /* TRSTRCY = 10 ms; plus some extra */ | 1482 | /* TRSTRCY = 10 ms; plus some extra */ |
1483 | msleep(10 + 40); | 1483 | msleep(10 + 40); |
1484 | udev->devnum = 0; /* Device now at address 0 */ | ||
1484 | /* FALL THROUGH */ | 1485 | /* FALL THROUGH */ |
1485 | case -ENOTCONN: | 1486 | case -ENOTCONN: |
1486 | case -ENODEV: | 1487 | case -ENODEV: |
@@ -2005,20 +2006,21 @@ static void ep0_reinit(struct usb_device *udev) | |||
2005 | #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) | 2006 | #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) |
2006 | #define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) | 2007 | #define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) |
2007 | 2008 | ||
2008 | static int hub_set_address(struct usb_device *udev) | 2009 | static int hub_set_address(struct usb_device *udev, int devnum) |
2009 | { | 2010 | { |
2010 | int retval; | 2011 | int retval; |
2011 | 2012 | ||
2012 | if (udev->devnum == 0) | 2013 | if (devnum <= 1) |
2013 | return -EINVAL; | 2014 | return -EINVAL; |
2014 | if (udev->state == USB_STATE_ADDRESS) | 2015 | if (udev->state == USB_STATE_ADDRESS) |
2015 | return 0; | 2016 | return 0; |
2016 | if (udev->state != USB_STATE_DEFAULT) | 2017 | if (udev->state != USB_STATE_DEFAULT) |
2017 | return -EINVAL; | 2018 | return -EINVAL; |
2018 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), | 2019 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), |
2019 | USB_REQ_SET_ADDRESS, 0, udev->devnum, 0, | 2020 | USB_REQ_SET_ADDRESS, 0, devnum, 0, |
2020 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 2021 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
2021 | if (retval == 0) { | 2022 | if (retval == 0) { |
2023 | udev->devnum = devnum; /* Device now using proper address */ | ||
2022 | usb_set_device_state(udev, USB_STATE_ADDRESS); | 2024 | usb_set_device_state(udev, USB_STATE_ADDRESS); |
2023 | ep0_reinit(udev); | 2025 | ep0_reinit(udev); |
2024 | } | 2026 | } |
@@ -2045,6 +2047,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2045 | unsigned delay = HUB_SHORT_RESET_TIME; | 2047 | unsigned delay = HUB_SHORT_RESET_TIME; |
2046 | enum usb_device_speed oldspeed = udev->speed; | 2048 | enum usb_device_speed oldspeed = udev->speed; |
2047 | char *speed, *type; | 2049 | char *speed, *type; |
2050 | int devnum = udev->devnum; | ||
2048 | 2051 | ||
2049 | /* root hub ports have a slightly longer reset period | 2052 | /* root hub ports have a slightly longer reset period |
2050 | * (from USB 2.0 spec, section 7.1.7.5) | 2053 | * (from USB 2.0 spec, section 7.1.7.5) |
@@ -2074,7 +2077,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2074 | goto fail; | 2077 | goto fail; |
2075 | } | 2078 | } |
2076 | oldspeed = udev->speed; | 2079 | oldspeed = udev->speed; |
2077 | 2080 | ||
2078 | /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... | 2081 | /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... |
2079 | * it's fixed size except for full speed devices. | 2082 | * it's fixed size except for full speed devices. |
2080 | * For Wireless USB devices, ep0 max packet is always 512 (tho | 2083 | * For Wireless USB devices, ep0 max packet is always 512 (tho |
@@ -2115,7 +2118,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2115 | dev_info (&udev->dev, | 2118 | dev_info (&udev->dev, |
2116 | "%s %s speed %sUSB device using %s and address %d\n", | 2119 | "%s %s speed %sUSB device using %s and address %d\n", |
2117 | (udev->config) ? "reset" : "new", speed, type, | 2120 | (udev->config) ? "reset" : "new", speed, type, |
2118 | udev->bus->controller->driver->name, udev->devnum); | 2121 | udev->bus->controller->driver->name, devnum); |
2119 | 2122 | ||
2120 | /* Set up TT records, if needed */ | 2123 | /* Set up TT records, if needed */ |
2121 | if (hdev->tt) { | 2124 | if (hdev->tt) { |
@@ -2202,7 +2205,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2202 | } | 2205 | } |
2203 | 2206 | ||
2204 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { | 2207 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { |
2205 | retval = hub_set_address(udev); | 2208 | retval = hub_set_address(udev, devnum); |
2206 | if (retval >= 0) | 2209 | if (retval >= 0) |
2207 | break; | 2210 | break; |
2208 | msleep(200); | 2211 | msleep(200); |
@@ -2210,7 +2213,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2210 | if (retval < 0) { | 2213 | if (retval < 0) { |
2211 | dev_err(&udev->dev, | 2214 | dev_err(&udev->dev, |
2212 | "device not accepting address %d, error %d\n", | 2215 | "device not accepting address %d, error %d\n", |
2213 | udev->devnum, retval); | 2216 | devnum, retval); |
2214 | goto fail; | 2217 | goto fail; |
2215 | } | 2218 | } |
2216 | 2219 | ||
@@ -2263,8 +2266,10 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2263 | retval = 0; | 2266 | retval = 0; |
2264 | 2267 | ||
2265 | fail: | 2268 | fail: |
2266 | if (retval) | 2269 | if (retval) { |
2267 | hub_port_disable(hub, port1, 0); | 2270 | hub_port_disable(hub, port1, 0); |
2271 | udev->devnum = devnum; /* for disconnect processing */ | ||
2272 | } | ||
2268 | mutex_unlock(&usb_address0_mutex); | 2273 | mutex_unlock(&usb_address0_mutex); |
2269 | return retval; | 2274 | return retval; |
2270 | } | 2275 | } |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 1a64a6a850f..1acca8696bc 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -284,9 +284,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
284 | 284 | ||
285 | if (!urb || urb->hcpriv || !urb->complete) | 285 | if (!urb || urb->hcpriv || !urb->complete) |
286 | return -EINVAL; | 286 | return -EINVAL; |
287 | if (!(dev = urb->dev) || | 287 | if (!(dev = urb->dev) || dev->state < USB_STATE_DEFAULT) |
288 | (dev->state < USB_STATE_DEFAULT) || | ||
289 | (!dev->bus) || (dev->devnum <= 0)) | ||
290 | return -ENODEV; | 288 | return -ENODEV; |
291 | if (dev->bus->controller->power.power_state.event != PM_EVENT_ON | 289 | if (dev->bus->controller->power.power_state.event != PM_EVENT_ON |
292 | || dev->state == USB_STATE_SUSPENDED) | 290 | || dev->state == USB_STATE_SUSPENDED) |