Makes the code a little bit better and adds some functions to
        the Composite Framework.

Signed-off-by: Felipe Balbi <[EMAIL PROTECTED]>
Signed-off-by: Ragner Magalhaes <[EMAIL PROTECTED]>
---

Index: linux-omap-2.6-ragner/drivers/usb/gadget/composite.c
===================================================================
--- linux-omap-2.6-ragner.orig/drivers/usb/gadget/composite.c
+++ linux-omap-2.6-ragner/drivers/usb/gadget/composite.c
@@ -1,3 +1,3 @@
 #define DEBUG 1
-// #define VERBOSE
+#define VERBOSE 1
 
@@ -24,2 +24,3 @@
 #include <linux/usb_ch9.h>
+#include <linux/usb/cdc.h>
 #include <linux/usb_gadget.h>
@@ -27,2 +28,3 @@
 
+#include "gadget_chips.h"
 
@@ -54,8 +56,11 @@
 /*-------------------------------------------------------------------------*/
+#define COMPOSITE_VERSION_NUM  0x0202
+#define COMPOSITE_NAME         "composite"
+/* For file storage */
+#define DELAYED_STATUS         (COMPOSITE_BUFSIZ + 999)
 
-/* big enough to hold our biggest descriptor */
-#define USB_BUFSIZ     512
-
+static const char shortname []         = COMPOSITE_NAME;
 
 static struct usb_composite_driver     *composite;
+static struct usb_gadget_driver        composite_driver;
 
