aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2013-05-23 10:32:02 +0200
committerFelipe Balbi <balbi@ti.com>2013-06-10 17:15:43 +0300
commitaa83c6adf753cc46e7898605ceb33dfa98eb63fa (patch)
treecb6e3d7878a8fa8bf863d1c47969055dae957d92 /drivers/usb
parente730660378be92b83288b59b824ccdace5cd2652 (diff)
usb: gadget: add helpers for configfs support for USB Ethernet
All USB Ethernet functions will have very similar attributes in configfs. This patch provides helper definitions to ease writing the functions and reduce source code duplication. 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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/f_ncm.c139
-rw-r--r--drivers/usb/gadget/u_ether_configfs.h164
2 files changed, 175 insertions, 128 deletions
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
index 697262e2a57..47a5724211c 100644
--- a/drivers/usb/gadget/f_ncm.c
+++ b/drivers/usb/gadget/f_ncm.c
@@ -24,6 +24,7 @@
#include <linux/usb/cdc.h>
#include "u_ether.h"
+#include "u_ether_configfs.h"
#include "u_ncm.h"
/*
@@ -1298,138 +1299,20 @@ static inline struct f_ncm_opts *to_f_ncm_opts(struct config_item *item)
func_inst.group);
}
-CONFIGFS_ATTR_STRUCT(f_ncm_opts);
-CONFIGFS_ATTR_OPS(f_ncm_opts);
+/* f_ncm_item_ops */
+USB_ETHERNET_CONFIGFS_ITEM(ncm);
-static void ncm_attr_release(struct config_item *item)
-{
- struct f_ncm_opts *opts = to_f_ncm_opts(item);
-
- usb_put_function_instance(&opts->func_inst);
-}
-
-static struct configfs_item_operations ncm_item_ops = {
- .release = ncm_attr_release,
- .show_attribute = f_ncm_opts_attr_show,
- .store_attribute = f_ncm_opts_attr_store,
-};
-
-static ssize_t ncm_opts_dev_addr_show(struct f_ncm_opts *opts, char *page)
-{
- int result;
-
- mutex_lock(&opts->lock);
- result = gether_get_dev_addr(opts->net, page, PAGE_SIZE);
- mutex_unlock(&opts->lock);
-
- return result;
-}
-
-static ssize_t ncm_opts_dev_addr_store(struct f_ncm_opts *opts,
- const char *page, size_t len)
-{
- int ret;
-
- mutex_lock(&opts->lock);
- if (opts->refcnt) {
- mutex_unlock(&opts->lock);
- return -EBUSY;
- }
-
- ret = gether_set_dev_addr(opts->net, page);
- mutex_unlock(&opts->lock);
- if (!ret)
- ret = len;
- return ret;
-}
-
-static struct f_ncm_opts_attribute f_ncm_opts_dev_addr =
- __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR, ncm_opts_dev_addr_show,
- ncm_opts_dev_addr_store);
-
-static ssize_t ncm_opts_host_addr_show(struct f_ncm_opts *opts, char *page)
-{
- int result;
-
- mutex_lock(&opts->lock);
- result = gether_get_host_addr(opts->net, page, PAGE_SIZE);
- mutex_unlock(&opts->lock);
-
- return result;
-}
-
-static ssize_t ncm_opts_host_addr_store(struct f_ncm_opts *opts,
- const char *page, size_t len)
-{
- int ret;
+/* f_ncm_opts_dev_addr */
+USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(ncm);
- mutex_lock(&opts->lock);
- if (opts->refcnt) {
- mutex_unlock(&opts->lock);
- return -EBUSY;
- }
-
- ret = gether_set_host_addr(opts->net, page);
- mutex_unlock(&opts->lock);
- if (!ret)
- ret = len;
- return ret;
-}
-
-static struct f_ncm_opts_attribute f_ncm_opts_host_addr =
- __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR, ncm_opts_host_addr_show,
- ncm_opts_host_addr_store);
-
-static ssize_t ncm_opts_qmult_show(struct f_ncm_opts *opts, char *page)
-{
- unsigned qmult;
-
- mutex_lock(&opts->lock);
- qmult = gether_get_qmult(opts->net);
- mutex_unlock(&opts->lock);
- return sprintf(page, "%d", qmult);
-}
-
-static ssize_t ncm_opts_qmult_store(struct f_ncm_opts *opts,
- const char *page, size_t len)
-{
- u8 val;
- int ret;
+/* f_ncm_opts_host_addr */
+USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(ncm);
- mutex_lock(&opts->lock);
- if (opts->refcnt) {
- ret = -EBUSY;
- goto out;
- }
-
- ret = kstrtou8(page, 0, &val);
- if (ret)
- goto out;
-
- gether_set_qmult(opts->net, val);
- ret = len;
-out:
- mutex_unlock(&opts->lock);
- return ret;
-}
-
-static struct f_ncm_opts_attribute f_ncm_opts_qmult =
- __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR, ncm_opts_qmult_show,
- ncm_opts_qmult_store);
-
-static ssize_t ncm_opts_ifname_show(struct f_ncm_opts *opts, char *page)
-{
- int ret;
-
- mutex_lock(&opts->lock);
- ret = gether_get_ifname(opts->net, page, PAGE_SIZE);
- mutex_unlock(&opts->lock);
-
- return ret;
-}
+/* f_ncm_opts_qmult */
+USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(ncm);
-static struct f_ncm_opts_attribute f_ncm_opts_ifname =
- __CONFIGFS_ATTR_RO(ifname, ncm_opts_ifname_show);
+/* f_ncm_opts_ifname */
+USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ncm);
static struct configfs_attribute *ncm_attrs[] = {
&f_ncm_opts_dev_addr.attr,
diff --git a/drivers/usb/gadget/u_ether_configfs.h b/drivers/usb/gadget/u_ether_configfs.h
new file mode 100644
index 00000000000..bcbd30146cf
--- /dev/null
+++ b/drivers/usb/gadget/u_ether_configfs.h
@@ -0,0 +1,164 @@
+/*
+ * u_ether_configfs.h
+ *
+ * Utility definitions for configfs support in USB Ethernet functions
+ *
+ * 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_ETHER_CONFIGFS_H
+#define __U_ETHER_CONFIGFS_H
+
+#define USB_ETHERNET_CONFIGFS_ITEM(_f_) \
+ CONFIGFS_ATTR_STRUCT(f_##_f_##_opts); \
+ CONFIGFS_ATTR_OPS(f_##_f_##_opts); \
+ \
+ static void _f_##_attr_release(struct config_item *item) \
+ { \
+ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
+ \
+ usb_put_function_instance(&opts->func_inst); \
+ } \
+ \
+ static struct configfs_item_operations _f_##_item_ops = { \
+ .release = _f_##_attr_release, \
+ .show_attribute = f_##_f_##_opts_attr_show, \
+ .store_attribute = f_##_f_##_opts_attr_store, \
+ }
+
+#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_) \
+ static ssize_t _f_##_opts_dev_addr_show(struct f_##_f_##_opts *opts, \
+ char *page) \
+ { \
+ int result; \
+ \
+ mutex_lock(&opts->lock); \
+ result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \
+ mutex_unlock(&opts->lock); \
+ \
+ return result; \
+ } \
+ \
+ static ssize_t _f_##_opts_dev_addr_store(struct f_##_f_##_opts *opts, \
+ const char *page, size_t len)\
+ { \
+ int ret; \
+ \
+ mutex_lock(&opts->lock); \
+ if (opts->refcnt) { \
+ mutex_unlock(&opts->lock); \
+ return -EBUSY; \
+ } \
+ \
+ ret = gether_set_dev_addr(opts->net, page); \
+ mutex_unlock(&opts->lock); \
+ if (!ret) \
+ ret = len; \
+ return ret; \
+ } \
+ \
+ static struct f_##_f_##_opts_attribute f_##_f_##_opts_dev_addr = \
+ __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR, \
+ _f_##_opts_dev_addr_show, \
+ _f_##_opts_dev_addr_store)
+
+#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_) \
+ static ssize_t _f_##_opts_host_addr_show(struct f_##_f_##_opts *opts, \
+ char *page) \
+ { \
+ int result; \
+ \
+ mutex_lock(&opts->lock); \
+ result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \
+ mutex_unlock(&opts->lock); \
+ \
+ return result; \
+ } \
+ \
+ static ssize_t _f_##_opts_host_addr_store(struct f_##_f_##_opts *opts, \
+ const char *page, size_t len)\
+ { \
+ int ret; \
+ \
+ mutex_lock(&opts->lock); \
+ if (opts->refcnt) { \
+ mutex_unlock(&opts->lock); \
+ return -EBUSY; \
+ } \
+ \
+ ret = gether_set_host_addr(opts->net, page); \
+ mutex_unlock(&opts->lock); \
+ if (!ret) \
+ ret = len; \
+ return ret; \
+ } \
+ \
+ static struct f_##_f_##_opts_attribute f_##_f_##_opts_host_addr = \
+ __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR, \
+ _f_##_opts_host_addr_show, \
+ _f_##_opts_host_addr_store)
+
+#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_) \
+ static ssize_t _f_##_opts_qmult_show(struct f_##_f_##_opts *opts, \
+ char *page) \
+ { \
+ unsigned qmult; \
+ \
+ mutex_lock(&opts->lock); \
+ qmult = gether_get_qmult(opts->net); \
+ mutex_unlock(&opts->lock); \
+ return sprintf(page, "%d", qmult); \
+ } \
+ \
+ static ssize_t _f_##_opts_qmult_store(struct f_##_f_##_opts *opts, \
+ const char *page, size_t len)\
+ { \
+ u8 val; \
+ int ret; \
+ \
+ mutex_lock(&opts->lock); \
+ if (opts->refcnt) { \
+ ret = -EBUSY; \
+ goto out; \
+ } \
+ \
+ ret = kstrtou8(page, 0, &val); \
+ if (ret) \
+ goto out; \
+ \
+ gether_set_qmult(opts->net, val); \
+ ret = len; \
+out: \
+ mutex_unlock(&opts->lock); \
+ return ret; \
+ } \
+ \
+ static struct f_##_f_##_opts_attribute f_##_f_##_opts_qmult = \
+ __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR, \
+ _f_##_opts_qmult_show, \
+ _f_##_opts_qmult_store)
+
+#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_) \
+ static ssize_t _f_##_opts_ifname_show(struct f_##_f_##_opts *opts, \
+ char *page) \
+ { \
+ int ret; \
+ \
+ mutex_lock(&opts->lock); \
+ ret = gether_get_ifname(opts->net, page, PAGE_SIZE); \
+ mutex_unlock(&opts->lock); \
+ \
+ return ret; \
+ } \
+ \
+ static struct f_##_f_##_opts_attribute f_##_f_##_opts_ifname = \
+ __CONFIGFS_ATTR_RO(ifname, _f_##_opts_ifname_show)
+
+#endif /* __U_ETHER_CONFIGFS_H */