u_ether_configfs.h 5.1 KB

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