Merge to Fedora kernel-2.6.7-1.441
[linux-2.6.git] / drivers / usb / core / hcd.c
index 04a8b32..ecac9fa 100644 (file)
@@ -764,8 +764,9 @@ EXPORT_SYMBOL (usb_deregister_bus);
  *
  * The USB host controller calls this function to register the root hub
  * properly with the USB subsystem.  It sets up the device properly in
- * the device model tree, and then calls usb_new_device() to register the
- * usb device.  It also assigns the root hub's USB address (always 1).
+ * the device tree and stores the root_hub pointer in the bus structure,
+ * then calls usb_new_device() to register the usb device.  It also
+ * assigns the root hub's USB address (always 1).
  */
 int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev)
 {
@@ -777,7 +778,10 @@ int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev
        memset (&usb_dev->bus->devmap.devicemap, 0,
                        sizeof usb_dev->bus->devmap.devicemap);
        set_bit (devnum, usb_dev->bus->devmap.devicemap);
-       usb_dev->state = USB_STATE_ADDRESS;
+       usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
+
+       down (&usb_bus_list_lock);
+       usb_dev->bus->root_hub = usb_dev;
 
        usb_dev->epmaxpacketin[0] = usb_dev->epmaxpacketout[0] = 64;
        retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
@@ -787,14 +791,15 @@ int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev
                return (retval < 0) ? retval : -EMSGSIZE;
        }
 
-       (void) usb_get_dev (usb_dev);
        down (&usb_dev->serialize);
        retval = usb_new_device (usb_dev);
-       if (retval)
+       up (&usb_dev->serialize);
+       if (retval) {
+               usb_dev->bus->root_hub = NULL;
                dev_err (parent_dev, "can't register root hub for %s, %d\n",
                                usb_dev->dev.bus_id, retval);
-       up (&usb_dev->serialize);
-       usb_put_dev (usb_dev);
+       }
+       up (&usb_bus_list_lock);
        return retval;
 }
 EXPORT_SYMBOL (usb_register_root_hub);
@@ -1574,11 +1579,13 @@ static void hcd_panic (void *_hcd)
        unsigned                i;
 
        /* hc's root hub is removed later removed in hcd->stop() */
-       hub->state = USB_STATE_NOTATTACHED;
+       down (&hub->serialize);
+       usb_set_device_state(hub, USB_STATE_NOTATTACHED);
        for (i = 0; i < hub->maxchild; i++) {
                if (hub->children [i])
                        usb_disconnect (&hub->children [i]);
        }
+       up (&hub->serialize);
 }
 
 /**