pci_resource_len (pdev, 0));
        if (dev->enabled)
                pci_disable_device(pdev);
-       device_unregister(&dev->gadget.dev);
+       if (dev->registered)
+               device_unregister(&dev->gadget.dev);
 
        pci_set_drvdata(pdev, NULL);
        dev->regs = NULL;
        if (!pdev->irq) {
                printk(KERN_ERR "Check PCI %s IRQ setup!\n", pci_name(pdev));
                retval = -ENODEV;
-               goto done;
+               goto err;
        }
 
        /* alloc, and start init */
        if (dev == NULL){
                pr_debug("enomem %s\n", pci_name(pdev));
                retval = -ENOMEM;
-               goto done;
+               goto err;
        }
 
        spin_lock_init(&dev->lock);
        retval = pci_enable_device(pdev);
        if (retval < 0) {
                DBG(dev, "can't enable, %d\n", retval);
-               goto done;
+               goto err;
        }
        dev->enabled = 1;
 
        if (!request_mem_region(resource, len, driver_name)) {
                DBG(dev, "controller already in use\n");
                retval = -EBUSY;
-               goto done;
+               goto err;
        }
        dev->got_region = 1;
 
        if (base == NULL) {
                DBG(dev, "can't map memory\n");
                retval = -EFAULT;
-               goto done;
+               goto err;
        }
        dev->regs = (struct goku_udc_regs __iomem *) base;
 
                        driver_name, dev) != 0) {
                DBG(dev, "request interrupt %d failed\n", pdev->irq);
                retval = -EBUSY;
-               goto done;
+               goto err;
        }
        dev->got_irq = 1;
        if (use_dma)
        create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev);
 #endif
 
-       /* done */
        the_controller = dev;
        retval = device_register(&dev->gadget.dev);
-       if (retval == 0)
-               return 0;
+       if (retval) {
+               put_device(&dev->gadget.dev);
+               goto err;
+       }
+       dev->registered = 1;
+       return 0;
 
-done:
+err:
        if (dev)
                goku_remove (pdev);
        return retval;