@@ -94,3 +99,3 @@ config_buf(struct usb_composite_dev *cde
        void                            *next = buf + USB_DT_CONFIG_SIZE;
-       int                             len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+       int                             len = COMPOSITE_BUFSIZ - 
USB_DT_CONFIG_SIZE;
        int                             hs;
@@ -139,2 +144,3 @@ static void composite_reset_config(
 ) {
+       struct usb_gadget               *gadget = cdev->gadget;
        struct usb_function             *f;
@@ -148,3 +154,4 @@ static void composite_reset_config(
        list_for_each_entry (f, &composite->functions, function) {
-               result = f->setup(cdev, req);
+               cdev->current_func = f;
+               result = f->setup(gadget, req);
                if (result < 0)
@@ -159,5 +166,6 @@ composite_set_config(struct usb_composit
 {
-       int                     result = 0, tmp;
+       int                     result = 0;
        struct usb_gadget       *gadget = cdev->gadget;
        struct usb_ctrlrequest  req;
+       struct usb_function     *f;
 
@@ -181,18 +189,12 @@ composite_set_config(struct usb_composit
                                | USB_TYPE_STANDARD
-                               | USB_RECIP_INTERFACE;
-               req.bRequest = USB_REQ_SET_INTERFACE;
-
-               for (tmp = 0; tmp < MAX_COMPOSITE_INTERFACES; tmp++) {
-                       struct usb_function     *f = cdev->interface[tmp];
+                               | USB_RECIP_DEVICE;
+               req.bRequest    = USB_REQ_SET_CONFIGURATION;
+               req.wValue      = COMPOSITE_CONFIG_VALUE;
 
-                       if (!f)
-                               continue;
-                       req.wIndex = cpu_to_le16(tmp);
-                       result = f->setup(cdev, &req);
-                       if (result < 0) {
-                               DBG(cdev, "interface %d/%s alt 0--> %d\n",
-                                               tmp, f->name, result);
-                               (void) composite_set_config(cdev, 0);
-                               return result;
-                       }
+               list_for_each_entry (f, &composite->functions, function) {
+                       cdev->current_func = f;
+                       result = f->setup(gadget, &req);
+                       if (result < 0)
+                               DBG(cdev, "set function configuration %s --> 
%d\n",
+                                       f->name, result);
                }
@@ -219,3 +221,3 @@ composite_set_config(struct usb_composit
 static void
-composite_collect_langs(const struct usb_gadget_strings **sp, __le16 *buf)
+composite_collect_langs(struct usb_gadget_strings *sp, __le16 *buf)
 {
@@ -225,4 +227,4 @@ composite_collect_langs(const struct usb
 
-       while (*sp) {
-               s = *sp;
+       if (sp) {
+               s = sp;
                language = cpu_to_le16(s->language);
@@ -230,7 +232,5 @@ composite_collect_langs(const struct usb
                        if (*tmp == language)
-                               goto repeat;
+                               return;
                }
                *tmp++ = language;
-repeat:
-               sp++;
        }
@@ -239,3 +239,3 @@ repeat:
 static int composite_check_string(
-       const struct usb_gadget_strings **sp,
+       struct usb_gadget_strings *sp,
        void                            *buf,
@@ -245,9 +245,9 @@ static int composite_check_string(
 {
-       const struct usb_gadget_strings *s;
+       struct usb_gadget_strings *s;
        int                             value;
 
-       while (*sp) {
-               s = *sp++;
+       if (sp) {
+               s = sp;
                if (s->language != language)
-                       continue;
+                       return -EINVAL;
                value = usb_gadget_get_string(s, id, buf);
@@ -267,5 +267,5 @@ static int composite_lookup_string(void 
                struct usb_string_descriptor    *s = buf;
-               const struct usb_gadget_strings **sp;
+               struct usb_gadget_strings *sp;
 
-               memset(s, 0, 256);
+               memset(s, 0, COMPOSITE_BUFSIZ);
                s->bDescriptorType = USB_DT_STRING;
@@ -318,11 +318,5 @@ static void composite_setup_complete(str
 
-/*
- * The setup() callback implements all the ep0 functionality that's
- * not handled lower down, in hardware or the hardware driver(like
- * device and endpoint feature flags, and their status).  It's all
- * housekeeping for the gadget function we're implementing.  Most of
- * the work is in config-specific setup.
- */
+
 static int
-composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
+composite_setup_standard(struct usb_gadget *gadget, const struct 
usb_ctrlrequest *ctrl)
 {
@@ -334,4 +328,2 @@ composite_setup(struct usb_gadget *gadge
        u16                             w_length = le16_to_cpu(ctrl->wLength);
-
-       req->zero = 0;
        switch (ctrl->bRequest) {
@@ -339,2 +331,3 @@ composite_setup(struct usb_gadget *gadge
        case USB_REQ_GET_DESCRIPTOR:
+               VDBG(cdev, "Get descriptor control req=%d \n", w_value >> 8);
                if (ctrl->bRequestType != USB_DIR_IN)
@@ -344,2 +337,3 @@ composite_setup(struct usb_gadget *gadge
                case USB_DT_DEVICE:
+                       VDBG(cdev, "Get descriptor device\n");
                        value = min(w_length, (u16) sizeof cdev->dev);
@@ -347,3 +341,5 @@ composite_setup(struct usb_gadget *gadge
                        break;
+#ifdef CONFIG_USB_GADGET_DUALSPEED
                case USB_DT_DEVICE_QUALIFIER:
+                       VDBG(cdev, "Get descriptor qualifier\n");
                        if (!is_dualspeed(gadget))
@@ -355,2 +351,3 @@ composite_setup(struct usb_gadget *gadge
                case USB_DT_OTHER_SPEED_CONFIG:
+                       VDBG(cdev, "Get descriptor speed config\n");
                        if (!is_dualspeed(gadget))
@@ -359,3 +356,9 @@ composite_setup(struct usb_gadget *gadge
 
+                       goto get_config;
+#endif
                case USB_DT_CONFIG:
+                       VDBG(cdev, "Get descriptor config\n");
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+                       get_config:
+#endif
                        /* one config ... so it must always be index 0 */
@@ -369,2 +372,4 @@ composite_setup(struct usb_gadget *gadge
                case USB_DT_STRING:
+                       VDBG(cdev, "Get descriptor string lang=%x id=%d\n",
+                                       w_index, w_value & 0xff);
                        value = composite_lookup_string(req->buf, w_index,
@@ -379,2 +384,3 @@ composite_setup(struct usb_gadget *gadge
        case USB_REQ_SET_CONFIGURATION:
+               VDBG(cdev, "Set configuration control req=%d\n", w_value);
                if (ctrl->bRequestType != 0)
@@ -392,2 +398,3 @@ composite_setup(struct usb_gadget *gadge
        case USB_REQ_GET_CONFIGURATION:
+               VDBG(cdev, "Get configuration control req\n");
                if (ctrl->bRequestType != USB_DIR_IN)
@@ -400,2 +407,3 @@ composite_setup(struct usb_gadget *gadge
        case USB_REQ_SET_INTERFACE:
+               VDBG(cdev, "Set interface control req=%d\n", w_index);
                if (ctrl->bRequestType != USB_RECIP_INTERFACE)
@@ -407,3 +415,4 @@ composite_setup(struct usb_gadget *gadge
                spin_lock(&cdev->lock);
-               value = cdev->interface[w_index]->setup(cdev, ctrl);
+               cdev->current_func = cdev->interface[w_index];
+               value = cdev->current_func->setup(gadget, ctrl);
                spin_unlock(&cdev->lock);
@@ -411,2 +420,3 @@ composite_setup(struct usb_gadget *gadge
        case USB_REQ_GET_INTERFACE:
+               VDBG(cdev, "Get interface control req=%d\n", w_index);
                if (ctrl->bRequestType !=(USB_DIR_IN|USB_RECIP_INTERFACE))
@@ -419,3 +429,4 @@ composite_setup(struct usb_gadget *gadge
                /* function must set cdev->req->buf[0] */
-               value = cdev->interface[w_index]->setup(cdev, ctrl);
+               cdev->current_func = cdev->interface[w_index];
+               value = cdev->current_func->setup(gadget, ctrl);
                spin_unlock(&cdev->lock);
@@ -425,3 +436,57 @@ composite_setup(struct usb_gadget *gadge
 unknown:
-               VDBG(dev,
+               VDBG(cdev,
+                       "unknown control req%02x.%02x v%04x i%04x l%d\n",
+                       ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+       }
+       return value;
+}
+static int
+composite_setup_class(struct usb_gadget *gadget,
+               const struct usb_ctrlrequest *ctrl)
+{
+       struct usb_composite_dev        *cdev = get_gadget_data(gadget);
+       int                             value = -EOPNOTSUPP;
+       u16                             w_index = le16_to_cpu(ctrl->wIndex);
+
+       if (w_index >= MAX_COMPOSITE_INTERFACES ||
+                       !cdev->interface[w_index])
+               return value;
+
+       spin_lock(&cdev->lock);
+       /* function must set cdev->req->buf[0] */
+       cdev->current_func = cdev->interface[w_index];
+       value = cdev->current_func->setup(gadget, ctrl);
+       spin_unlock(&cdev->lock);
+       return value;
+}
+
+
+/*
+ * The setup() callback implements all the ep0 functionality that's
+ * not handled lower down, in hardware or the hardware driver(like
+ * device and endpoint feature flags, and their status). It's all
+ * housekeeping for the gadget function we're implementing. Most of
+ * the work is in config-specific setup.
+ */
+static int
+composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
+{
+       struct usb_composite_dev        *cdev = get_gadget_data(gadget);
+       struct usb_request              *req = cdev->req;
+       int                             value = -EOPNOTSUPP;
+       u16                             w_index = le16_to_cpu(ctrl->wIndex);
+       u16                             w_value = le16_to_cpu(ctrl->wValue);
+       u16                             w_length = le16_to_cpu(ctrl->wLength);
+
+       req->zero = 0;
+       switch (ctrl->bRequestType & USB_TYPE_MASK) {
+       case USB_TYPE_STANDARD:
+               value = composite_setup_standard(gadget, ctrl);
+               break;
+       case USB_TYPE_CLASS:
+               value = composite_setup_class(gadget, ctrl);
+               break;
+       default:
+               VDBG(cdev,
                        "unknown control req%02x.%02x v%04x i%04x l%d\n",
@@ -432,3 +497,3 @@ unknown:
        /* respond with data transfer before status phase? */
-       if (value >= 0) {
+       if (value >= 0 && value != DELAYED_STATUS) {
                req->length = value;
@@ -474,5 +539,6 @@ composite_unbind(struct usb_gadget *gadg
        list_for_each_entry (f, &cdev->driver->functions, function) {
+               cdev->current_func = f;
                if (f->unbind)
-                       f->unbind(cdev);
-               if (f == cdev->current_bind)
+                       f->unbind(gadget);
+               if (f == cdev->current_func)
                        break;
@@ -495,4 +561,5 @@ composite_bind(struct usb_gadget *gadget
        int                             status = -ENOMEM;
+       int                             gcnum;
 
-       cdev = kzalloc(sizeof *cdev, SLAB_KERNEL);
+       cdev = kzalloc(sizeof *cdev, GFP_KERNEL);
        if (!cdev)
@@ -508,3 +575,3 @@ composite_bind(struct usb_gadget *gadget
                goto fail;
-       cdev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL);
+       cdev->req->buf = kmalloc(COMPOSITE_BUFSIZ, GFP_KERNEL);
        if (!cdev->req->buf)
@@ -521,2 +588,6 @@ composite_bind(struct usb_gadget *gadget
 
+       /* before composite->bind() */
+       cdev->next_string_id = 0;
+       cdev->next_interface_id = 0;
+
        /* mostly to assign strings for whole device, like serial number,
@@ -530,2 +601,16 @@ composite_bind(struct usb_gadget *gadget
 
+       gcnum = usb_gadget_controller_number(gadget);
+       /* FIXME */
+       if (gcnum >= 0)
+               cdev->dev.bcdDevice =
+                               cpu_to_le16(COMPOSITE_VERSION_NUM | gcnum);
+       else {
+               DBG(cdev, "composite_bind: controller '%s' not"
+                               " recognized\n",        gadget->name);
+               /* unrecognized, but safe unless bulk is REALLY quirky */
+               cdev->dev.bcdDevice =
+                       __constant_cpu_to_le16(COMPOSITE_VERSION_NUM|0x0099);
+       }
+
+
        /* function binding involves updating interface, class, and
@@ -543,4 +628,4 @@ composite_bind(struct usb_gadget *gadget
        list_for_each_entry (f, &cdev->driver->functions, function) {
-               cdev->current_bind = f;
-               status = f->bind(cdev);
+               cdev->current_func = f;
+               status = f->bind(gadget);
                if (status < 0)
@@ -554,3 +639,3 @@ composite_bind(struct usb_gadget *gadget
        }
-       cdev->current_bind = NULL;
+       cdev->current_func = NULL;
        cdev->config.bNumInterfaces = cdev->next_interface_id;
@@ -584,19 +669,228 @@ fail:
 
+/* Return function descriptor header from the current function.
+ */
+static struct usb_descriptor_header **get_func_descriptors(
+       struct usb_composite_dev *cdev)
+{
+       struct usb_function             *f = cdev->current_func;
+
+       if (!f || !f->descriptors)
+               return NULL;
+       if (is_dualspeed(cdev->gadget) &&
+               (cdev->gadget->speed == USB_SPEED_HIGH))
+               return f->hs_descriptors;
+
+       return f->descriptors;
+}
+
+static struct usb_string *get_func_strings(struct usb_composite_dev *cdev)
+{
+       return cdev->current_func->strings->strings;
+}
+
+static void
+set_interface_str_id(struct usb_composite_dev *cdev,
+       struct usb_interface_descriptor *interf_desc)
+{
+       interf_desc->iInterface += cdev->current_func->string_id_shift;
+}
+
+static void
+set_cs_interface_str_id(struct usb_composite_dev *cdev,
+       struct usb_cdc_header_desc *cdc_desc)
+{
+       struct usb_cdc_ether_desc       *ether_desc;
+
+       switch (cdc_desc->bDescriptorSubType) {
+       case USB_CDC_ETHERNET_TYPE:
+               ether_desc = (struct usb_cdc_ether_desc *) cdc_desc;
+               ether_desc->iMACAddress += cdev->current_func->string_id_shift;
+               break;
+       }
+}
+
+/* FIXME
+ * Set the string id for each string in the current
+ * func referenced by current_func
+ */
 int usb_composite_string_id(struct usb_composite_dev *cdev)
 {
-       if (cdev->current_bind && cdev->next_string_id < 255)
-               return cdev->next_string_id++;
-       return -ENODEV;
+       struct usb_string               *str_src = get_func_strings(cdev);
+       struct usb_descriptor_header    **src;
+       int                             status = 0;
+
+       if (!cdev->current_func && cdev->next_string_id >= 255) {
+               return -ENODEV;
+       }
+
+       cdev->current_func->string_id_shift = cdev->next_string_id;
+       src = get_func_descriptors(cdev);
+
+       if (src == NULL) {
+               ERROR(cdev, "Invalid descriptors header.\n");
+               return -EINVAL;
+       }
+
+       for (; str_src && str_src->s ; str_src++) {
+               (str_src)->id += cdev->current_func->string_id_shift;
+               if ((str_src)->id > cdev->next_string_id)
+                       cdev->next_string_id = (str_src)->id;
+       }
+
+       for (; 0 != *src; src++) {
+               switch ((*src)->bDescriptorType) {
+               case USB_DT_INTERFACE:
+                       set_interface_str_id(cdev,
+                                       container_of(&((*src)->bLength),
+                                       struct usb_interface_descriptor,
+                                       bLength));
+                       break;
+               case USB_DT_CS_INTERFACE:
+                       set_cs_interface_str_id(cdev,
+                                       container_of(&((*src)->bLength),
+                                       struct usb_cdc_header_desc,
+                                       bLength));
+                       break;
+               case USB_DT_DEVICE:
+                       break;
+               }
+       }
+       return status;
 }
 
+/* Set the new interface number for the gadget interface in
+ * Composite Device.
+ */
+static int
+set_interface_number(struct usb_composite_dev *cdev,
+       struct usb_interface_descriptor *interf_desc)
+{
+       /* set the new interface number for the gadget in composite device.*/
+       interf_desc->bInterfaceNumber += cdev->current_func->interface_shift;
+
+       if ((cdev->next_interface_id - interf_desc->bInterfaceNumber) < 0) {
+               ERROR(cdev, "Invalid interface number.\n" );
+               return -EINVAL;
+       }
+
+       if (cdev->next_interface_id >= MAX_COMPOSITE_INTERFACES) {
+               ERROR(cdev, "Max composite interfaces number reached.\n" );
+               return -EINVAL;
+       }
+
+       cdev->interface[cdev->next_interface_id] = cdev->current_func;
+       cdev->next_interface_id = interf_desc->bInterfaceNumber + 1;
+
+       return 0;
+}
+
+static int
+set_cs_interface_number(struct usb_composite_dev *cdev,
+       struct usb_cdc_header_desc *cdc_desc)
+{
+       struct usb_cdc_union_desc               *union_desc;
+       struct usb_cdc_call_mgmt_descriptor     *mgmt_desc;
+
+       switch (cdc_desc->bDescriptorSubType) {
+       case USB_CDC_UNION_TYPE:
+               union_desc = (struct usb_cdc_union_desc *) cdc_desc;
+               union_desc->bMasterInterface0   +=
+                                       cdev->current_func->interface_shift;
+               union_desc->bSlaveInterface0    +=
+                                       cdev->current_func->interface_shift;
+               break;
+       case USB_CDC_CALL_MANAGEMENT_TYPE:
+               mgmt_desc = (struct usb_cdc_call_mgmt_descriptor *) cdc_desc;
+               mgmt_desc->bDataInterface       +=
+                                       cdev->current_func->interface_shift;
+               break;
+       }
+
+       return 0;
+}
+
+/* Set the interface id for each interface in the current
+ * func referenced by current_func in cdev.
+ */
 int usb_composite_interface_id(struct usb_composite_dev *cdev)
 {
-       if (cdev->next_interface_id < MAX_COMPOSITE_INTERFACES
-                       && cdev->current_bind) {
-               cdev->interface[cdev->next_interface_id] = cdev->current_bind;
-               return cdev->next_interface_id++;
+       struct usb_descriptor_header    **src;
+       int                             status = 0;
+
+       if (!cdev->current_func ||
+                       cdev->next_interface_id >= MAX_COMPOSITE_INTERFACES ) {
+               ERROR(cdev, "Invalid func or max composite interfaces number"
+                                                               " reached.\n");
+               return -EINVAL;
+       }
+
+       /* Shift of the gadget interface number for composite device*/
+       cdev->current_func->interface_shift = cdev->next_interface_id;
+
+       src = get_func_descriptors(cdev);
+       if (src == NULL) {
+               ERROR(cdev, "Invalid descriptors header.\n");
+               return -EINVAL;
+       }
+
+       for (; 0 != *src; src++) {
+               switch ((*src)->bDescriptorType) {
+               case USB_DT_INTERFACE:
+                       status = set_interface_number(cdev,
+                                       container_of(&((*src)->bLength),
+                                       struct usb_interface_descriptor,
+                                       bLength));
+                       break;
+               case USB_DT_CS_INTERFACE:
+                       status = set_cs_interface_number(cdev,
+                                       container_of(&((*src)->bLength),
+                                       struct usb_cdc_header_desc,
+                                       bLength));
+                       break;
+               }
+       }
+
+       return status;
+}
+
+int usb_composite_reset_interface(struct usb_composite_dev *cdev)
+{
+       struct usb_descriptor_header    **src;
+       int                             status = 0;
+
+       if (!cdev->current_func) {
+               ERROR(cdev, "Invalid current func.\n");
+               return -EINVAL;
        }
-       return -ENODEV;
+
+       /* back the orig interface number for composite device*/
+       cdev->current_func->interface_shift *= -1;
+
+       src = get_func_descriptors(cdev);
+       if (src == NULL) {
+               ERROR(cdev, "Invalid descriptors header.\n");
+               return -EINVAL;
+       }
+
+       for (; 0 != *src; src++) {
+               switch ((*src)->bDescriptorType) {
+               case USB_DT_INTERFACE:
+                       status = set_interface_number(cdev,
+                                       container_of(&((*src)->bLength),
+                                       struct usb_interface_descriptor,
+                                       bLength));
+                       break;
+               case USB_DT_CS_INTERFACE:
+                       status = set_cs_interface_number(cdev,
+                                       container_of(&((*src)->bLength),
+                                       struct usb_cdc_header_desc,
+                                       bLength));
+                       break;
+               }
+       }
+
+       return status;
 }
 
+
 /*-------------------------------------------------------------------------*/
@@ -612,5 +906,6 @@ composite_suspend(struct usb_gadget *gad
        list_for_each_entry (f, &cdev->driver->functions, function) {
+               cdev->current_func = f;
                if (!f->suspend)
                        continue;
-               f->suspend(cdev);
+               f->suspend(gadget);
        }
@@ -627,5 +922,6 @@ composite_resume(struct usb_gadget *gadg
        list_for_each_entry (f, &cdev->driver->functions, function) {
+                       cdev->current_func = f;
                if (!f->resume)
                        continue;
-               f->resume(cdev);
+               f->resume(gadget);
        }
@@ -650,2 +946,3 @@ static struct usb_gadget_driver composit
                .owner          = THIS_MODULE,
+               .name           = (char *) shortname,
        },
@@ -672,3 +969,3 @@ int usb_composite_register(struct usb_co
        if (!d->name)
-               d->name = "composite";
+               d->name = shortname;
        composite_driver.function =  (char *) d->name;
@@ -679 +976,5 @@ int usb_composite_register(struct usb_co
 }
+void __exit usb_composite_unregister(struct usb_composite_driver *d)
+{
+       usb_gadget_unregister_driver(&composite_driver);
+}
Index: linux-omap-2.6-ragner/drivers/usb/gadget/config.c
===================================================================
--- linux-omap-2.6-ragner.orig/drivers/usb/gadget/config.c
+++ linux-omap-2.6-ragner/drivers/usb/gadget/config.c
@@ -44,3 +44,3 @@ int
 usb_descriptor_fillbuf(void *buf, unsigned buflen,
-               const struct usb_descriptor_header **src)
+               struct usb_descriptor_header **src)
 {
@@ -89,3 +89,3 @@ int usb_gadget_config_buf(
        unsigned                                length,
-       const struct usb_descriptor_header      **desc
+       struct usb_descriptor_header            **desc
 )
Index: linux-omap-2.6-ragner/include/linux/usb/composite.h
===================================================================
--- linux-omap-2.6-ragner.orig/include/linux/usb/composite.h
+++ linux-omap-2.6-ragner/include/linux/usb/composite.h
@@ -7,2 +7,10 @@
 
+#if    defined(CONFIG_USB_COMPOSITE) || defined(CONFIG_USB_COMPOSITE_MODULE)
+/* defines shared with gadgets */
+#define USB_COMPOSITE_DEVICE
+#define COMPOSITE_CONFIG_VALUE 3
+/* big enough to hold our biggest descriptor */
+#define COMPOSITE_BUFSIZ       256
+#endif
+
 /* Support for composite gadgets, built from distinct function drivers.
@@ -42,5 +50,5 @@ struct usb_function {
        const char                              *name;
-       const struct usb_gadget_strings         **strings;
-       const struct usb_descriptor_header      **descriptors;
-       const struct usb_descriptor_header      **hs_descriptors;
+       struct usb_gadget_strings               *strings;
+       struct usb_descriptor_header            **descriptors;
+       struct usb_descriptor_header            **hs_descriptors;
 
@@ -48,2 +56,8 @@ struct usb_function {
 
+       /* data private to the driver */
+       void                    *driver_data;
+
+       u8                      interface_shift;
+       u8                      string_id_shift;
+
        /* REVISIT want multi-config at *same* speed too ...
@@ -53,9 +67,9 @@ struct usb_function {
 
-       int                     (*bind)(struct usb_composite_dev *);
-       void                    (*unbind)(struct usb_composite_dev *);
-       int                     (*setup)(struct usb_composite_dev *,
+       int                     (*bind)(struct usb_gadget *);
+       void                    (*unbind)(struct usb_gadget *);
+       int                     (*setup)(struct usb_gadget *,
                                        const struct usb_ctrlrequest *);
-       void                    (*disconnect)(struct usb_composite_dev *);
-       void                    (*suspend)(struct usb_composite_dev *);
-       void                    (*resume)(struct usb_composite_dev *);
+       void                    (*disconnect)(struct usb_gadget *);
+       void                    (*suspend)(struct usb_gadget *);
+       void                    (*resume)(struct usb_gadget *);
 };
@@ -79,3 +93,3 @@ struct usb_composite_driver {
        const struct usb_device_descriptor      *dev;
-       const struct usb_gadget_strings         **strings;
+       struct usb_gadget_strings               *strings;
 
@@ -91,4 +105,2 @@ struct usb_composite_driver {
                                        const struct usb_ctrlrequest *);
-
-       /* REVISIT disconnect(), suspend(), resume() too ?? */
 };
@@ -97,2 +109,6 @@ extern int usb_composite_register(struct
 
+extern void usb_composite_unregister(struct usb_composite_driver *);
+extern int usb_function_register(struct usb_function *);
+extern void usb_function_unregister(struct usb_function *);
+extern int usb_composite_ep_reset (struct usb_ep *);
 
@@ -123,3 +139,3 @@ struct usb_composite_dev {
        u8                      next_interface_id;
-       struct usb_function     *current_bind;
+       struct usb_function     *current_func;
        struct usb_function     *interface[MAX_COMPOSITE_INTERFACES];
@@ -133,2 +149,8 @@ extern int usb_composite_string_id(struc
 extern int usb_composite_interface_id(struct usb_composite_dev *c);
+extern int usb_composite_reset_interface(struct usb_composite_dev *c);
+
+static inline void set_composite_data (struct usb_composite_dev *cdev, void 
*data)
+       { cdev->current_func->driver_data = data; }
+static inline void *get_composite_data (struct usb_composite_dev *cdev)
+       { return cdev->current_func->driver_data; }
 
Index: linux-omap-2.6-ragner/include/linux/usb_gadget.h
===================================================================
--- linux-omap-2.6-ragner.orig/include/linux/usb_gadget.h
+++ linux-omap-2.6-ragner/include/linux/usb_gadget.h
@@ -863,3 +863,3 @@ int usb_gadget_get_string(const struct u
 int usb_descriptor_fillbuf(void *, unsigned,
-               const struct usb_descriptor_header **);
+               struct usb_descriptor_header **);
 
@@ -867,3 +867,3 @@ int usb_descriptor_fillbuf(void *, unsig
 int usb_gadget_config_buf(const struct usb_config_descriptor *config,
-       void *buf, unsigned buflen, const struct usb_descriptor_header **desc);
+       void *buf, unsigned buflen, struct usb_descriptor_header **desc);
 

--
Best Regards,

Felipe Balbi
[EMAIL PROTECTED]

Nokia Institute of Technology - INdT
Kernel Developers Team

+55 92 2126 1003


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to