
Dear Lukasz Majewski,
USB Composite gadget implementation for u-boot. It builds on top of USB UDC drivers.
This commit is based on following files from Linux Kernel v2.6.36:
./include/linux/usb/composite.h ./drivers/usb/gadget/composite.c
SHA1: d187abb9a83e6c6b6e9f2ca17962bdeafb4bc903
Signed-off-by: Lukasz Majewski l.majewski@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com Cc: Marek Vasut marex@denx.de
Changes for v2:
- Squash the kernel files with u-boot compatibility layer.
- Removal of dead/kernel specific code
- Comments corrected according to u-boot coding style
drivers/usb/gadget/composite.c | 1091 +++++++++++++++++++++++++++++++++++++++ include/linux/usb/composite.h | 350 +++++++++++++ include/usb/lin_gadget_compat.h | 25 +- 3 files changed, 1464 insertions(+), 2 deletions(-) create mode 100644 drivers/usb/gadget/composite.c create mode 100644 include/linux/usb/composite.h
[...]
+int usb_string_ids_n(struct usb_composite_dev *c, unsigned n) +{
- unsigned next = c->next_string_id;
- if (unlikely(n > 254 || (unsigned)next + n > 254))
This unlikely() call is unlikely part of uboot :)
return -ENODEV;
- c->next_string_id += n;
- return next + 1;
+}
+static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) +{
- if (req->status || req->actual != req->length)
debug("%s: setup complete --> %d, %d/%d\n", __func__,
req->status, req->actual, req->length);
+}
+/*
[...]
+static void composite_unbind(struct usb_gadget *gadget) +{
- struct usb_composite_dev *cdev = get_gadget_data(gadget);
- /*
* composite_disconnect() must already have been called
* by the underlying peripheral controller driver!
* so there's no i/o concurrency that could affect the
* state protected by cdev->lock.
*/
- BUG_ON(cdev->config);
Do we have BUG_ON() defined in uboot ?
- while (!list_empty(&cdev->configs)) {
struct usb_configuration *c;
c = list_first_entry(&cdev->configs,
struct usb_configuration, list);
while (!list_empty(&c->functions)) {
struct usb_function *f;
f = list_first_entry(&c->functions,
struct usb_function, list);
list_del(&f->list);
if (f->unbind) {
debug("unbind function '%s'/%p\n",
f->name, f);
f->unbind(c, f);
}
}
list_del(&c->list);
if (c->unbind) {
debug("unbind config '%s'/%p\n", c->label, c);
c->unbind(c);
}
- }
- if (composite->unbind)
composite->unbind(cdev);
- if (cdev->req) {
kfree(cdev->req->buf);
usb_ep_free_request(gadget->ep0, cdev->req);
- }
- kfree(cdev);
- set_gadget_data(gadget, NULL);
- composite = NULL;
+}
+static int composite_bind(struct usb_gadget *gadget) +{
- struct usb_composite_dev *cdev;
- int status = -ENOMEM;
- cdev = calloc(sizeof *cdev, 1);
- if (!cdev)
return status;
- cdev->gadget = gadget;
- set_gadget_data(gadget, cdev);
- INIT_LIST_HEAD(&cdev->configs);
- /* preallocate control response and buffer */
- cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
- if (!cdev->req)
goto fail;
- cdev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL);
- if (!cdev->req->buf)
goto fail;
- cdev->req->complete = composite_setup_complete;
- gadget->ep0->driver_data = cdev;
- cdev->bufsiz = USB_BUFSIZ;
- cdev->driver = composite;
- usb_gadget_set_selfpowered(gadget);
- usb_ep_autoconfig_reset(cdev->gadget);
- status = composite->bind(cdev);
- if (status < 0)
goto fail;
- cdev->desc = *composite->dev;
- cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
- debug("%s: ready\n", composite->name);
- return 0;
+fail:
- composite_unbind(gadget);
- return status;
+}
+static void +composite_suspend(struct usb_gadget *gadget) +{
- struct usb_composite_dev *cdev = get_gadget_data(gadget);
- struct usb_function *f;
- debug("%s: suspend\n", __func__);
- if (cdev->config) {
list_for_each_entry(f, &cdev->config->functions, list) {
if (f->suspend)
f->suspend(f);
}
- }
- if (composite->suspend)
composite->suspend(cdev);
- cdev->suspended = 1;
+}
+static void +composite_resume(struct usb_gadget *gadget) +{
- struct usb_composite_dev *cdev = get_gadget_data(gadget);
- struct usb_function *f;
- debug("%s: resume\n", __func__);
- if (composite->resume)
composite->resume(cdev);
- if (cdev->config) {
list_for_each_entry(f, &cdev->config->functions, list) {
if (f->resume)
f->resume(f);
}
- }
- cdev->suspended = 0;
+}
+static struct usb_gadget_driver composite_driver = {
- .speed = USB_SPEED_HIGH,
- .bind = composite_bind,
- .unbind = composite_unbind,
You have some weird indent in here?
- .setup = composite_setup,
- .disconnect = composite_disconnect,
- .suspend = composite_suspend,
- .resume = composite_resume,
+};
I think this patch is getting much better ;-)