Skip to content

Commit

Permalink
usb: gadget: f_subset: add configfs support
Browse files Browse the repository at this point in the history
f_subset learns about configfs so we can, eventually,
remove in-kernel gadget drivers.

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 74bf963 commit 02832e5
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 1 deletion.
14 changes: 14 additions & 0 deletions Documentation/ABI/testing/configfs-usb-gadget-subset
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
What: /config/usb-gadget/gadget/functions/geth.name
Date: May 2013
KenelVersion: 3.11
Description:
The attributes:

ifname - network device interface name associated with
this function instance
qmult - queue length multiplier for high and
super speed
host_addr - MAC address of host's end of this
Ethernet over USB link
dev_addr - MAC address of device's end of this
Ethernet over USB link
10 changes: 10 additions & 0 deletions drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,16 @@ choice

# this first set of drivers all depend on bulk-capable hardware.

config USB_CONFIGFS_ECM_SUBSET
boolean "Ethernet Control Model (CDC ECM) subset"
depends on USB_CONFIGFS
depends on NET
select USB_U_ETHER
select USB_F_SUBSET
help
On hardware that can't implement the full protocol,
a simple CDC subset is used, placing fewer demands on USB.

config USB_CONFIGFS_EEM
bool "Ethernet Emulation Model (EEM)"
depends on USB_CONFIGFS
Expand Down
46 changes: 45 additions & 1 deletion drivers/usb/gadget/f_subset.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/etherdevice.h>

#include "u_ether.h"
#include "u_ether_configfs.h"
#include "u_gether.h"

/*
Expand Down Expand Up @@ -313,8 +314,10 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
* with regard to gether_opts->bound access
*/
if (!gether_opts->bound) {
mutex_lock(&gether_opts->lock);
gether_set_gadget(gether_opts->net, cdev->gadget);
status = gether_register_netdev(gether_opts->net);
mutex_unlock(&gether_opts->lock);
if (status)
return status;
gether_opts->bound = true;
Expand Down Expand Up @@ -445,6 +448,41 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],

#else

static inline struct f_gether_opts *to_f_gether_opts(struct config_item *item)
{
return container_of(to_config_group(item), struct f_gether_opts,
func_inst.group);
}

/* f_gether_item_ops */
USB_ETHERNET_CONFIGFS_ITEM(gether);

/* f_gether_opts_dev_addr */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(gether);

/* f_gether_opts_host_addr */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(gether);

/* f_gether_opts_qmult */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(gether);

/* f_gether_opts_ifname */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(gether);

static struct configfs_attribute *gether_attrs[] = {
&f_gether_opts_dev_addr.attr,
&f_gether_opts_host_addr.attr,
&f_gether_opts_qmult.attr,
&f_gether_opts_ifname.attr,
NULL,
};

static struct config_item_type gether_func_type = {
.ct_item_ops = &gether_item_ops,
.ct_attrs = gether_attrs,
.ct_owner = THIS_MODULE,
};

static void geth_free_inst(struct usb_function_instance *f)
{
struct f_gether_opts *opts;
Expand All @@ -464,12 +502,15 @@ static struct usb_function_instance *geth_alloc_inst(void)
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
if (!opts)
return ERR_PTR(-ENOMEM);

mutex_init(&opts->lock);
opts->func_inst.free_func_inst = geth_free_inst;
opts->net = gether_setup_default();
if (IS_ERR(opts->net))
return ERR_CAST(opts->net);

config_group_init_type_name(&opts->func_inst.group, "",
&gether_func_type);

return &opts->func_inst;
}

Expand Down Expand Up @@ -500,6 +541,8 @@ static struct usb_function *geth_alloc(struct usb_function_instance *fi)

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

mutex_lock(&opts->lock);
opts->refcnt++;
/* export host's Ethernet address in CDC format */
status = gether_get_host_addr_cdc(opts->net, geth->ethaddr,
sizeof(geth->ethaddr));
Expand All @@ -510,6 +553,7 @@ static struct usb_function *geth_alloc(struct usb_function_instance *fi)
geth_string_defs[1].s = geth->ethaddr;

geth->port.ioport = netdev_priv(opts->net);
mutex_unlock(&opts->lock);
geth->port.cdc_filter = DEFAULT_FILTER;

geth->port.func.name = "cdc_subset";
Expand Down
9 changes: 9 additions & 0 deletions drivers/usb/gadget/u_gether.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ struct f_gether_opts {
struct usb_function_instance func_inst;
struct net_device *net;
bool bound;

/*
* Read/write access to configfs attributes is handled by configfs.
*
* This is to protect the data from concurrent access by read/write
* and create symlink/remove symlink.
*/
struct mutex lock;
int refcnt;
};

#endif /* U_GETHER_H */

0 comments on commit 02832e5

Please sign in to comment.