1 /* 2 * u_ether_configfs.h 3 * 4 * Utility definitions for configfs support in USB Ethernet functions 5 * 6 * Copyright (c) 2013 Samsung Electronics Co., Ltd. 7 * http://www.samsung.com 8 * 9 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 */ 15 16 #ifndef __U_ETHER_CONFIGFS_H 17 #define __U_ETHER_CONFIGFS_H 18 19 #define USB_ETHERNET_CONFIGFS_ITEM(_f_) \ 20 CONFIGFS_ATTR_STRUCT(f_##_f_##_opts); \ 21 CONFIGFS_ATTR_OPS(f_##_f_##_opts); \ 22 \ 23 static void _f_##_attr_release(struct config_item *item) \ 24 { \ 25 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 26 \ 27 usb_put_function_instance(&opts->func_inst); \ 28 } \ 29 \ 30 static struct configfs_item_operations _f_##_item_ops = { \ 31 .release = _f_##_attr_release, \ 32 .show_attribute = f_##_f_##_opts_attr_show, \ 33 .store_attribute = f_##_f_##_opts_attr_store, \ 34 } 35 36 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_) \ 37 static ssize_t _f_##_opts_dev_addr_show(struct f_##_f_##_opts *opts, \ 38 char *page) \ 39 { \ 40 int result; \ 41 \ 42 mutex_lock(&opts->lock); \ 43 result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \ 44 mutex_unlock(&opts->lock); \ 45 \ 46 return result; \ 47 } \ 48 \ 49 static ssize_t _f_##_opts_dev_addr_store(struct f_##_f_##_opts *opts, \ 50 const char *page, size_t len)\ 51 { \ 52 int ret; \ 53 \ 54 mutex_lock(&opts->lock); \ 55 if (opts->refcnt) { \ 56 mutex_unlock(&opts->lock); \ 57 return -EBUSY; \ 58 } \ 59 \ 60 ret = gether_set_dev_addr(opts->net, page); \ 61 mutex_unlock(&opts->lock); \ 62 if (!ret) \ 63 ret = len; \ 64 return ret; \ 65 } \ 66 \ 67 static struct f_##_f_##_opts_attribute f_##_f_##_opts_dev_addr = \ 68 __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR, \ 69 _f_##_opts_dev_addr_show, \ 70 _f_##_opts_dev_addr_store) 71 72 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_) \ 73 static ssize_t _f_##_opts_host_addr_show(struct f_##_f_##_opts *opts, \ 74 char *page) \ 75 { \ 76 int result; \ 77 \ 78 mutex_lock(&opts->lock); \ 79 result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \ 80 mutex_unlock(&opts->lock); \ 81 \ 82 return result; \ 83 } \ 84 \ 85 static ssize_t _f_##_opts_host_addr_store(struct f_##_f_##_opts *opts, \ 86 const char *page, size_t len)\ 87 { \ 88 int ret; \ 89 \ 90 mutex_lock(&opts->lock); \ 91 if (opts->refcnt) { \ 92 mutex_unlock(&opts->lock); \ 93 return -EBUSY; \ 94 } \ 95 \ 96 ret = gether_set_host_addr(opts->net, page); \ 97 mutex_unlock(&opts->lock); \ 98 if (!ret) \ 99 ret = len; \ 100 return ret; \ 101 } \ 102 \ 103 static struct f_##_f_##_opts_attribute f_##_f_##_opts_host_addr = \ 104 __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR, \ 105 _f_##_opts_host_addr_show, \ 106 _f_##_opts_host_addr_store) 107 108 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_) \ 109 static ssize_t _f_##_opts_qmult_show(struct f_##_f_##_opts *opts, \ 110 char *page) \ 111 { \ 112 unsigned qmult; \ 113 \ 114 mutex_lock(&opts->lock); \ 115 qmult = gether_get_qmult(opts->net); \ 116 mutex_unlock(&opts->lock); \ 117 return sprintf(page, "%d", qmult); \ 118 } \ 119 \ 120 static ssize_t _f_##_opts_qmult_store(struct f_##_f_##_opts *opts, \ 121 const char *page, size_t len)\ 122 { \ 123 u8 val; \ 124 int ret; \ 125 \ 126 mutex_lock(&opts->lock); \ 127 if (opts->refcnt) { \ 128 ret = -EBUSY; \ 129 goto out; \ 130 } \ 131 \ 132 ret = kstrtou8(page, 0, &val); \ 133 if (ret) \ 134 goto out; \ 135 \ 136 gether_set_qmult(opts->net, val); \ 137 ret = len; \ 138 out: \ 139 mutex_unlock(&opts->lock); \ 140 return ret; \ 141 } \ 142 \ 143 static struct f_##_f_##_opts_attribute f_##_f_##_opts_qmult = \ 144 __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR, \ 145 _f_##_opts_qmult_show, \ 146 _f_##_opts_qmult_store) 147 148 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_) \ 149 static ssize_t _f_##_opts_ifname_show(struct f_##_f_##_opts *opts, \ 150 char *page) \ 151 { \ 152 int ret; \ 153 \ 154 mutex_lock(&opts->lock); \ 155 ret = gether_get_ifname(opts->net, page, PAGE_SIZE); \ 156 mutex_unlock(&opts->lock); \ 157 \ 158 return ret; \ 159 } \ 160 \ 161 static struct f_##_f_##_opts_attribute f_##_f_##_opts_ifname = \ 162 __CONFIGFS_ATTR_RO(ifname, _f_##_opts_ifname_show) 163 164 #endif /* __U_ETHER_CONFIGFS_H */ 165