Skip to content

Commit

Permalink
usb: gadget: f_eem: convert to new function interface with backward c…
Browse files Browse the repository at this point in the history
…ompatibility

Converting eem to the new function interface requires converting
the USB eem's function code and its users.

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

The file is now compiled into a separate usb_f_eem.ko module.

The old function interface is provided by means of a 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>
  • Loading branch information
Andrzej Pietrasiewicz authored and Felipe Balbi committed Jun 10, 2013
1 parent 9c62ce8 commit b29002a
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 36 deletions.
3 changes: 3 additions & 0 deletions drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,9 @@ config USB_F_ECM
config USB_F_PHONET
tristate

config USB_F_EEM
tristate

choice
tristate "USB Gadget Drivers"
default USB_ETH
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/gadget/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ usb_f_ecm-y := f_ecm.o
obj-$(CONFIG_USB_F_ECM) += usb_f_ecm.o
usb_f_phonet-y := f_phonet.o
obj-$(CONFIG_USB_F_PHONET) += usb_f_phonet.o
usb_f_eem-y := f_eem.o
obj-$(CONFIG_USB_F_EEM) += usb_f_eem.o

#
# USB gadget drivers
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/gadget/ether.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ static inline bool has_rndis(void)
#include "f_rndis.c"
#include "rndis.h"
#endif

#define USB_FEEM_INCLUDED
#include "f_eem.c"

/*-------------------------------------------------------------------------*/
Expand Down
174 changes: 138 additions & 36 deletions drivers/usb/gadget/f_eem.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/etherdevice.h>
#include <linux/crc32.h>
#include <linux/slab.h>

#include "u_ether.h"
#include "u_eem.h"

#define EEM_HLEN 2

Expand All @@ -40,7 +42,7 @@ static inline struct f_eem *func_to_eem(struct usb_function *f)

/* interface descriptor: */

static struct usb_interface_descriptor eem_intf __initdata = {
static struct usb_interface_descriptor eem_intf = {
.bLength = sizeof eem_intf,
.bDescriptorType = USB_DT_INTERFACE,

Expand All @@ -54,23 +56,23 @@ static struct usb_interface_descriptor eem_intf __initdata = {

/* full speed support: */

static struct usb_endpoint_descriptor eem_fs_in_desc __initdata = {
static struct usb_endpoint_descriptor eem_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 eem_fs_out_desc __initdata = {
static struct usb_endpoint_descriptor eem_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 *eem_fs_function[] __initdata = {
static struct usb_descriptor_header *eem_fs_function[] = {
/* CDC EEM control descriptors */
(struct usb_descriptor_header *) &eem_intf,
(struct usb_descriptor_header *) &eem_fs_in_desc,
Expand All @@ -80,7 +82,7 @@ static struct usb_descriptor_header *eem_fs_function[] __initdata = {

/* high speed support: */

static struct usb_endpoint_descriptor eem_hs_in_desc __initdata = {
static struct usb_endpoint_descriptor eem_hs_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,

Expand All @@ -89,7 +91,7 @@ static struct usb_endpoint_descriptor eem_hs_in_desc __initdata = {
.wMaxPacketSize = cpu_to_le16(512),
};

static struct usb_endpoint_descriptor eem_hs_out_desc __initdata = {
static struct usb_endpoint_descriptor eem_hs_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,

Expand All @@ -98,7 +100,7 @@ static struct usb_endpoint_descriptor eem_hs_out_desc __initdata = {
.wMaxPacketSize = cpu_to_le16(512),
};

static struct usb_descriptor_header *eem_hs_function[] __initdata = {
static struct usb_descriptor_header *eem_hs_function[] = {
/* CDC EEM control descriptors */
(struct usb_descriptor_header *) &eem_intf,
(struct usb_descriptor_header *) &eem_hs_in_desc,
Expand All @@ -108,7 +110,7 @@ static struct usb_descriptor_header *eem_hs_function[] __initdata = {

/* super speed support: */

static struct usb_endpoint_descriptor eem_ss_in_desc __initdata = {
static struct usb_endpoint_descriptor eem_ss_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,

Expand All @@ -117,7 +119,7 @@ static struct usb_endpoint_descriptor eem_ss_in_desc __initdata = {
.wMaxPacketSize = cpu_to_le16(1024),
};

static struct usb_endpoint_descriptor eem_ss_out_desc __initdata = {
static struct usb_endpoint_descriptor eem_ss_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,

Expand All @@ -126,7 +128,7 @@ static struct usb_endpoint_descriptor eem_ss_out_desc __initdata = {
.wMaxPacketSize = cpu_to_le16(1024),
};

static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc __initdata = {
static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc = {
.bLength = sizeof eem_ss_bulk_comp_desc,
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,

Expand All @@ -135,7 +137,7 @@ static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc __initdata = {
/* .bmAttributes = 0, */
};

static struct usb_descriptor_header *eem_ss_function[] __initdata = {
static struct usb_descriptor_header *eem_ss_function[] = {
/* CDC EEM control descriptors */
(struct usb_descriptor_header *) &eem_intf,
(struct usb_descriptor_header *) &eem_ss_in_desc,
Expand Down Expand Up @@ -242,14 +244,44 @@ static void eem_disable(struct usb_function *f)

/* EEM function driver setup/binding */

static int __init
eem_bind(struct usb_configuration *c, struct usb_function *f)
static int eem_bind(struct usb_configuration *c, struct usb_function *f)
{
struct usb_composite_dev *cdev = c->cdev;
struct f_eem *eem = func_to_eem(f);
int status;
struct usb_ep *ep;

#ifndef USB_FEEM_INCLUDED
struct f_eem_opts *eem_opts;

eem_opts = container_of(f->fi, struct f_eem_opts, func_inst);
/*
* in drivers/usb/gadget/configfs.c:configfs_composite_bind()
* configurations are bound in sequence with list_for_each_entry,
* in each configuration its functions are bound in sequence
* with list_for_each_entry, so we assume no race condition
* with regard to eem_opts->bound access
*/
if (!eem_opts->bound) {
gether_set_gadget(eem_opts->net, cdev->gadget);
status = gether_register_netdev(eem_opts->net);
if (status)
return status;
eem_opts->bound = true;
}
#endif

/* maybe allocate device-global string IDs */
if (eem_string_defs[0].id == 0) {

/* control interface label */
status = usb_string_id(c->cdev);
if (status < 0)
return status;
eem_string_defs[0].id = status;
eem_intf.iInterface = status;
}

/* allocate instance-specific interface IDs */
status = usb_interface_id(c, f);
if (status < 0)
Expand Down Expand Up @@ -307,17 +339,6 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
return status;
}

static void
eem_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_eem *eem = func_to_eem(f);

DBG(c->cdev, "eem unbind\n");

usb_free_all_descriptors(f);
kfree(eem);
}

static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req)
{
struct sk_buff *skb = (struct sk_buff *)req->context;
Expand Down Expand Up @@ -518,6 +539,18 @@ static int eem_unwrap(struct gether *port,
return status;
}

#ifdef USB_FEEM_INCLUDED

static void eem_old_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_eem *eem = func_to_eem(f);

DBG(c->cdev, "eem unbind\n");

usb_free_all_descriptors(f);
kfree(eem);
}

/**
* eem_bind_config - add CDC Ethernet (EEM) network link to a configuration
* @c: the configuration to support the network link
Expand All @@ -533,17 +566,6 @@ int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
struct f_eem *eem;
int status;

/* maybe allocate device-global string IDs */
if (eem_string_defs[0].id == 0) {

/* control interface label */
status = usb_string_id(c->cdev);
if (status < 0)
return status;
eem_string_defs[0].id = status;
eem_intf.iInterface = status;
}

/* allocate and initialize one new instance */
eem = kzalloc(sizeof *eem, GFP_KERNEL);
if (!eem)
Expand All @@ -556,7 +578,7 @@ int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
eem->port.func.strings = eem_strings;
/* descriptors are per-instance copies */
eem->port.func.bind = eem_bind;
eem->port.func.unbind = eem_unbind;
eem->port.func.unbind = eem_old_unbind;
eem->port.func.set_alt = eem_set_alt;
eem->port.func.setup = eem_setup;
eem->port.func.disable = eem_disable;
Expand All @@ -570,3 +592,83 @@ int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
return status;
}

#else

static void eem_free_inst(struct usb_function_instance *f)
{
struct f_eem_opts *opts;

opts = container_of(f, struct f_eem_opts, func_inst);
if (opts->bound)
gether_cleanup(netdev_priv(opts->net));
else
free_netdev(opts->net);
kfree(opts);
}

static struct usb_function_instance *eem_alloc_inst(void)
{
struct f_eem_opts *opts;

opts = kzalloc(sizeof(*opts), GFP_KERNEL);
if (!opts)
return ERR_PTR(-ENOMEM);
opts->func_inst.free_func_inst = eem_free_inst;
opts->net = gether_setup_default();
if (IS_ERR(opts->net))
return ERR_CAST(opts->net);

return &opts->func_inst;
}

static void eem_free(struct usb_function *f)
{
struct f_eem *eem;

eem = func_to_eem(f);
kfree(eem);
}

static void eem_unbind(struct usb_configuration *c, struct usb_function *f)
{
DBG(c->cdev, "eem unbind\n");

usb_free_all_descriptors(f);
}

struct usb_function *eem_alloc(struct usb_function_instance *fi)
{
struct f_eem *eem;
struct f_eem_opts *opts;

/* allocate and initialize one new instance */
eem = kzalloc(sizeof(*eem), GFP_KERNEL);
if (!eem)
return ERR_PTR(-ENOMEM);

opts = container_of(fi, struct f_eem_opts, func_inst);

eem->port.ioport = netdev_priv(opts->net);
eem->port.cdc_filter = DEFAULT_FILTER;

eem->port.func.name = "cdc_eem";
eem->port.func.strings = eem_strings;
/* descriptors are per-instance copies */
eem->port.func.bind = eem_bind;
eem->port.func.unbind = eem_unbind;
eem->port.func.set_alt = eem_set_alt;
eem->port.func.setup = eem_setup;
eem->port.func.disable = eem_disable;
eem->port.func.free_func = eem_free;
eem->port.wrap = eem_wrap;
eem->port.unwrap = eem_unwrap;
eem->port.header_len = EEM_HLEN;

return &eem->port.func;
}

DECLARE_USB_FUNCTION_INIT(eem, eem_alloc_inst, eem_alloc);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Brownell");

#endif
27 changes: 27 additions & 0 deletions drivers/usb/gadget/u_eem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* u_eem.h
*
* Utility definitions for the eem function
*
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#ifndef U_EEM_H
#define U_EEM_H

#include <linux/usb/composite.h>

struct f_eem_opts {
struct usb_function_instance func_inst;
struct net_device *net;
bool bound;
};

#endif /* U_EEM_H */

0 comments on commit b29002a

Please sign in to comment.