usb: gadget: f_serial: convert to new function interface with backward compatibility
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>
Mon, 18 Mar 2013 08:52:57 +0000 (09:52 +0100)
committerFelipe Balbi <balbi@ti.com>
Wed, 3 Apr 2013 11:43:33 +0000 (14:43 +0300)
Converting f_serial to the new function interface requires converting
the f_serial's function code and its users.

This patch converts the f_serial.c to the new function interface.

The file is now compiled into a separate usb_f_serial.ko module.
The old function interface is provided by means of preprocessor
conditional directives. After all users are converted, the old interface
can be removed.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/f_serial.c
drivers/usb/gadget/serial.c

index 74a29de8f254c875e2639dd3d920447576a4cbde..8a08efbb11e74e79e12de83f68dd1c8cb6c38e61 100644 (file)
@@ -505,6 +505,9 @@ config USB_F_SS_LB
 config USB_U_SERIAL
        tristate
 
+config USB_F_SERIAL
+       tristate
+
 choice
        tristate "USB Gadget Drivers"
        default USB_ETH
index b938e06382b76feeb783aad4249b734111ae96bb..34bb49a131e902d867c66a42694b92ce9f9ebd22 100644 (file)
@@ -41,6 +41,8 @@ obj-$(CONFIG_USB_F_ACM)               += usb_f_acm.o
 usb_f_ss_lb-y                  := f_loopback.o f_sourcesink.o
 obj-$(CONFIG_USB_F_SS_LB)      += usb_f_ss_lb.o
 obj-$(CONFIG_USB_U_SERIAL)     += u_serial.o
+usb_f_serial-y                 := f_serial.o
+obj-$(CONFIG_USB_F_SERIAL)     += usb_f_serial.o
 
 #
 # USB gadget drivers
index da33cfb3031df2b34d3ccdfb202530124fd3f907..465789bd5c910d5a0569e0f0dc043a9b3fc826aa 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/device.h>
 
 #include "u_serial.h"
@@ -42,7 +43,7 @@ static inline struct f_gser *func_to_gser(struct usb_function *f)
 
 /* interface descriptor: */
 
-static struct usb_interface_descriptor gser_interface_desc __initdata = {
+static struct usb_interface_descriptor gser_interface_desc = {
        .bLength =              USB_DT_INTERFACE_SIZE,
        .bDescriptorType =      USB_DT_INTERFACE,
        /* .bInterfaceNumber = DYNAMIC */
@@ -55,21 +56,21 @@ static struct usb_interface_descriptor gser_interface_desc __initdata = {
 
 /* full speed support: */
 
-static struct usb_endpoint_descriptor gser_fs_in_desc __initdata = {
+static struct usb_endpoint_descriptor gser_fs_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
 };
 
-static struct usb_endpoint_descriptor gser_fs_out_desc __initdata = {
+static struct usb_endpoint_descriptor gser_fs_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bEndpointAddress =     USB_DIR_OUT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
 };
 
-static struct usb_descriptor_header *gser_fs_function[] __initdata = {
+static struct usb_descriptor_header *gser_fs_function[] = {
        (struct usb_descriptor_header *) &gser_interface_desc,
        (struct usb_descriptor_header *) &gser_fs_in_desc,
        (struct usb_descriptor_header *) &gser_fs_out_desc,
@@ -78,47 +79,47 @@ static struct usb_descriptor_header *gser_fs_function[] __initdata = {
 
 /* high speed support: */
 
-static struct usb_endpoint_descriptor gser_hs_in_desc __initdata = {
+static struct usb_endpoint_descriptor gser_hs_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(512),
 };
 
-static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = {
+static struct usb_endpoint_descriptor gser_hs_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(512),
 };
 
-static struct usb_descriptor_header *gser_hs_function[] __initdata = {
+static struct usb_descriptor_header *gser_hs_function[] = {
        (struct usb_descriptor_header *) &gser_interface_desc,
        (struct usb_descriptor_header *) &gser_hs_in_desc,
        (struct usb_descriptor_header *) &gser_hs_out_desc,
        NULL,
 };
 
-static struct usb_endpoint_descriptor gser_ss_in_desc __initdata = {
+static struct usb_endpoint_descriptor gser_ss_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(1024),
 };
 
-static struct usb_endpoint_descriptor gser_ss_out_desc __initdata = {
+static struct usb_endpoint_descriptor gser_ss_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(1024),
 };
 
-static struct usb_ss_ep_comp_descriptor gser_ss_bulk_comp_desc __initdata = {
+static struct usb_ss_ep_comp_descriptor gser_ss_bulk_comp_desc = {
        .bLength =              sizeof gser_ss_bulk_comp_desc,
        .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
 };
 
-static struct usb_descriptor_header *gser_ss_function[] __initdata = {
+static struct usb_descriptor_header *gser_ss_function[] = {
        (struct usb_descriptor_header *) &gser_interface_desc,
        (struct usb_descriptor_header *) &gser_ss_in_desc,
        (struct usb_descriptor_header *) &gser_ss_bulk_comp_desc,
@@ -183,14 +184,25 @@ static void gser_disable(struct usb_function *f)
 
 /* serial function driver setup/binding */
 
-static int __init
-gser_bind(struct usb_configuration *c, struct usb_function *f)
+static int gser_bind(struct usb_configuration *c, struct usb_function *f)
 {
        struct usb_composite_dev *cdev = c->cdev;
        struct f_gser           *gser = func_to_gser(f);
        int                     status;
        struct usb_ep           *ep;
 
+       /* REVISIT might want instance-specific strings to help
+        * distinguish instances ...
+        */
+
+       /* maybe allocate device-global string ID */
+       if (gser_string_defs[0].id == 0) {
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               gser_string_defs[0].id = status;
+       }
+
        /* allocate instance-specific interface IDs */
        status = usb_interface_id(c, f);
        if (status < 0)
@@ -246,8 +258,10 @@ fail:
        return status;
 }
 
+#ifdef USB_FSERIAL_INCLUDED
+
 static void
-gser_unbind(struct usb_configuration *c, struct usb_function *f)
+gser_old_unbind(struct usb_configuration *c, struct usb_function *f)
 {
        usb_free_all_descriptors(f);
        kfree(func_to_gser(f));
@@ -266,18 +280,6 @@ int __init gser_bind_config(struct usb_configuration *c, u8 port_num)
        struct f_gser   *gser;
        int             status;
 
-       /* REVISIT might want instance-specific strings to help
-        * distinguish instances ...
-        */
-
-       /* maybe allocate device-global string ID */
-       if (gser_string_defs[0].id == 0) {
-               status = usb_string_id(c->cdev);
-               if (status < 0)
-                       return status;
-               gser_string_defs[0].id = status;
-       }
-
        /* allocate and initialize one new instance */
        gser = kzalloc(sizeof *gser, GFP_KERNEL);
        if (!gser)
@@ -288,7 +290,7 @@ int __init gser_bind_config(struct usb_configuration *c, u8 port_num)
        gser->port.func.name = "gser";
        gser->port.func.strings = gser_strings;
        gser->port.func.bind = gser_bind;
-       gser->port.func.unbind = gser_unbind;
+       gser->port.func.unbind = gser_old_unbind;
        gser->port.func.set_alt = gser_set_alt;
        gser->port.func.disable = gser_disable;
 
@@ -297,3 +299,78 @@ int __init gser_bind_config(struct usb_configuration *c, u8 port_num)
                kfree(gser);
        return status;
 }
+
+#else
+
+static void gser_free_inst(struct usb_function_instance *f)
+{
+       struct f_serial_opts *opts;
+
+       opts = container_of(f, struct f_serial_opts, func_inst);
+       gserial_free_line(opts->port_num);
+       kfree(opts);
+}
+
+static struct usb_function_instance *gser_alloc_inst(void)
+{
+       struct f_serial_opts *opts;
+       int ret;
+
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
+
+       opts->func_inst.free_func_inst = gser_free_inst;
+       ret = gserial_alloc_line(&opts->port_num);
+       if (ret) {
+               kfree(opts);
+               return ERR_PTR(ret);
+       }
+
+       return &opts->func_inst;
+}
+
+static void gser_free(struct usb_function *f)
+{
+       struct f_gser *serial;
+
+       serial = func_to_gser(f);
+       kfree(serial);
+}
+
+static void gser_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       usb_free_all_descriptors(f);
+}
+
+struct usb_function *gser_alloc(struct usb_function_instance *fi)
+{
+       struct f_gser   *gser;
+       struct f_serial_opts *opts;
+
+       /* allocate and initialize one new instance */
+       gser = kzalloc(sizeof(*gser), GFP_KERNEL);
+       if (!gser)
+               return ERR_PTR(-ENOMEM);
+
+       opts = container_of(fi, struct f_serial_opts, func_inst);
+
+       gser->port_num = opts->port_num;
+
+       gser->port.func.name = "gser";
+       gser->port.func.strings = gser_strings;
+       gser->port.func.bind = gser_bind;
+       gser->port.func.unbind = gser_unbind;
+       gser->port.func.set_alt = gser_set_alt;
+       gser->port.func.disable = gser_disable;
+       gser->port.func.free_func = gser_free;
+
+       return &gser->port.func;
+}
+
+DECLARE_USB_FUNCTION_INIT(gser, gser_alloc_inst, gser_alloc);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Al Borchers");
+MODULE_AUTHOR("David Brownell");
+
+#endif
index c48ca1eb5442a77ad106469eef622aae5c2b67b1..07c1e802f91717533c15058fdccbbcf40aee6d19 100644 (file)
@@ -37,6 +37,7 @@
  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
  */
 #include "f_obex.c"
+#define USB_FSERIAL_INCLUDED
 #include "f_serial.c"
 
 /*-------------------------------------------------------------------------*/