On Tue, 21 Sep 2010 11:34:13 +0200, Felipe Balbi <balbi@xxxxxx> wrote:
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
+static inline int usb_gadget_start(struct usb_gadget *gadget) +{ + if (!gadget->ops->start) + return -EOPNOTSUPP;
So EOPNOTSUPP after all? Omission or have you decided to leave it that way after all?
+ return gadget->ops->start(gadget); +}
+int usb_add_udc(struct device *parent, struct usb_udc *udc) +{ + struct device *dev; + unsigned long flags; + int ret; + + if (!udc->gadget || !udc->gadget->ops || + !udc->gadget->ops->start) { + dev_dbg(parent, "unitializaed gadget\n"); + return -EINVAL; + } + + dev_vdbg(parent, "registering UDC\n"); + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto err1; + } + + device_initialize(dev); + + dev->class = udc_class; + dev->type = &udc_device_type; + dev->parent = parent; + dev->release = usb_udc_release; + dev_set_drvdata(dev, udc); + udc->dev = dev; + udc->gadget->dev.parent = udc->dev; + udc->gadget->dev.release = usb_udc_nop_release; + udc->gadget->dev.dma_mask = parent->dma_mask; + + ret = dev_set_name(dev, "%s", udc->name); + if (ret) + goto err2; + + ret = dev_set_name(&udc->gadget->dev, udc->name);
Still with no "%s"?
+ if (ret) + goto err2; + + ret = device_add(dev); + if (ret) + goto err2; + + ret = device_register(&udc->gadget->dev); + if (ret) + goto err3; + + + spin_lock_irqsave(&udc_lock, flags); + list_add_tail(&udc->list, &udc_list); + spin_unlock_irqrestore(&udc_lock, flags); + + return 0; + +err3: + device_unregister(dev); + +err2: + kfree(dev); + +err1: + return ret; +}
+void usb_del_udc(struct usb_udc *udc) +{ + unsigned long flags; + + dev_vdbg(udc->dev->parent, "unregistering UDC\n"); + + spin_lock_irqsave(&udc_lock, flags); + list_del(&udc->list); + spin_unlock_irqrestore(&udc_lock, flags); + + if (udc->busy) + usb_gadget_unregister_driver(udc->driver);
usb_gadget_unregister_driver() won't find the UDC -- it has been removed from the list after all. Also, the more I think about it, the more I'm convinced that this needs some synchronisation. If usb_del_udc() is called at the same time as usb_gadget_unregister_driver() funky stuff can happen. Funky stuff will also happen if usb_del_udc() is called at the same time as usb_gadget_register_driver(). I think, spin lock should be replaced with a mutex and the all of the operations need to be performed when holding the mutex. Alternatively, mutex can be used in addition to spin lock and then usb_add_udc() could work without locking the mutex. Or, per-UDC mutex needs to be created and registering, unregistering and deleting would be performed while holding this mutex.
+ + device_unregister(udc->dev); + device_unregister(&udc->gadget->dev); +
Useless empty line.
+}
+static void __exit usb_udc_exit(void) +{ + class_destroy(udc_class); + udc_class = NULL; +} +module_exit(usb_udc_exit); +
Useless empty line at end of file.
diff --git a/include/linux/usb/udc.h b/include/linux/usb/udc.h
+#endif /* __LINUX_USB_UDC_H */ +
Same here. -- Best regards, _ _ | Humble Liege of Serenely Enlightened Majesty of o' \,=./ `o | Computer Science, MichaÅ "mina86" Nazarewicz (o o) +----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo-- -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html