[PATCH] g_serial modification for it to become a USB_FUNCTION.
Signed-off-by: Felipe Balbi <[EMAIL PROTECTED]>
Signed-off-by: Ragner Magalhaes <[EMAIL PROTECTED]>
---
Index: 2.6-dev/drivers/usb/gadget/serial.c
===================================================================
--- 2.6-dev.orig/drivers/usb/gadget/serial.c 2007-01-29
11:44:59.000000000 -0400
+++ 2.6-dev/drivers/usb/gadget/serial.c 2007-01-29 11:45:11.000000000
-0400
@@ -45,6 +45,7 @@
#include <linux/usb_ch9.h>
#include <linux/usb/cdc.h>
+#include <linux/usb/composite.h>
#include <linux/usb_gadget.h>
#include "gadget_chips.h"
@@ -66,7 +67,12 @@
#define GS_NUM_CONFIGS 1
#define GS_NO_CONFIG_ID 0
#define GS_BULK_CONFIG_ID 1
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+#define COMPOSITE_CONFIG_VALUE 3 /* composite config */
+#define GS_ACM_CONFIG_ID COMPOSITE_CONFIG_VALUE
+#else
#define GS_ACM_CONFIG_ID 2
+#endif
#define GS_MAX_NUM_INTERFACES 2
#define GS_BULK_INTERFACE_ID 0
@@ -97,6 +103,8 @@
#define GS_SPEED_SELECT(is_hs,hs,fs) (fs)
#endif /* CONFIG_USB_GADGET_DUALSPEED */
+#define GS_DEBUG 1
+
/* debug settings */
#ifdef GS_DEBUG
static int debug = 1;
@@ -189,7 +197,7 @@
/* tty driver */
static int gs_open(struct tty_struct *tty, struct file *file);
static void gs_close(struct tty_struct *tty, struct file *file);
-static int gs_write(struct tty_struct *tty,
+static int gs_write(struct tty_struct *tty,
const unsigned char *buf, int count);
static void gs_put_char(struct tty_struct *tty, unsigned char ch);
static void gs_flush_chars(struct tty_struct *tty);
@@ -211,6 +219,16 @@
static void gs_write_complete(struct usb_ep *ep, struct usb_request
*req);
/* gadget driver */
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+static int gs_bind(struct usb_composite_dev *cdev);
+static void gs_unbind(struct usb_composite_dev *cdev);
+static int gs_setup(struct usb_composite_dev *cdev,
+ const struct usb_ctrlrequest *ctrl);
+static int gs_setup_standard(struct usb_composite_dev *cdev,
+ const struct usb_ctrlrequest *ctrl);
+static int gs_setup_class(struct usb_composite_dev *cdev,
+ const struct usb_ctrlrequest *ctrl);
+#else
static int gs_bind(struct usb_gadget *gadget);
static void gs_unbind(struct usb_gadget *gadget);
static int gs_setup(struct usb_gadget *gadget,
@@ -219,8 +237,13 @@
const struct usb_ctrlrequest *ctrl);
static int gs_setup_class(struct usb_gadget *gadget,
const struct usb_ctrlrequest *ctrl);
+#endif
static void gs_setup_complete(struct usb_ep *ep, struct usb_request
*req);
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+static void gs_disconnect(struct usb_composite_dev *cdev);
+#else
static void gs_disconnect(struct usb_gadget *gadget);
+#endif
static int gs_set_config(struct gs_dev *dev, unsigned config);
static void gs_reset_config(struct gs_dev *dev);
static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed,
@@ -286,7 +309,24 @@
.chars_in_buffer = gs_chars_in_buffer,
};
static struct tty_driver *gs_tty_driver;
+static struct usb_gadget_strings gs_string_table;
+struct usb_descriptor_header *gs_acm_fullspeed_function[];
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+/* USB_FUNCTION */
+struct usb_function gs_usb_function = {
+ .name = GS_LONG_NAME,
+ .strings = &gs_string_table,
+ .descriptors = gs_acm_fullspeed_function,
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+ .hs_descriptors = gs_acm_highspeed_function,
+#endif
+ .bind = gs_bind,
+ .unbind = gs_unbind,
+ .setup = gs_setup,
+ .disconnect = gs_disconnect,
+};
+#else
/* gadget driver struct */
static struct usb_gadget_driver gs_gadget_driver = {
#ifdef CONFIG_USB_GADGET_DUALSPEED
@@ -303,10 +343,21 @@
.name = GS_SHORT_NAME,
},
};
+#endif
/* USB descriptors */
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+/* eth[11-20], serial[21-27], storage[31-35] */
+#define GS_MANUFACTURER_STR_ID 21
+#define GS_PRODUCT_STR_ID 22
+#define GS_SERIAL_STR_ID 23
+#define GS_BULK_CONFIG_STR_ID 24
+#define GS_ACM_CONFIG_STR_ID 25
+#define GS_CONTROL_STR_ID 26
+#define GS_DATA_STR_ID 27
+#else
#define GS_MANUFACTURER_STR_ID 1
#define GS_PRODUCT_STR_ID 2
#define GS_SERIAL_STR_ID 3
@@ -314,6 +365,7 @@
#define GS_ACM_CONFIG_STR_ID 5
#define GS_CONTROL_STR_ID 6
#define GS_DATA_STR_ID 7
+#endif /* End if Composite*/
/* static strings, in UTF-8 */
static char manufacturer[50];
@@ -375,7 +427,7 @@
.bMaxPower = 1,
};
-static const struct usb_interface_descriptor gs_bulk_interface_desc = {
+struct usb_interface_descriptor gs_bulk_interface_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = GS_BULK_INTERFACE_ID,
@@ -386,7 +438,7 @@
.iInterface = GS_DATA_STR_ID,
};
-static const struct usb_interface_descriptor gs_control_interface_desc
= {
+struct usb_interface_descriptor gs_control_interface_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = GS_CONTROL_INTERFACE_ID,
@@ -397,7 +449,7 @@
.iInterface = GS_CONTROL_STR_ID,
};
-static const struct usb_interface_descriptor gs_data_interface_desc = {
+struct usb_interface_descriptor gs_data_interface_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = GS_DATA_INTERFACE_ID,
@@ -430,14 +482,14 @@
.bmCapabilities = 0,
};
-static const struct usb_cdc_union_desc gs_union_desc = {
+static struct usb_cdc_union_desc gs_union_desc = {
.bLength = sizeof(gs_union_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_UNION_TYPE,
.bMasterInterface0 = 0, /* index of control interface */
.bSlaveInterface0 = 1, /* index of data interface */
};
-
+
static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -469,7 +521,7 @@
NULL,
};
-static const struct usb_descriptor_header *gs_acm_fullspeed_function[]
= {
+struct usb_descriptor_header *gs_acm_fullspeed_function[] = {
(struct usb_descriptor_header *) &gs_otg_descriptor,
(struct usb_descriptor_header *) &gs_control_interface_desc,
(struct usb_descriptor_header *) &gs_header_desc,
@@ -523,7 +575,7 @@
NULL,
};
-static const struct usb_descriptor_header *gs_acm_highspeed_function[]
= {
+struct usb_descriptor_header *gs_acm_highspeed_function[] = {
(struct usb_descriptor_header *) &gs_otg_descriptor,
(struct usb_descriptor_header *) &gs_control_interface_desc,
(struct usb_descriptor_header *) &gs_header_desc,
@@ -575,7 +627,11 @@
int i;
int retval;
- retval = usb_gadget_register_driver(&gs_gadget_driver);
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+ retval = usb_function_register(&gs_usb_function);
+#else
+ retval = usb_gadget_register_driver(&gs_gadget_driver);
+#endif
if (retval) {
printk(KERN_ERR "gs_module_init: cannot register gadget driver,
ret=%
d\n", retval);
return retval;
@@ -601,7 +657,10 @@
retval = tty_register_driver(gs_tty_driver);
if (retval) {
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+#else
usb_gadget_unregister_driver(&gs_gadget_driver);
+#endif
put_tty_driver(gs_tty_driver);
printk(KERN_ERR "gs_module_init: cannot register tty driver,
ret=%d
\n", retval);
return retval;
@@ -620,7 +679,11 @@
{
tty_unregister_driver(gs_tty_driver);
put_tty_driver(gs_tty_driver);
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+ usb_function_unregister(&gs_usb_function);
+#else
usb_gadget_unregister_driver(&gs_gadget_driver);
+#endif
printk(KERN_INFO "gs_module_exit: %s %s unloaded\n", GS_LONG_NAME,
GS_VERSION_STR);
}
@@ -1351,8 +1414,14 @@
* Called on module load. Allocates and initializes the device
* structure and a control request.
*/
-static int __init gs_bind(struct usb_gadget *gadget)
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+static int __devinit gs_bind(struct usb_composite_dev *cdev)
{
+ struct usb_gadget *gadget = cdev->gadget;
+#else
+static int __devinit gs_bind(struct usb_gadget *gadget)
+{
+#endif
int ret;
struct usb_ep *ep;
struct gs_dev *dev;
@@ -1377,7 +1446,10 @@
__constant_cpu_to_le16(GS_VERSION_NUM|0x0099);
}
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+#else
usb_ep_autoconfig_reset(gadget);
+#endif
ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc);
if (!ep)
@@ -1441,15 +1513,26 @@
dev->dev_gadget = gadget;
spin_lock_init(&dev->dev_lock);
INIT_LIST_HEAD(&dev->dev_req_list);
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+ cdev->current_func->driver_data = dev;
+#else
set_gadget_data(gadget, dev);
+#endif
if ((ret=gs_alloc_ports(dev, GFP_KERNEL)) != 0) {
printk(KERN_ERR "gs_bind: cannot allocate ports\n");
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+ gs_unbind(cdev);
+#else
gs_unbind(gadget);
+#endif
return ret;
}
/* preallocate control response and buffer */
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+ dev->dev_ctrl_req = cdev->req;
+#else
dev->dev_ctrl_req = gs_alloc_req(gadget->ep0, GS_MAX_DESC_LEN,
GFP_KERNEL);
if (dev->dev_ctrl_req == NULL) {
@@ -1459,9 +1542,13 @@
dev->dev_ctrl_req->complete = gs_setup_complete;
gadget->ep0->driver_data = dev;
+#endif
+
printk(KERN_INFO "gs_bind: %s %s bound\n",
GS_LONG_NAME, GS_VERSION_STR);
+ printk(KERN_INFO "using %s, OUT %s IN %s STATUS %s\n",
+ gadget->name, EP_OUT_NAME, EP_IN_NAME, EP_NOTIFY_NAME);
return 0;
@@ -1476,14 +1563,25 @@
* Called on module unload. Frees the control request and device
* structure.
*/
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+static void /* __init_or_exit */ gs_unbind(struct usb_composite_dev
*cdev)
+{
+ struct gs_dev *dev = cdev->current_func->driver_data;
+#else
static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
{
struct gs_dev *dev = get_gadget_data(gadget);
+#endif
gs_device = NULL;
/* read/write requests already freed, only control request remains */
if (dev != NULL) {
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+ dev->dev_ctrl_req = NULL;
+ gs_free_ports(dev);
+ kfree(dev);
+#else
if (dev->dev_ctrl_req != NULL) {
gs_free_req(gadget->ep0, dev->dev_ctrl_req);
dev->dev_ctrl_req = NULL;
@@ -1491,6 +1589,7 @@
gs_free_ports(dev);
kfree(dev);
set_gadget_data(gadget, NULL);
+#endif
}
printk(KERN_INFO "gs_unbind: %s %s unbound\n", GS_LONG_NAME,
@@ -1506,11 +1605,19 @@
* Returns the size of the data sent to the host, or a negative
* error number.
*/
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+static int gs_setup(struct usb_composite_dev *cdev,
+ const struct usb_ctrlrequest *ctrl)
+{
+ struct usb_gadget *gadget = cdev->gadget;
+ struct gs_dev *dev = cdev->current_func->driver_data;
+#else
static int gs_setup(struct usb_gadget *gadget,
const struct usb_ctrlrequest *ctrl)
{
- int ret = -EOPNOTSUPP;
struct gs_dev *dev = get_gadget_data(gadget);
+#endif
+ int ret = -EOPNOTSUPP;
struct usb_request *req = dev->dev_ctrl_req;
u16 wIndex = le16_to_cpu(ctrl->wIndex);
u16 wValue = le16_to_cpu(ctrl->wValue);
@@ -1518,11 +1625,22 @@
switch (ctrl->bRequestType & USB_TYPE_MASK) {
case USB_TYPE_STANDARD:
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+ ret = gs_setup_standard(cdev,ctrl);
+ /* Send to host only composite configuration */
+ if( (wValue >> 8) == USB_REQ_SET_CONFIGURATION )
+ goto done_composite;
+#else
ret = gs_setup_standard(gadget,ctrl);
+#endif
break;
case USB_TYPE_CLASS:
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+ ret = gs_setup_class(cdev,ctrl);
+#else
ret = gs_setup_class(gadget,ctrl);
+#endif
break;
default:
@@ -1546,15 +1664,24 @@
}
}
+done_composite:
/* device either stalls (ret < 0) or reports success */
return ret;
}
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+static int gs_setup_standard(struct usb_composite_dev *cdev,
+ const struct usb_ctrlrequest *ctrl)
+{
+ struct usb_gadget *gadget = cdev->gadget;
+ struct gs_dev *dev = cdev->current_func->driver_data;
+#else
static int gs_setup_standard(struct usb_gadget *gadget,
const struct usb_ctrlrequest *ctrl)
{
- int ret = -EOPNOTSUPP;
struct gs_dev *dev = get_gadget_data(gadget);
+#endif
+ int ret = -EOPNOTSUPP;
struct usb_request *req = dev->dev_ctrl_req;
u16 wIndex = le16_to_cpu(ctrl->wIndex);
u16 wValue = le16_to_cpu(ctrl->wValue);
@@ -1620,13 +1747,19 @@
break;
case USB_REQ_SET_INTERFACE:
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+ wIndex = wIndex - cdev->current_func->interface_shift;
+#endif
if (ctrl->bRequestType != USB_RECIP_INTERFACE
|| !dev->dev_config
|| wIndex >= GS_MAX_NUM_INTERFACES)
break;
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+#else
if (dev->dev_config == GS_BULK_CONFIG_ID
&& wIndex != GS_BULK_INTERFACE_ID)
break;
+#endif
/* no alternate interface settings */
if (wValue != 0)
break;
@@ -1680,11 +1813,18 @@
return ret;
}
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+static int gs_setup_class(struct usb_composite_dev *cdev,
+ const struct usb_ctrlrequest *ctrl)
+{
+ struct gs_dev *dev = cdev->current_func->driver_data;
+#else
static int gs_setup_class(struct usb_gadget *gadget,
const struct usb_ctrlrequest *ctrl)
{
- int ret = -EOPNOTSUPP;
struct gs_dev *dev = get_gadget_data(gadget);
+#endif
+ int ret = -EOPNOTSUPP;
struct gs_port *port = dev->dev_port[0]; /* ACM only has one
port */
struct usb_request *req = dev->dev_ctrl_req;
u16 wIndex = le16_to_cpu(ctrl->wIndex);
@@ -1745,10 +1885,17 @@
* ports and disconnects open ports. Open ports will be freed
* on close. Then reallocates the ports for the next connection.
*/
+#if defined(CONFIG_USB_COMPOSITE) ||
defined(CONFIG_USB_COMPOSITE_MODULE)
+static void gs_disconnect(struct usb_composite_dev *cdev)
+{
+// struct usb_gadget *gadget = cdev->gadget;
+ struct gs_dev *dev = cdev->current_func->driver_data;
+#else
static void gs_disconnect(struct usb_gadget *gadget)
{
- unsigned long flags;
struct gs_dev *dev = get_gadget_data(gadget);
+#endif
+ unsigned long flags;
spin_lock_irqsave(&dev->dev_lock, flags);
--
Best Regards,
Felipe Balbi
[EMAIL PROTECTED]
Nokia Institute of Technology - INdT
Kernel Developers Team
+55 92 2126 1003
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel