Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4326ed0be93574dac5b5e475713015159108bd88
Commit:     4326ed0be93574dac5b5e475713015159108bd88
Parent:     5e60a16139c2a48b9876b0ff910671eee5fb32ec
Author:     Alan Stern <[EMAIL PROTECTED]>
AuthorDate: Mon Jul 30 17:08:43 2007 -0400
Committer:  Greg Kroah-Hartman <[EMAIL PROTECTED]>
CommitDate: Fri Oct 12 14:55:01 2007 -0700

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 drivers/usb/core/hub.c |   21 +++++++++++++--------
 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 c8a01f6..34be27a 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,
                case 0:
                        /* TRSTRCY = 10 ms; plus some extra */
                        msleep(10 + 40);
+                       udev->devnum = 0;       /* Device now at address 0 */
                        /* FALL THROUGH */
                case -ENOTCONN:
                case -ENODEV:
@@ -2005,20 +2006,21 @@ static void ep0_reinit(struct usb_device *udev)
 #define usb_sndaddr0pipe()     (PIPE_CONTROL << 30)
 #define usb_rcvaddr0pipe()     ((PIPE_CONTROL << 30) | USB_DIR_IN)
 
-static int hub_set_address(struct usb_device *udev)
+static int hub_set_address(struct usb_device *udev, int devnum)
 {
        int retval;
 
-       if (udev->devnum == 0)
+       if (devnum <= 1)
                return -EINVAL;
        if (udev->state == USB_STATE_ADDRESS)
                return 0;
        if (udev->state != USB_STATE_DEFAULT)
                return -EINVAL;
        retval = usb_control_msg(udev, usb_sndaddr0pipe(),
-               USB_REQ_SET_ADDRESS, 0, udev->devnum, 0,
+               USB_REQ_SET_ADDRESS, 0, devnum, 0,
                NULL, 0, USB_CTRL_SET_TIMEOUT);
        if (retval == 0) {
+               udev->devnum = devnum;  /* Device now using proper address */
                usb_set_device_state(udev, USB_STATE_ADDRESS);
                ep0_reinit(udev);
        }
@@ -2045,6 +2047,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device 
*udev, int port1,
        unsigned                delay = HUB_SHORT_RESET_TIME;
        enum usb_device_speed   oldspeed = udev->speed;
        char                    *speed, *type;
+       int                     devnum = udev->devnum;
 
        /* root hub ports have a slightly longer reset period
         * (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,
                goto fail;
        }
        oldspeed = udev->speed;
-  
+
        /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
         * it's fixed size except for full speed devices.
         * 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,
        dev_info (&udev->dev,
                  "%s %s speed %sUSB device using %s and address %d\n",
                  (udev->config) ? "reset" : "new", speed, type,
-                 udev->bus->controller->driver->name, udev->devnum);
+                 udev->bus->controller->driver->name, devnum);
 
        /* Set up TT records, if needed  */
        if (hdev->tt) {
@@ -2202,7 +2205,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device 
*udev, int port1,
                }
 
                for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
-                       retval = hub_set_address(udev);
+                       retval = hub_set_address(udev, devnum);
                        if (retval >= 0)
                                break;
                        msleep(200);
@@ -2210,7 +2213,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device 
*udev, int port1,
                if (retval < 0) {
                        dev_err(&udev->dev,
                                "device not accepting address %d, error %d\n",
-                               udev->devnum, retval);
+                               devnum, retval);
                        goto fail;
                }
  
@@ -2263,8 +2266,10 @@ hub_port_init (struct usb_hub *hub, struct usb_device 
*udev, int port1,
        retval = 0;
 
 fail:
-       if (retval)
+       if (retval) {
                hub_port_disable(hub, port1, 0);
+               udev->devnum = devnum;  /* for disconnect processing */
+       }
        mutex_unlock(&usb_address0_mutex);
        return retval;
 }
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 1a64a6a..1acca86 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)
 
        if (!urb || urb->hcpriv || !urb->complete)
                return -EINVAL;
-       if (!(dev = urb->dev) ||
-           (dev->state < USB_STATE_DEFAULT) ||
-           (!dev->bus) || (dev->devnum <= 0))
+       if (!(dev = urb->dev) || dev->state < USB_STATE_DEFAULT)
                return -ENODEV;
        if (dev->bus->controller->power.power_state.event != PM_EVENT_ON
                        || dev->state == USB_STATE_SUSPENDED)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to