]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/core/hcd.c
Merge master.kernel.org:/home/rmk/linux-2.6-serial
[linux-2.6-omap-h63xx.git] / drivers / usb / core / hcd.c
index 16790ad0e2e46bd435ba413e23779ab56498af29..0018bbc4de3414bae4bd447e619b169239e593fc 100644 (file)
  */
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
@@ -130,7 +125,7 @@ static const u8 usb2_rh_dev_descriptor [18] = {
        0x09,       /*  __u8  bDeviceClass; HUB_CLASSCODE */
        0x00,       /*  __u8  bDeviceSubClass; */
        0x01,       /*  __u8  bDeviceProtocol; [ usb 2.0 single TT ]*/
-       0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
+       0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */
 
        0x00, 0x00, /*  __le16 idVendor; */
        0x00, 0x00, /*  __le16 idProduct; */
@@ -153,7 +148,7 @@ static const u8 usb11_rh_dev_descriptor [18] = {
        0x09,       /*  __u8  bDeviceClass; HUB_CLASSCODE */
        0x00,       /*  __u8  bDeviceSubClass; */
        0x00,       /*  __u8  bDeviceProtocol; [ low/full speeds only ] */
-       0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
+       0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */
 
        0x00, 0x00, /*  __le16 idVendor; */
        0x00, 0x00, /*  __le16 idProduct; */
@@ -744,10 +739,9 @@ struct usb_bus *usb_alloc_bus (struct usb_operations *op)
 {
        struct usb_bus *bus;
 
-       bus = kmalloc (sizeof *bus, GFP_KERNEL);
+       bus = kzalloc (sizeof *bus, GFP_KERNEL);
        if (!bus)
                return NULL;
-       memset(bus, 0, sizeof(struct usb_bus));
        usb_bus_init (bus);
        bus->op = op;
        return bus;
@@ -793,7 +787,6 @@ static int usb_register_bus(struct usb_bus *bus)
        up (&usb_bus_list_lock);
 
        usb_notify_add_bus(bus);
-       usbmon_notify_bus_add (bus);
 
        dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum);
        return 0;
@@ -821,7 +814,6 @@ static void usb_deregister_bus (struct usb_bus *bus)
        up (&usb_bus_list_lock);
 
        usb_notify_remove_bus(bus);
-       usbmon_notify_bus_remove (bus);
 
        clear_bit (bus->busnum, busmap.busmap);
 
@@ -865,9 +857,7 @@ static int register_root_hub (struct usb_device *usb_dev,
                return (retval < 0) ? retval : -EMSGSIZE;
        }
 
-       usb_lock_device (usb_dev);
        retval = usb_new_device (usb_dev);
-       usb_unlock_device (usb_dev);
        if (retval) {
                usb_dev->bus->root_hub = NULL;
                dev_err (parent_dev, "can't register root hub for %s, %d\n",
@@ -1323,11 +1313,12 @@ static int hcd_unlink_urb (struct urb *urb, int status)
         * finish unlinking the initial failed usb_set_address()
         * or device descriptor fetch.
         */
-       if (!hcd->saw_irq && hcd->self.root_hub != urb->dev) {
+       if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags)
+           && hcd->self.root_hub != urb->dev) {
                dev_warn (hcd->self.controller, "Unlink after no-IRQ?  "
                        "Controller is probably using the wrong IRQ."
                        "\n");
-               hcd->saw_irq = 1;
+               set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
        }
 
        urb->status = status;
@@ -1657,13 +1648,15 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
        struct usb_hcd          *hcd = __hcd;
        int                     start = hcd->state;
 
-       if (start == HC_STATE_HALT)
+       if (unlikely(start == HC_STATE_HALT ||
+           !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
                return IRQ_NONE;
        if (hcd->driver->irq (hcd, r) == IRQ_NONE)
                return IRQ_NONE;
 
-       hcd->saw_irq = 1;
-       if (hcd->state == HC_STATE_HALT)
+       set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
+
+       if (unlikely(hcd->state == HC_STATE_HALT))
                usb_hc_died (hcd);
        return IRQ_HANDLED;
 }
@@ -1776,6 +1769,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
 
        dev_info(hcd->self.controller, "%s\n", hcd->product_desc);
 
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
        /* till now HC has been in an indeterminate state ... */
        if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
                dev_err(hcd->self.controller, "can't reset\n");
@@ -1830,8 +1825,6 @@ int usb_add_hcd(struct usb_hcd *hcd,
                retval = -ENOMEM;
                goto err_allocate_root_hub;
        }
-       rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
-                       USB_SPEED_FULL;
 
        /* Although in principle hcd->driver->start() might need to use rhdev,
         * none of the current drivers do.
@@ -1849,6 +1842,9 @@ int usb_add_hcd(struct usb_hcd *hcd,
                dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
        hcd->remote_wakeup = hcd->can_wakeup;
 
+       rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
+                       USB_SPEED_FULL;
+       rhdev->bus_mA = min(500u, hcd->power_budget);
        if ((retval = register_root_hub(rhdev, hcd)) != 0)
                goto err_register_root_hub;
 
@@ -1894,7 +1890,10 @@ void usb_remove_hcd(struct usb_hcd *hcd)
        spin_lock_irq (&hcd_root_hub_lock);
        hcd->rh_registered = 0;
        spin_unlock_irq (&hcd_root_hub_lock);
+
+       down(&usb_bus_list_lock);
        usb_disconnect(&hcd->self.root_hub);
+       up(&usb_bus_list_lock);
 
        hcd->poll_rh = 0;
        del_timer_sync(&hcd->rh_timer);