[patch 3/8] PATCH Modifications on David Brownells patch.

Felipe Balbi <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
patch-composite-device-db02.diff (text/plain, 23.1 KB)
	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
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.