linux/drivers/usb/gadget/function/u_ether_configfs.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * u_ether_configfs.h
   4 *
   5 * Utility definitions for configfs support in USB Ethernet functions
   6 *
   7 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
   8 *              http://www.samsung.com
   9 *
  10 * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
  11 */
  12
  13#ifndef __U_ETHER_CONFIGFS_H
  14#define __U_ETHER_CONFIGFS_H
  15
  16#define USB_ETHERNET_CONFIGFS_ITEM(_f_)                                 \
  17        static void _f_##_attr_release(struct config_item *item)        \
  18        {                                                               \
  19                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
  20                                                                        \
  21                usb_put_function_instance(&opts->func_inst);            \
  22        }                                                               \
  23                                                                        \
  24        static struct configfs_item_operations _f_##_item_ops = {       \
  25                .release        = _f_##_attr_release,                   \
  26        }
  27
  28#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_)                   \
  29        static ssize_t _f_##_opts_dev_addr_show(struct config_item *item, \
  30                                                char *page)             \
  31        {                                                               \
  32                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
  33                int result;                                             \
  34                                                                        \
  35                mutex_lock(&opts->lock);                                \
  36                result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \
  37                mutex_unlock(&opts->lock);                              \
  38                                                                        \
  39                return result;                                          \
  40        }                                                               \
  41                                                                        \
  42        static ssize_t _f_##_opts_dev_addr_store(struct config_item *item, \
  43                                                 const char *page, size_t len)\
  44        {                                                               \
  45                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
  46                int ret;                                                \
  47                                                                        \
  48                mutex_lock(&opts->lock);                                \
  49                if (opts->refcnt) {                                     \
  50                        mutex_unlock(&opts->lock);                      \
  51                        return -EBUSY;                                  \
  52                }                                                       \
  53                                                                        \
  54                ret = gether_set_dev_addr(opts->net, page);             \
  55                mutex_unlock(&opts->lock);                              \
  56                if (!ret)                                               \
  57                        ret = len;                                      \
  58                return ret;                                             \
  59        }                                                               \
  60                                                                        \
  61        CONFIGFS_ATTR(_f_##_opts_, dev_addr)
  62
  63#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_)                  \
  64        static ssize_t _f_##_opts_host_addr_show(struct config_item *item, \
  65                                                 char *page)            \
  66        {                                                               \
  67                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
  68                int result;                                             \
  69                                                                        \
  70                mutex_lock(&opts->lock);                                \
  71                result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \
  72                mutex_unlock(&opts->lock);                              \
  73                                                                        \
  74                return result;                                          \
  75        }                                                               \
  76                                                                        \
  77        static ssize_t _f_##_opts_host_addr_store(struct config_item *item, \
  78                                                  const char *page, size_t len)\
  79        {                                                               \
  80                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
  81                int ret;                                                \
  82                                                                        \
  83                mutex_lock(&opts->lock);                                \
  84                if (opts->refcnt) {                                     \
  85                        mutex_unlock(&opts->lock);                      \
  86                        return -EBUSY;                                  \
  87                }                                                       \
  88                                                                        \
  89                ret = gether_set_host_addr(opts->net, page);            \
  90                mutex_unlock(&opts->lock);                              \
  91                if (!ret)                                               \
  92                        ret = len;                                      \
  93                return ret;                                             \
  94        }                                                               \
  95                                                                        \
  96        CONFIGFS_ATTR(_f_##_opts_, host_addr)
  97
  98#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_)                      \
  99        static ssize_t _f_##_opts_qmult_show(struct config_item *item,  \
 100                                             char *page)                \
 101        {                                                               \
 102                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
 103                unsigned qmult;                                         \
 104                                                                        \
 105                mutex_lock(&opts->lock);                                \
 106                qmult = gether_get_qmult(opts->net);                    \
 107                mutex_unlock(&opts->lock);                              \
 108                return sprintf(page, "%d\n", qmult);                    \
 109        }                                                               \
 110                                                                        \
 111        static ssize_t _f_##_opts_qmult_store(struct config_item *item, \
 112                                              const char *page, size_t len)\
 113        {                                                               \
 114                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
 115                u8 val;                                                 \
 116                int ret;                                                \
 117                                                                        \
 118                mutex_lock(&opts->lock);                                \
 119                if (opts->refcnt) {                                     \
 120                        ret = -EBUSY;                                   \
 121                        goto out;                                       \
 122                }                                                       \
 123                                                                        \
 124                ret = kstrtou8(page, 0, &val);                          \
 125                if (ret)                                                \
 126                        goto out;                                       \
 127                                                                        \
 128                gether_set_qmult(opts->net, val);                       \
 129                ret = len;                                              \
 130out:                                                                    \
 131                mutex_unlock(&opts->lock);                              \
 132                return ret;                                             \
 133        }                                                               \
 134                                                                        \
 135        CONFIGFS_ATTR(_f_##_opts_, qmult)
 136
 137#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_)                     \
 138        static ssize_t _f_##_opts_ifname_show(struct config_item *item, \
 139                                              char *page)               \
 140        {                                                               \
 141                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
 142                int ret;                                                \
 143                                                                        \
 144                mutex_lock(&opts->lock);                                \
 145                ret = gether_get_ifname(opts->net, page, PAGE_SIZE);    \
 146                mutex_unlock(&opts->lock);                              \
 147                                                                        \
 148                return ret;                                             \
 149        }                                                               \
 150                                                                        \
 151        static ssize_t _f_##_opts_ifname_store(struct config_item *item, \
 152                                               const char *page, size_t len)\
 153        {                                                               \
 154                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
 155                int ret = -EBUSY;                                       \
 156                                                                        \
 157                mutex_lock(&opts->lock);                                \
 158                if (!opts->refcnt)                                      \
 159                        ret = gether_set_ifname(opts->net, page, len);  \
 160                mutex_unlock(&opts->lock);                              \
 161                return ret ?: len;                                      \
 162        }                                                               \
 163                                                                        \
 164        CONFIGFS_ATTR(_f_##_opts_, ifname)
 165
 166#define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_)                    \
 167        static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\
 168                                               char *page)              \
 169        {                                                               \
 170                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
 171                int ret;                                                \
 172                                                                        \
 173                mutex_lock(&opts->lock);                                \
 174                ret = sprintf(page, "%02x\n", opts->_n_);               \
 175                mutex_unlock(&opts->lock);                              \
 176                                                                        \
 177                return ret;                                             \
 178        }                                                               \
 179                                                                        \
 180        static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\
 181                                                const char *page,       \
 182                                                size_t len)             \
 183        {                                                               \
 184                struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
 185                int ret = -EINVAL;                                      \
 186                u8 val;                                                 \
 187                                                                        \
 188                mutex_lock(&opts->lock);                                \
 189                if (sscanf(page, "%02hhx", &val) > 0) {                 \
 190                        opts->_n_ = val;                                \
 191                        ret = len;                                      \
 192                }                                                       \
 193                mutex_unlock(&opts->lock);                              \
 194                                                                        \
 195                return ret;                                             \
 196        }                                                               \
 197                                                                        \
 198        CONFIGFS_ATTR(_f_##_opts_, _n_)
 199
 200#endif /* __U_ETHER_CONFIGFS_H */
 201