Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
[powerpc.git] / drivers / usb / gadget / dummy_hcd.c
index fdab97a..fcb5526 100644 (file)
@@ -40,9 +40,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
-#include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/timer.h>
@@ -779,7 +777,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
                return -EINVAL;
        if (dum->driver)
                return -EBUSY;
-       if (!driver->bind || !driver->unbind || !driver->setup
+       if (!driver->bind || !driver->setup
                        || driver->speed == USB_SPEED_UNKNOWN)
                return -EINVAL;
 
@@ -816,15 +814,14 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
        dum->gadget.dev.driver = &driver->driver;
        dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n",
                        driver->driver.name);
-       if ((retval = driver->bind (&dum->gadget)) != 0) {
-               dum->driver = NULL;
-               dum->gadget.dev.driver = NULL;
-               return retval;
-       }
+       if ((retval = driver->bind (&dum->gadget)) != 0)
+               goto err_bind_gadget;
 
        driver->driver.bus = dum->gadget.dev.parent->bus;
-       driver_register (&driver->driver);
-       device_bind_driver (&dum->gadget.dev);
+       if ((retval = driver_register (&driver->driver)) != 0)
+               goto err_register;
+       if ((retval = device_bind_driver (&dum->gadget.dev)) != 0)
+               goto err_bind_driver;
 
        /* khubd will enumerate this in a while */
        spin_lock_irq (&dum->lock);
@@ -834,6 +831,20 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
 
        usb_hcd_poll_rh_status (dummy_to_hcd (dum));
        return 0;
+
+err_bind_driver:
+       driver_unregister (&driver->driver);
+err_register:
+       if (driver->unbind)
+               driver->unbind (&dum->gadget);
+       spin_lock_irq (&dum->lock);
+       dum->pullup = 0;
+       set_link_state (dum);
+       spin_unlock_irq (&dum->lock);
+err_bind_gadget:
+       dum->driver = NULL;
+       dum->gadget.dev.driver = NULL;
+       return retval;
 }
 EXPORT_SYMBOL (usb_gadget_register_driver);
 
@@ -845,7 +856,7 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 
        if (!dum)
                return -ENODEV;
-       if (!driver || driver != dum->driver)
+       if (!driver || driver != dum->driver || !driver->unbind)
                return -EINVAL;
 
        dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n",
@@ -916,7 +927,9 @@ static int dummy_udc_probe (struct platform_device *pdev)
        usb_get_hcd (dummy_to_hcd (dum));
 
        platform_set_drvdata (pdev, dum);
-       device_create_file (&dum->gadget.dev, &dev_attr_function);
+       rc = device_create_file (&dum->gadget.dev, &dev_attr_function);
+       if (rc < 0)
+               device_unregister (&dum->gadget.dev);
        return rc;
 }
 
@@ -1537,7 +1550,7 @@ return_urb:
                        ep->already_seen = ep->setup_stage = 0;
 
                spin_unlock (&dum->lock);
-               usb_hcd_giveback_urb (dummy_to_hcd(dum), urb, NULL);
+               usb_hcd_giveback_urb (dummy_to_hcd(dum), urb);
                spin_lock (&dum->lock);
 
                goto restart;
@@ -1864,8 +1877,7 @@ static int dummy_start (struct usb_hcd *hcd)
 #endif
 
        /* FIXME 'urbs' should be a per-device thing, maybe in usbcore */
-       device_create_file (dummy_dev(dum), &dev_attr_urbs);
-       return 0;
+       return device_create_file (dummy_dev(dum), &dev_attr_urbs);
 }
 
 static void dummy_stop (struct usb_hcd *hcd)