0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/debugfs.h>
0009 #include <linux/slab.h>
0010
0011 #include <net/bluetooth/bluetooth.h>
0012 #include <net/bluetooth/hci_core.h>
0013
0014 #include "btmrvl_drv.h"
0015
0016 struct btmrvl_debugfs_data {
0017 struct dentry *config_dir;
0018 struct dentry *status_dir;
0019 };
0020
0021 static ssize_t btmrvl_hscfgcmd_write(struct file *file,
0022 const char __user *ubuf, size_t count, loff_t *ppos)
0023 {
0024 struct btmrvl_private *priv = file->private_data;
0025 long result, ret;
0026
0027 ret = kstrtol_from_user(ubuf, count, 10, &result);
0028 if (ret)
0029 return ret;
0030
0031 priv->btmrvl_dev.hscfgcmd = result;
0032
0033 if (priv->btmrvl_dev.hscfgcmd) {
0034 btmrvl_prepare_command(priv);
0035 wake_up_interruptible(&priv->main_thread.wait_q);
0036 }
0037
0038 return count;
0039 }
0040
0041 static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf,
0042 size_t count, loff_t *ppos)
0043 {
0044 struct btmrvl_private *priv = file->private_data;
0045 char buf[16];
0046 int ret;
0047
0048 ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
0049 priv->btmrvl_dev.hscfgcmd);
0050
0051 return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
0052 }
0053
0054 static const struct file_operations btmrvl_hscfgcmd_fops = {
0055 .read = btmrvl_hscfgcmd_read,
0056 .write = btmrvl_hscfgcmd_write,
0057 .open = simple_open,
0058 .llseek = default_llseek,
0059 };
0060
0061 static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
0062 size_t count, loff_t *ppos)
0063 {
0064 struct btmrvl_private *priv = file->private_data;
0065 long result, ret;
0066
0067 ret = kstrtol_from_user(ubuf, count, 10, &result);
0068 if (ret)
0069 return ret;
0070
0071 priv->btmrvl_dev.pscmd = result;
0072
0073 if (priv->btmrvl_dev.pscmd) {
0074 btmrvl_prepare_command(priv);
0075 wake_up_interruptible(&priv->main_thread.wait_q);
0076 }
0077
0078 return count;
0079
0080 }
0081
0082 static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf,
0083 size_t count, loff_t *ppos)
0084 {
0085 struct btmrvl_private *priv = file->private_data;
0086 char buf[16];
0087 int ret;
0088
0089 ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.pscmd);
0090
0091 return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
0092 }
0093
0094 static const struct file_operations btmrvl_pscmd_fops = {
0095 .read = btmrvl_pscmd_read,
0096 .write = btmrvl_pscmd_write,
0097 .open = simple_open,
0098 .llseek = default_llseek,
0099 };
0100
0101 static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
0102 size_t count, loff_t *ppos)
0103 {
0104 struct btmrvl_private *priv = file->private_data;
0105 long result, ret;
0106
0107 ret = kstrtol_from_user(ubuf, count, 10, &result);
0108 if (ret)
0109 return ret;
0110
0111 priv->btmrvl_dev.hscmd = result;
0112 if (priv->btmrvl_dev.hscmd) {
0113 btmrvl_prepare_command(priv);
0114 wake_up_interruptible(&priv->main_thread.wait_q);
0115 }
0116
0117 return count;
0118 }
0119
0120 static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf,
0121 size_t count, loff_t *ppos)
0122 {
0123 struct btmrvl_private *priv = file->private_data;
0124 char buf[16];
0125 int ret;
0126
0127 ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hscmd);
0128
0129 return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
0130 }
0131
0132 static const struct file_operations btmrvl_hscmd_fops = {
0133 .read = btmrvl_hscmd_read,
0134 .write = btmrvl_hscmd_write,
0135 .open = simple_open,
0136 .llseek = default_llseek,
0137 };
0138
0139 void btmrvl_debugfs_init(struct hci_dev *hdev)
0140 {
0141 struct btmrvl_private *priv = hci_get_drvdata(hdev);
0142 struct btmrvl_debugfs_data *dbg;
0143
0144 if (!hdev->debugfs)
0145 return;
0146
0147 dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
0148 priv->debugfs_data = dbg;
0149
0150 if (!dbg) {
0151 BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
0152 return;
0153 }
0154
0155 dbg->config_dir = debugfs_create_dir("config", hdev->debugfs);
0156
0157 debugfs_create_u8("psmode", 0644, dbg->config_dir,
0158 &priv->btmrvl_dev.psmode);
0159 debugfs_create_file("pscmd", 0644, dbg->config_dir,
0160 priv, &btmrvl_pscmd_fops);
0161 debugfs_create_x16("gpiogap", 0644, dbg->config_dir,
0162 &priv->btmrvl_dev.gpio_gap);
0163 debugfs_create_u8("hsmode", 0644, dbg->config_dir,
0164 &priv->btmrvl_dev.hsmode);
0165 debugfs_create_file("hscmd", 0644, dbg->config_dir,
0166 priv, &btmrvl_hscmd_fops);
0167 debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
0168 priv, &btmrvl_hscfgcmd_fops);
0169
0170 dbg->status_dir = debugfs_create_dir("status", hdev->debugfs);
0171 debugfs_create_u8("curpsmode", 0444, dbg->status_dir,
0172 &priv->adapter->psmode);
0173 debugfs_create_u8("psstate", 0444, dbg->status_dir,
0174 &priv->adapter->ps_state);
0175 debugfs_create_u8("hsstate", 0444, dbg->status_dir,
0176 &priv->adapter->hs_state);
0177 debugfs_create_u8("txdnldready", 0444, dbg->status_dir,
0178 &priv->btmrvl_dev.tx_dnld_rdy);
0179 }
0180
0181 void btmrvl_debugfs_remove(struct hci_dev *hdev)
0182 {
0183 struct btmrvl_private *priv = hci_get_drvdata(hdev);
0184 struct btmrvl_debugfs_data *dbg = priv->debugfs_data;
0185
0186 if (!dbg)
0187 return;
0188
0189 debugfs_remove_recursive(dbg->config_dir);
0190 debugfs_remove_recursive(dbg->status_dir);
0191
0192 kfree(dbg);
0193 }