btmrvl_debugfs.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /**
  2. * Marvell Bluetooth driver: debugfs related functions
  3. *
  4. * Copyright (C) 2009, Marvell International Ltd.
  5. *
  6. * This software file (the "File") is distributed by Marvell International
  7. * Ltd. under the terms of the GNU General Public License Version 2, June 1991
  8. * (the "License"). You may use, redistribute and/or modify this File in
  9. * accordance with the terms and conditions of the License, a copy of which
  10. * is available by writing to the Free Software Foundation, Inc.,
  11. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  12. * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  13. *
  14. *
  15. * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
  18. * this warranty disclaimer.
  19. **/
  20. #include <linux/debugfs.h>
  21. #include <linux/slab.h>
  22. #include <net/bluetooth/bluetooth.h>
  23. #include <net/bluetooth/hci_core.h>
  24. #include "btmrvl_drv.h"
  25. struct btmrvl_debugfs_data {
  26. struct dentry *config_dir;
  27. struct dentry *status_dir;
  28. /* config */
  29. struct dentry *psmode;
  30. struct dentry *pscmd;
  31. struct dentry *hsmode;
  32. struct dentry *hscmd;
  33. struct dentry *gpiogap;
  34. struct dentry *hscfgcmd;
  35. /* status */
  36. struct dentry *curpsmode;
  37. struct dentry *hsstate;
  38. struct dentry *psstate;
  39. struct dentry *txdnldready;
  40. };
  41. static ssize_t btmrvl_hscfgcmd_write(struct file *file,
  42. const char __user *ubuf, size_t count, loff_t *ppos)
  43. {
  44. struct btmrvl_private *priv = file->private_data;
  45. char buf[16];
  46. long result, ret;
  47. memset(buf, 0, sizeof(buf));
  48. if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
  49. return -EFAULT;
  50. ret = strict_strtol(buf, 10, &result);
  51. if (ret)
  52. return ret;
  53. priv->btmrvl_dev.hscfgcmd = result;
  54. if (priv->btmrvl_dev.hscfgcmd) {
  55. btmrvl_prepare_command(priv);
  56. wake_up_interruptible(&priv->main_thread.wait_q);
  57. }
  58. return count;
  59. }
  60. static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf,
  61. size_t count, loff_t *ppos)
  62. {
  63. struct btmrvl_private *priv = file->private_data;
  64. char buf[16];
  65. int ret;
  66. ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
  67. priv->btmrvl_dev.hscfgcmd);
  68. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  69. }
  70. static const struct file_operations btmrvl_hscfgcmd_fops = {
  71. .read = btmrvl_hscfgcmd_read,
  72. .write = btmrvl_hscfgcmd_write,
  73. .open = simple_open,
  74. .llseek = default_llseek,
  75. };
  76. static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf,
  77. size_t count, loff_t *ppos)
  78. {
  79. struct btmrvl_private *priv = file->private_data;
  80. char buf[16];
  81. long result, ret;
  82. memset(buf, 0, sizeof(buf));
  83. if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
  84. return -EFAULT;
  85. ret = strict_strtol(buf, 10, &result);
  86. if (ret)
  87. return ret;
  88. priv->btmrvl_dev.psmode = result;
  89. return count;
  90. }
  91. static ssize_t btmrvl_psmode_read(struct file *file, char __user *userbuf,
  92. size_t count, loff_t *ppos)
  93. {
  94. struct btmrvl_private *priv = file->private_data;
  95. char buf[16];
  96. int ret;
  97. ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
  98. priv->btmrvl_dev.psmode);
  99. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  100. }
  101. static const struct file_operations btmrvl_psmode_fops = {
  102. .read = btmrvl_psmode_read,
  103. .write = btmrvl_psmode_write,
  104. .open = simple_open,
  105. .llseek = default_llseek,
  106. };
  107. static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
  108. size_t count, loff_t *ppos)
  109. {
  110. struct btmrvl_private *priv = file->private_data;
  111. char buf[16];
  112. long result, ret;
  113. memset(buf, 0, sizeof(buf));
  114. if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
  115. return -EFAULT;
  116. ret = strict_strtol(buf, 10, &result);
  117. if (ret)
  118. return ret;
  119. priv->btmrvl_dev.pscmd = result;
  120. if (priv->btmrvl_dev.pscmd) {
  121. btmrvl_prepare_command(priv);
  122. wake_up_interruptible(&priv->main_thread.wait_q);
  123. }
  124. return count;
  125. }
  126. static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf,
  127. size_t count, loff_t *ppos)
  128. {
  129. struct btmrvl_private *priv = file->private_data;
  130. char buf[16];
  131. int ret;
  132. ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.pscmd);
  133. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  134. }
  135. static const struct file_operations btmrvl_pscmd_fops = {
  136. .read = btmrvl_pscmd_read,
  137. .write = btmrvl_pscmd_write,
  138. .open = simple_open,
  139. .llseek = default_llseek,
  140. };
  141. static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf,
  142. size_t count, loff_t *ppos)
  143. {
  144. struct btmrvl_private *priv = file->private_data;
  145. char buf[16];
  146. long result, ret;
  147. memset(buf, 0, sizeof(buf));
  148. if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
  149. return -EFAULT;
  150. ret = strict_strtol(buf, 16, &result);
  151. if (ret)
  152. return ret;
  153. priv->btmrvl_dev.gpio_gap = result;
  154. return count;
  155. }
  156. static ssize_t btmrvl_gpiogap_read(struct file *file, char __user *userbuf,
  157. size_t count, loff_t *ppos)
  158. {
  159. struct btmrvl_private *priv = file->private_data;
  160. char buf[16];
  161. int ret;
  162. ret = snprintf(buf, sizeof(buf) - 1, "0x%x\n",
  163. priv->btmrvl_dev.gpio_gap);
  164. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  165. }
  166. static const struct file_operations btmrvl_gpiogap_fops = {
  167. .read = btmrvl_gpiogap_read,
  168. .write = btmrvl_gpiogap_write,
  169. .open = simple_open,
  170. .llseek = default_llseek,
  171. };
  172. static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
  173. size_t count, loff_t *ppos)
  174. {
  175. struct btmrvl_private *priv = file->private_data;
  176. char buf[16];
  177. long result, ret;
  178. memset(buf, 0, sizeof(buf));
  179. if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
  180. return -EFAULT;
  181. ret = strict_strtol(buf, 10, &result);
  182. if (ret)
  183. return ret;
  184. priv->btmrvl_dev.hscmd = result;
  185. if (priv->btmrvl_dev.hscmd) {
  186. btmrvl_prepare_command(priv);
  187. wake_up_interruptible(&priv->main_thread.wait_q);
  188. }
  189. return count;
  190. }
  191. static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf,
  192. size_t count, loff_t *ppos)
  193. {
  194. struct btmrvl_private *priv = file->private_data;
  195. char buf[16];
  196. int ret;
  197. ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hscmd);
  198. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  199. }
  200. static const struct file_operations btmrvl_hscmd_fops = {
  201. .read = btmrvl_hscmd_read,
  202. .write = btmrvl_hscmd_write,
  203. .open = simple_open,
  204. .llseek = default_llseek,
  205. };
  206. static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf,
  207. size_t count, loff_t *ppos)
  208. {
  209. struct btmrvl_private *priv = file->private_data;
  210. char buf[16];
  211. long result, ret;
  212. memset(buf, 0, sizeof(buf));
  213. if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
  214. return -EFAULT;
  215. ret = strict_strtol(buf, 10, &result);
  216. if (ret)
  217. return ret;
  218. priv->btmrvl_dev.hsmode = result;
  219. return count;
  220. }
  221. static ssize_t btmrvl_hsmode_read(struct file *file, char __user * userbuf,
  222. size_t count, loff_t *ppos)
  223. {
  224. struct btmrvl_private *priv = file->private_data;
  225. char buf[16];
  226. int ret;
  227. ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hsmode);
  228. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  229. }
  230. static const struct file_operations btmrvl_hsmode_fops = {
  231. .read = btmrvl_hsmode_read,
  232. .write = btmrvl_hsmode_write,
  233. .open = simple_open,
  234. .llseek = default_llseek,
  235. };
  236. static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf,
  237. size_t count, loff_t *ppos)
  238. {
  239. struct btmrvl_private *priv = file->private_data;
  240. char buf[16];
  241. int ret;
  242. ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->psmode);
  243. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  244. }
  245. static const struct file_operations btmrvl_curpsmode_fops = {
  246. .read = btmrvl_curpsmode_read,
  247. .open = simple_open,
  248. .llseek = default_llseek,
  249. };
  250. static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf,
  251. size_t count, loff_t *ppos)
  252. {
  253. struct btmrvl_private *priv = file->private_data;
  254. char buf[16];
  255. int ret;
  256. ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->ps_state);
  257. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  258. }
  259. static const struct file_operations btmrvl_psstate_fops = {
  260. .read = btmrvl_psstate_read,
  261. .open = simple_open,
  262. .llseek = default_llseek,
  263. };
  264. static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf,
  265. size_t count, loff_t *ppos)
  266. {
  267. struct btmrvl_private *priv = file->private_data;
  268. char buf[16];
  269. int ret;
  270. ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->hs_state);
  271. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  272. }
  273. static const struct file_operations btmrvl_hsstate_fops = {
  274. .read = btmrvl_hsstate_read,
  275. .open = simple_open,
  276. .llseek = default_llseek,
  277. };
  278. static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf,
  279. size_t count, loff_t *ppos)
  280. {
  281. struct btmrvl_private *priv = file->private_data;
  282. char buf[16];
  283. int ret;
  284. ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
  285. priv->btmrvl_dev.tx_dnld_rdy);
  286. return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  287. }
  288. static const struct file_operations btmrvl_txdnldready_fops = {
  289. .read = btmrvl_txdnldready_read,
  290. .open = simple_open,
  291. .llseek = default_llseek,
  292. };
  293. void btmrvl_debugfs_init(struct hci_dev *hdev)
  294. {
  295. struct btmrvl_private *priv = hci_get_drvdata(hdev);
  296. struct btmrvl_debugfs_data *dbg;
  297. if (!hdev->debugfs)
  298. return;
  299. dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
  300. priv->debugfs_data = dbg;
  301. if (!dbg) {
  302. BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
  303. return;
  304. }
  305. dbg->config_dir = debugfs_create_dir("config", hdev->debugfs);
  306. dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir,
  307. priv, &btmrvl_psmode_fops);
  308. dbg->pscmd = debugfs_create_file("pscmd", 0644, dbg->config_dir,
  309. priv, &btmrvl_pscmd_fops);
  310. dbg->gpiogap = debugfs_create_file("gpiogap", 0644, dbg->config_dir,
  311. priv, &btmrvl_gpiogap_fops);
  312. dbg->hsmode = debugfs_create_file("hsmode", 0644, dbg->config_dir,
  313. priv, &btmrvl_hsmode_fops);
  314. dbg->hscmd = debugfs_create_file("hscmd", 0644, dbg->config_dir,
  315. priv, &btmrvl_hscmd_fops);
  316. dbg->hscfgcmd = debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
  317. priv, &btmrvl_hscfgcmd_fops);
  318. dbg->status_dir = debugfs_create_dir("status", hdev->debugfs);
  319. dbg->curpsmode = debugfs_create_file("curpsmode", 0444,
  320. dbg->status_dir, priv,
  321. &btmrvl_curpsmode_fops);
  322. dbg->psstate = debugfs_create_file("psstate", 0444, dbg->status_dir,
  323. priv, &btmrvl_psstate_fops);
  324. dbg->hsstate = debugfs_create_file("hsstate", 0444, dbg->status_dir,
  325. priv, &btmrvl_hsstate_fops);
  326. dbg->txdnldready = debugfs_create_file("txdnldready", 0444,
  327. dbg->status_dir, priv,
  328. &btmrvl_txdnldready_fops);
  329. }
  330. void btmrvl_debugfs_remove(struct hci_dev *hdev)
  331. {
  332. struct btmrvl_private *priv = hci_get_drvdata(hdev);
  333. struct btmrvl_debugfs_data *dbg = priv->debugfs_data;
  334. if (!dbg)
  335. return;
  336. debugfs_remove(dbg->psmode);
  337. debugfs_remove(dbg->pscmd);
  338. debugfs_remove(dbg->gpiogap);
  339. debugfs_remove(dbg->hsmode);
  340. debugfs_remove(dbg->hscmd);
  341. debugfs_remove(dbg->hscfgcmd);
  342. debugfs_remove(dbg->config_dir);
  343. debugfs_remove(dbg->curpsmode);
  344. debugfs_remove(dbg->psstate);
  345. debugfs_remove(dbg->hsstate);
  346. debugfs_remove(dbg->txdnldready);
  347. debugfs_remove(dbg->status_dir);
  348. kfree(dbg);
  349. }