100a2430fSAndrzej Pietrasiewicz /* 200a2430fSAndrzej Pietrasiewicz * u_ether_configfs.h 300a2430fSAndrzej Pietrasiewicz * 400a2430fSAndrzej Pietrasiewicz * Utility definitions for configfs support in USB Ethernet functions 500a2430fSAndrzej Pietrasiewicz * 600a2430fSAndrzej Pietrasiewicz * Copyright (c) 2013 Samsung Electronics Co., Ltd. 700a2430fSAndrzej Pietrasiewicz * http://www.samsung.com 800a2430fSAndrzej Pietrasiewicz * 900a2430fSAndrzej Pietrasiewicz * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> 1000a2430fSAndrzej Pietrasiewicz * 1100a2430fSAndrzej Pietrasiewicz * This program is free software; you can redistribute it and/or modify 1200a2430fSAndrzej Pietrasiewicz * it under the terms of the GNU General Public License version 2 as 1300a2430fSAndrzej Pietrasiewicz * published by the Free Software Foundation. 1400a2430fSAndrzej Pietrasiewicz */ 1500a2430fSAndrzej Pietrasiewicz 1600a2430fSAndrzej Pietrasiewicz #ifndef __U_ETHER_CONFIGFS_H 1700a2430fSAndrzej Pietrasiewicz #define __U_ETHER_CONFIGFS_H 1800a2430fSAndrzej Pietrasiewicz 1900a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM(_f_) \ 2000a2430fSAndrzej Pietrasiewicz CONFIGFS_ATTR_STRUCT(f_##_f_##_opts); \ 2100a2430fSAndrzej Pietrasiewicz CONFIGFS_ATTR_OPS(f_##_f_##_opts); \ 2200a2430fSAndrzej Pietrasiewicz \ 2300a2430fSAndrzej Pietrasiewicz static void _f_##_attr_release(struct config_item *item) \ 2400a2430fSAndrzej Pietrasiewicz { \ 2500a2430fSAndrzej Pietrasiewicz struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 2600a2430fSAndrzej Pietrasiewicz \ 2700a2430fSAndrzej Pietrasiewicz usb_put_function_instance(&opts->func_inst); \ 2800a2430fSAndrzej Pietrasiewicz } \ 2900a2430fSAndrzej Pietrasiewicz \ 3000a2430fSAndrzej Pietrasiewicz static struct configfs_item_operations _f_##_item_ops = { \ 3100a2430fSAndrzej Pietrasiewicz .release = _f_##_attr_release, \ 3200a2430fSAndrzej Pietrasiewicz .show_attribute = f_##_f_##_opts_attr_show, \ 3300a2430fSAndrzej Pietrasiewicz .store_attribute = f_##_f_##_opts_attr_store, \ 3400a2430fSAndrzej Pietrasiewicz } 3500a2430fSAndrzej Pietrasiewicz 3600a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_) \ 3700a2430fSAndrzej Pietrasiewicz static ssize_t _f_##_opts_dev_addr_show(struct f_##_f_##_opts *opts, \ 3800a2430fSAndrzej Pietrasiewicz char *page) \ 3900a2430fSAndrzej Pietrasiewicz { \ 4000a2430fSAndrzej Pietrasiewicz int result; \ 4100a2430fSAndrzej Pietrasiewicz \ 4200a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 4300a2430fSAndrzej Pietrasiewicz result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \ 4400a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 4500a2430fSAndrzej Pietrasiewicz \ 4600a2430fSAndrzej Pietrasiewicz return result; \ 4700a2430fSAndrzej Pietrasiewicz } \ 4800a2430fSAndrzej Pietrasiewicz \ 4900a2430fSAndrzej Pietrasiewicz static ssize_t _f_##_opts_dev_addr_store(struct f_##_f_##_opts *opts, \ 5000a2430fSAndrzej Pietrasiewicz const char *page, size_t len)\ 5100a2430fSAndrzej Pietrasiewicz { \ 5200a2430fSAndrzej Pietrasiewicz int ret; \ 5300a2430fSAndrzej Pietrasiewicz \ 5400a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 5500a2430fSAndrzej Pietrasiewicz if (opts->refcnt) { \ 5600a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 5700a2430fSAndrzej Pietrasiewicz return -EBUSY; \ 5800a2430fSAndrzej Pietrasiewicz } \ 5900a2430fSAndrzej Pietrasiewicz \ 6000a2430fSAndrzej Pietrasiewicz ret = gether_set_dev_addr(opts->net, page); \ 6100a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 6200a2430fSAndrzej Pietrasiewicz if (!ret) \ 6300a2430fSAndrzej Pietrasiewicz ret = len; \ 6400a2430fSAndrzej Pietrasiewicz return ret; \ 6500a2430fSAndrzej Pietrasiewicz } \ 6600a2430fSAndrzej Pietrasiewicz \ 6700a2430fSAndrzej Pietrasiewicz static struct f_##_f_##_opts_attribute f_##_f_##_opts_dev_addr = \ 6800a2430fSAndrzej Pietrasiewicz __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR, \ 6900a2430fSAndrzej Pietrasiewicz _f_##_opts_dev_addr_show, \ 7000a2430fSAndrzej Pietrasiewicz _f_##_opts_dev_addr_store) 7100a2430fSAndrzej Pietrasiewicz 7200a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_) \ 7300a2430fSAndrzej Pietrasiewicz static ssize_t _f_##_opts_host_addr_show(struct f_##_f_##_opts *opts, \ 7400a2430fSAndrzej Pietrasiewicz char *page) \ 7500a2430fSAndrzej Pietrasiewicz { \ 7600a2430fSAndrzej Pietrasiewicz int result; \ 7700a2430fSAndrzej Pietrasiewicz \ 7800a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 7900a2430fSAndrzej Pietrasiewicz result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \ 8000a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 8100a2430fSAndrzej Pietrasiewicz \ 8200a2430fSAndrzej Pietrasiewicz return result; \ 8300a2430fSAndrzej Pietrasiewicz } \ 8400a2430fSAndrzej Pietrasiewicz \ 8500a2430fSAndrzej Pietrasiewicz static ssize_t _f_##_opts_host_addr_store(struct f_##_f_##_opts *opts, \ 8600a2430fSAndrzej Pietrasiewicz const char *page, size_t len)\ 8700a2430fSAndrzej Pietrasiewicz { \ 8800a2430fSAndrzej Pietrasiewicz int ret; \ 8900a2430fSAndrzej Pietrasiewicz \ 9000a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 9100a2430fSAndrzej Pietrasiewicz if (opts->refcnt) { \ 9200a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 9300a2430fSAndrzej Pietrasiewicz return -EBUSY; \ 9400a2430fSAndrzej Pietrasiewicz } \ 9500a2430fSAndrzej Pietrasiewicz \ 9600a2430fSAndrzej Pietrasiewicz ret = gether_set_host_addr(opts->net, page); \ 9700a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 9800a2430fSAndrzej Pietrasiewicz if (!ret) \ 9900a2430fSAndrzej Pietrasiewicz ret = len; \ 10000a2430fSAndrzej Pietrasiewicz return ret; \ 10100a2430fSAndrzej Pietrasiewicz } \ 10200a2430fSAndrzej Pietrasiewicz \ 10300a2430fSAndrzej Pietrasiewicz static struct f_##_f_##_opts_attribute f_##_f_##_opts_host_addr = \ 10400a2430fSAndrzej Pietrasiewicz __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR, \ 10500a2430fSAndrzej Pietrasiewicz _f_##_opts_host_addr_show, \ 10600a2430fSAndrzej Pietrasiewicz _f_##_opts_host_addr_store) 10700a2430fSAndrzej Pietrasiewicz 10800a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_) \ 10900a2430fSAndrzej Pietrasiewicz static ssize_t _f_##_opts_qmult_show(struct f_##_f_##_opts *opts, \ 11000a2430fSAndrzej Pietrasiewicz char *page) \ 11100a2430fSAndrzej Pietrasiewicz { \ 11200a2430fSAndrzej Pietrasiewicz unsigned qmult; \ 11300a2430fSAndrzej Pietrasiewicz \ 11400a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 11500a2430fSAndrzej Pietrasiewicz qmult = gether_get_qmult(opts->net); \ 11600a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 11700a2430fSAndrzej Pietrasiewicz return sprintf(page, "%d", qmult); \ 11800a2430fSAndrzej Pietrasiewicz } \ 11900a2430fSAndrzej Pietrasiewicz \ 12000a2430fSAndrzej Pietrasiewicz static ssize_t _f_##_opts_qmult_store(struct f_##_f_##_opts *opts, \ 12100a2430fSAndrzej Pietrasiewicz const char *page, size_t len)\ 12200a2430fSAndrzej Pietrasiewicz { \ 12300a2430fSAndrzej Pietrasiewicz u8 val; \ 12400a2430fSAndrzej Pietrasiewicz int ret; \ 12500a2430fSAndrzej Pietrasiewicz \ 12600a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 12700a2430fSAndrzej Pietrasiewicz if (opts->refcnt) { \ 12800a2430fSAndrzej Pietrasiewicz ret = -EBUSY; \ 12900a2430fSAndrzej Pietrasiewicz goto out; \ 13000a2430fSAndrzej Pietrasiewicz } \ 13100a2430fSAndrzej Pietrasiewicz \ 13200a2430fSAndrzej Pietrasiewicz ret = kstrtou8(page, 0, &val); \ 13300a2430fSAndrzej Pietrasiewicz if (ret) \ 13400a2430fSAndrzej Pietrasiewicz goto out; \ 13500a2430fSAndrzej Pietrasiewicz \ 13600a2430fSAndrzej Pietrasiewicz gether_set_qmult(opts->net, val); \ 13700a2430fSAndrzej Pietrasiewicz ret = len; \ 13800a2430fSAndrzej Pietrasiewicz out: \ 13900a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 14000a2430fSAndrzej Pietrasiewicz return ret; \ 14100a2430fSAndrzej Pietrasiewicz } \ 14200a2430fSAndrzej Pietrasiewicz \ 14300a2430fSAndrzej Pietrasiewicz static struct f_##_f_##_opts_attribute f_##_f_##_opts_qmult = \ 14400a2430fSAndrzej Pietrasiewicz __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR, \ 14500a2430fSAndrzej Pietrasiewicz _f_##_opts_qmult_show, \ 14600a2430fSAndrzej Pietrasiewicz _f_##_opts_qmult_store) 14700a2430fSAndrzej Pietrasiewicz 14800a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_) \ 14900a2430fSAndrzej Pietrasiewicz static ssize_t _f_##_opts_ifname_show(struct f_##_f_##_opts *opts, \ 15000a2430fSAndrzej Pietrasiewicz char *page) \ 15100a2430fSAndrzej Pietrasiewicz { \ 15200a2430fSAndrzej Pietrasiewicz int ret; \ 15300a2430fSAndrzej Pietrasiewicz \ 15400a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 15500a2430fSAndrzej Pietrasiewicz ret = gether_get_ifname(opts->net, page, PAGE_SIZE); \ 15600a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 15700a2430fSAndrzej Pietrasiewicz \ 15800a2430fSAndrzej Pietrasiewicz return ret; \ 15900a2430fSAndrzej Pietrasiewicz } \ 16000a2430fSAndrzej Pietrasiewicz \ 16100a2430fSAndrzej Pietrasiewicz static struct f_##_f_##_opts_attribute f_##_f_##_opts_ifname = \ 16200a2430fSAndrzej Pietrasiewicz __CONFIGFS_ATTR_RO(ifname, _f_##_opts_ifname_show) 16300a2430fSAndrzej Pietrasiewicz 16400a2430fSAndrzej Pietrasiewicz #endif /* __U_ETHER_CONFIGFS_H */ 165