u_ether_configfs.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. #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. static ssize_t _f_##_opts_ifname_store(struct config_item *item, \
  146. const char *page, size_t len)\
  147. { \
  148. struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
  149. int ret = -EBUSY; \
  150. \
  151. mutex_lock(&opts->lock); \
  152. if (!opts->refcnt) \
  153. ret = gether_set_ifname(opts->net, page, len); \
  154. mutex_unlock(&opts->lock); \
  155. return ret ?: len; \
  156. } \
  157. \
  158. CONFIGFS_ATTR(_f_##_opts_, ifname)
  159. #define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \
  160. static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\
  161. char *page) \
  162. { \
  163. struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
  164. int ret; \
  165. \
  166. mutex_lock(&opts->lock); \
  167. ret = sprintf(page, "%02x\n", opts->_n_); \
  168. mutex_unlock(&opts->lock); \
  169. \
  170. return ret; \
  171. } \
  172. \
  173. static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\
  174. const char *page, \
  175. size_t len) \
  176. { \
  177. struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
  178. int ret = -EINVAL; \
  179. u8 val; \
  180. \
  181. mutex_lock(&opts->lock); \
  182. if (sscanf(page, "%02hhx", &val) > 0) { \
  183. opts->_n_ = val; \
  184. ret = len; \
  185. } \
  186. mutex_unlock(&opts->lock); \
  187. \
  188. return ret; \
  189. } \
  190. \
  191. CONFIGFS_ATTR(_f_##_opts_, _n_)
  192. #endif /* __U_ETHER_CONFIGFS_H */