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 static void _f_##_attr_release(struct config_item *item) \ 21 { \ 22 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 23 \ 24 usb_put_function_instance(&opts->func_inst); \ 25 } \ 26 \ 27 static struct configfs_item_operations _f_##_item_ops = { \ 28 .release = _f_##_attr_release, \ 29 } 30 31 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_) \ 32 static ssize_t _f_##_opts_dev_addr_show(struct config_item *item, \ 33 char *page) \ 34 { \ 35 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 36 int result; \ 37 \ 38 mutex_lock(&opts->lock); \ 39 result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \ 40 mutex_unlock(&opts->lock); \ 41 \ 42 return result; \ 43 } \ 44 \ 45 static ssize_t _f_##_opts_dev_addr_store(struct config_item *item, \ 46 const char *page, size_t len)\ 47 { \ 48 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 49 int ret; \ 50 \ 51 mutex_lock(&opts->lock); \ 52 if (opts->refcnt) { \ 53 mutex_unlock(&opts->lock); \ 54 return -EBUSY; \ 55 } \ 56 \ 57 ret = gether_set_dev_addr(opts->net, page); \ 58 mutex_unlock(&opts->lock); \ 59 if (!ret) \ 60 ret = len; \ 61 return ret; \ 62 } \ 63 \ 64 CONFIGFS_ATTR(_f_##_opts_, dev_addr) 65 66 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_) \ 67 static ssize_t _f_##_opts_host_addr_show(struct config_item *item, \ 68 char *page) \ 69 { \ 70 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 71 int result; \ 72 \ 73 mutex_lock(&opts->lock); \ 74 result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \ 75 mutex_unlock(&opts->lock); \ 76 \ 77 return result; \ 78 } \ 79 \ 80 static ssize_t _f_##_opts_host_addr_store(struct config_item *item, \ 81 const char *page, size_t len)\ 82 { \ 83 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 84 int ret; \ 85 \ 86 mutex_lock(&opts->lock); \ 87 if (opts->refcnt) { \ 88 mutex_unlock(&opts->lock); \ 89 return -EBUSY; \ 90 } \ 91 \ 92 ret = gether_set_host_addr(opts->net, page); \ 93 mutex_unlock(&opts->lock); \ 94 if (!ret) \ 95 ret = len; \ 96 return ret; \ 97 } \ 98 \ 99 CONFIGFS_ATTR(_f_##_opts_, host_addr) 100 101 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_) \ 102 static ssize_t _f_##_opts_qmult_show(struct config_item *item, \ 103 char *page) \ 104 { \ 105 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 106 unsigned qmult; \ 107 \ 108 mutex_lock(&opts->lock); \ 109 qmult = gether_get_qmult(opts->net); \ 110 mutex_unlock(&opts->lock); \ 111 return sprintf(page, "%d\n", qmult); \ 112 } \ 113 \ 114 static ssize_t _f_##_opts_qmult_store(struct config_item *item, \ 115 const char *page, size_t len)\ 116 { \ 117 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 118 u8 val; \ 119 int ret; \ 120 \ 121 mutex_lock(&opts->lock); \ 122 if (opts->refcnt) { \ 123 ret = -EBUSY; \ 124 goto out; \ 125 } \ 126 \ 127 ret = kstrtou8(page, 0, &val); \ 128 if (ret) \ 129 goto out; \ 130 \ 131 gether_set_qmult(opts->net, val); \ 132 ret = len; \ 133 out: \ 134 mutex_unlock(&opts->lock); \ 135 return ret; \ 136 } \ 137 \ 138 CONFIGFS_ATTR(_f_##_opts_, qmult) 139 140 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_) \ 141 static ssize_t _f_##_opts_ifname_show(struct config_item *item, \ 142 char *page) \ 143 { \ 144 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 145 int ret; \ 146 \ 147 mutex_lock(&opts->lock); \ 148 ret = gether_get_ifname(opts->net, page, PAGE_SIZE); \ 149 mutex_unlock(&opts->lock); \ 150 \ 151 return ret; \ 152 } \ 153 \ 154 CONFIGFS_ATTR_RO(_f_##_opts_, ifname) 155 156 #define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \ 157 static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\ 158 char *page) \ 159 { \ 160 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 161 int ret; \ 162 \ 163 mutex_lock(&opts->lock); \ 164 ret = sprintf(page, "%02x\n", opts->_n_); \ 165 mutex_unlock(&opts->lock); \ 166 \ 167 return ret; \ 168 } \ 169 \ 170 static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\ 171 const char *page, \ 172 size_t len) \ 173 { \ 174 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 175 int ret; \ 176 u8 val; \ 177 \ 178 mutex_lock(&opts->lock); \ 179 ret = sscanf(page, "%02hhx", &val); \ 180 if (ret > 0) { \ 181 opts->_n_ = val; \ 182 ret = len; \ 183 } \ 184 mutex_unlock(&opts->lock); \ 185 \ 186 return ret; \ 187 } \ 188 \ 189 CONFIGFS_ATTR(_f_##_opts_, _n_) 190 191 #endif /* __U_ETHER_CONFIGFS_H */ 192