| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifndef __U_ETHER_CONFIGFS_H |
| #define __U_ETHER_CONFIGFS_H |
| |
| #define USB_ETHERNET_CONFIGFS_ITEM(_f_) \ |
| <------>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, \ |
| <------>} |
| |
| #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_) \ |
| <------>static ssize_t _f_##_opts_dev_addr_show(struct config_item *item, \ |
| <------><------><------><------><------><------>char *page) \ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>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 config_item *item, \ |
| <------><------><------><------><------><------> const char *page, size_t len)\ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>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; \ |
| <------>} \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------>CONFIGFS_ATTR(_f_##_opts_, dev_addr) |
| |
| #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_) \ |
| <------>static ssize_t _f_##_opts_host_addr_show(struct config_item *item, \ |
| <------><------><------><------><------><------> char *page) \ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>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 config_item *item, \ |
| <------><------><------><------><------><------> const char *page, size_t len)\ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>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; \ |
| <------>} \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------>CONFIGFS_ATTR(_f_##_opts_, host_addr) |
| |
| #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_) \ |
| <------>static ssize_t _f_##_opts_qmult_show(struct config_item *item, \ |
| <------><------><------><------><------> char *page) \ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>unsigned qmult; \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------><------>mutex_lock(&opts->lock); \ |
| <------><------>qmult = gether_get_qmult(opts->net); \ |
| <------><------>mutex_unlock(&opts->lock); \ |
| <------><------>return sprintf(page, "%d\n", qmult); \ |
| <------>} \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------>static ssize_t _f_##_opts_qmult_store(struct config_item *item, \ |
| <------><------><------><------><------> const char *page, size_t len)\ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>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; \ |
| <------>} \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------>CONFIGFS_ATTR(_f_##_opts_, qmult) |
| |
| #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_) \ |
| <------>static ssize_t _f_##_opts_ifname_show(struct config_item *item, \ |
| <------><------><------><------><------> char *page) \ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>int ret; \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------><------>mutex_lock(&opts->lock); \ |
| <------><------>ret = gether_get_ifname(opts->net, page, PAGE_SIZE); \ |
| <------><------>mutex_unlock(&opts->lock); \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------><------>return ret; \ |
| <------>} \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------>static ssize_t _f_##_opts_ifname_store(struct config_item *item, \ |
| <------><------><------><------><------> const char *page, size_t len)\ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>int ret = -EBUSY; \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------><------>mutex_lock(&opts->lock); \ |
| <------><------>if (!opts->refcnt) \ |
| <------><------><------>ret = gether_set_ifname(opts->net, page, len); \ |
| <------><------>mutex_unlock(&opts->lock); \ |
| <------><------>return ret ?: len; \ |
| <------>} \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------>CONFIGFS_ATTR(_f_##_opts_, ifname) |
| |
| #define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \ |
| <------>static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\ |
| <------><------><------><------><------> char *page) \ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>int ret; \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------><------>mutex_lock(&opts->lock); \ |
| <------><------>ret = sprintf(page, "%02x\n", opts->_n_); \ |
| <------><------>mutex_unlock(&opts->lock); \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------><------>return ret; \ |
| <------>} \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------>static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\ |
| <------><------><------><------><------><------>const char *page, \ |
| <------><------><------><------><------><------>size_t len) \ |
| <------>{ \ |
| <------><------>struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ |
| <------><------>int ret = -EINVAL; \ |
| <------><------>u8 val; \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------><------>mutex_lock(&opts->lock); \ |
| <------><------>if (sscanf(page, "%02hhx", &val) > 0) { \ |
| <------><------><------>opts->_n_ = val; \ |
| <------><------><------>ret = len; \ |
| <------><------>} \ |
| <------><------>mutex_unlock(&opts->lock); \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------><------>return ret; \ |
| <------>} \ |
| <------><------><------><------><------><------><------><------><------>\ |
| <------>CONFIGFS_ATTR(_f_##_opts_, _n_) |
| |
| #endif |
| |