[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-19 Thread Ragner Magalhaes
From: Ragner Magalhaes [EMAIL PROTECTED]

Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]
---

 drivers/usb/gadget/composite.c |  679 
 drivers/usb/gadget/usbstring.c |2 
 include/linux/usb/composite.h  |  137 
 include/linux/usb_gadget.h |2 
 4 files changed, 818 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  

[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-04 Thread Ragner Magalhaes
Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]

:00 100644 000... 495c660... A  drivers/usb/gadget/composite.c
:100644 100644 3459ea6... 9de6f2e... M  drivers/usb/gadget/usbstring.c
:00 100644 000... 82fdb13... A  include/linux/usb/composite.h
:100644 100644 e17186d... f1c9b73... M  include/linux/usb_gadget.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  *req
+) {
+   struct 

[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-04 Thread Ragner Magalhaes
Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]

:00 100644 000... 495c660... A  drivers/usb/gadget/composite.c
:100644 100644 3459ea6... 9de6f2e... M  drivers/usb/gadget/usbstring.c
:00 100644 000... 82fdb13... A  include/linux/usb/composite.h
:100644 100644 e17186d... f1c9b73... M  include/linux/usb_gadget.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  *req
+) {
+   struct 

[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-04 Thread Ragner Magalhaes
Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]

:00 100644 000... 495c660... A  drivers/usb/gadget/composite.c
:100644 100644 3459ea6... 9de6f2e... M  drivers/usb/gadget/usbstring.c
:00 100644 000... 82fdb13... A  include/linux/usb/composite.h
:100644 100644 e17186d... f1c9b73... M  include/linux/usb_gadget.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  *req
+) {
+   struct 

[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-04 Thread Ragner Magalhaes
Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]

:00 100644 000... 495c660... A  drivers/usb/gadget/composite.c
:100644 100644 3459ea6... 9de6f2e... M  drivers/usb/gadget/usbstring.c
:00 100644 000... 82fdb13... A  include/linux/usb/composite.h
:100644 100644 e17186d... f1c9b73... M  include/linux/usb_gadget.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  *req
+) {
+   struct 

[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-04 Thread Ragner Magalhaes
Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]

:00 100644 000... 495c660... A  drivers/usb/gadget/composite.c
:100644 100644 3459ea6... 9de6f2e... M  drivers/usb/gadget/usbstring.c
:00 100644 000... 82fdb13... A  include/linux/usb/composite.h
:100644 100644 e17186d... f1c9b73... M  include/linux/usb_gadget.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  *req
+) {
+   struct 

[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-04 Thread Ragner Magalhaes
Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]

:00 100644 000... 495c660... A  drivers/usb/gadget/composite.c
:100644 100644 3459ea6... 9de6f2e... M  drivers/usb/gadget/usbstring.c
:00 100644 000... 82fdb13... A  include/linux/usb/composite.h
:100644 100644 e17186d... f1c9b73... M  include/linux/usb_gadget.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  *req
+) {
+   struct 

[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-04 Thread Ragner Magalhaes
Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]

:00 100644 000... 495c660... A  drivers/usb/gadget/composite.c
:100644 100644 3459ea6... 9de6f2e... M  drivers/usb/gadget/usbstring.c
:00 100644 000... 82fdb13... A  include/linux/usb/composite.h
:100644 100644 e17186d... f1c9b73... M  include/linux/usb_gadget.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  *req
+) {
+   struct 

[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-04 Thread Ragner Magalhaes
Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]

:00 100644 000... 495c660... A  drivers/usb/gadget/composite.c
:100644 100644 3459ea6... 9de6f2e... M  drivers/usb/gadget/usbstring.c
:00 100644 000... 82fdb13... A  include/linux/usb/composite.h
:100644 100644 e17186d... f1c9b73... M  include/linux/usb_gadget.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  *req
+) {
+   struct 

[linux-usb-devel] [PATCH 2/6] Composite gadget driver

2007-05-04 Thread Ragner Magalhaes
Add linux/usb/composite.h interfaces for composite gadget drivers:

-   struct usb_function ... grouping one or more interfaces into
a function that will often be managed as one unit;

-   struct usb_composite_driver ... grouping one or more such
functions into a gadget driver.

-   struct usb_composite_dev ... what's managed by the composite
driver.

There's an implementation library behind the composite_driver which
exposes the composite_dev.

Separate patches will be updating some gadget drivers to use this
new interface.


Signed-off-by: David Brownell [EMAIL PROTECTED]

:00 100644 000... 495c660... A  drivers/usb/gadget/composite.c
:100644 100644 3459ea6... 9de6f2e... M  drivers/usb/gadget/usbstring.c
:00 100644 000... 82fdb13... A  include/linux/usb/composite.h
:100644 100644 e17186d... f1c9b73... M  include/linux/usb_gadget.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644
index 000..495c660
--- /dev/null
+++ b/drivers/usb/gadget/composite.c
@@ -0,0 +1,679 @@
+#define DEBUG 1
+// #define VERBOSE
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/ioport.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/smp_lock.h
+#include linux/errno.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/list.h
+#include linux/interrupt.h
+#include linux/utsname.h
+#include linux/device.h
+#include linux/moduleparam.h
+
+#include asm/byteorder.h
+#include asm/system.h
+#include asm/unaligned.h
+
+#include linux/usb_ch9.h
+#include linux/usb_gadget.h
+#include linux/usb/composite.h
+
+
+#define xprintk(d,level,fmt,args...) \
+   dev_printk(level , (d)-gadget-dev , fmt , ## args)
+
+#ifdef DEBUG
+#define DBG(dev,fmt,args...) \
+   xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDBG   DBG
+#else
+#define VDBG(dev,fmt,args...) \
+   do { } while(0)
+#endif /* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+   xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+   xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+   xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 512
+
+
+static struct usb_composite_driver *composite;
+
+static inline int is_dualspeed(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+   return g-is_dualspeed;
+#else
+   return 0;
+#endif
+}
+
+static inline int is_otg(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+   return g-is_otg;
+#else
+   return 0;
+#endif
+}
+
+/*-*/
+
+/* To simplify, we expect to have only ONE real configuration, working the
+ * same no matter what speed it connects with.  A given function may expose
+ * multiple interfaces.  Each interface includes its descriptor, plus optional
+ * class and endpoint descriptors (as usual).
+ */
+
+#defineCONFIG_NUMBER   1
+
+static int
+config_buf(struct usb_composite_dev *cdev, void *buf, u8 type)
+{
+   struct usb_config_descriptor*c = buf;
+   void*next = buf + USB_DT_CONFIG_SIZE;
+   int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+   int hs;
+   struct usb_function *f;
+
+   if (is_dualspeed(cdev-gadget)) {
+   hs = (cdev-gadget-speed == USB_SPEED_HIGH);
+   if (type == USB_DT_OTHER_SPEED_CONFIG)
+   hs = !hs;
+   } else
+   hs = 0;
+
+   /* write a config descriptor */
+   *c = cdev-config;
+   c-bLength = USB_DT_CONFIG_SIZE;
+   c-bDescriptorType = type;
+   c-bConfigurationValue = CONFIG_NUMBER;
+
+   /* REVISIT some configurations might need other descriptors,
+* independent of the interfaces they implement ... notably
+* OTG descriptors.
+*/
+
+   /* add each function's descriptors */
+   list_for_each_entry (f, composite-functions, function) {
+   int status;
+
+   status = usb_descriptor_fillbuf(next, len,
+   hs ? f-hs_descriptors : f-descriptors);
+   if (status  0)
+   return status;
+   len -= status;
+   next += status;
+   }
+
+   len = next - buf;
+   c-wTotalLength = cpu_to_le16(len);
+   return len;
+}
+
+/*-*/
+
+static void composite_reset_config(
+   struct usb_composite_dev*cdev,
+   struct usb_ctrlrequest  *req
+) {
+   struct