Bluetooth: hci_core: Move all debugfs handling to hci_debugfs.c

This moves hci_debugfs_create_basic to hci_debugfs.c which is where all
the others debugfs entries are handled.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
Luiz Augusto von Dentz 2021-09-21 11:25:04 -07:00 committed by Marcel Holtmann
parent 3e5f2d90c2
commit 8331dc487f
3 changed files with 128 additions and 124 deletions

View File

@ -62,130 +62,6 @@ DEFINE_MUTEX(hci_cb_list_lock);
/* HCI ID Numbering */
static DEFINE_IDA(hci_index_ida);
/* ---- HCI debugfs entries ---- */
static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y' : 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
struct sk_buff *skb;
bool enable;
int err;
if (!test_bit(HCI_UP, &hdev->flags))
return -ENETDOWN;
err = kstrtobool_from_user(user_buf, count, &enable);
if (err)
return err;
if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE))
return -EALREADY;
hci_req_sync_lock(hdev);
if (enable)
skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
HCI_CMD_TIMEOUT);
else
skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
HCI_CMD_TIMEOUT);
hci_req_sync_unlock(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
kfree_skb(skb);
hci_dev_change_flag(hdev, HCI_DUT_MODE);
return count;
}
static const struct file_operations dut_mode_fops = {
.open = simple_open,
.read = dut_mode_read,
.write = dut_mode_write,
.llseek = default_llseek,
};
static ssize_t vendor_diag_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) ? 'Y' : 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
bool enable;
int err;
err = kstrtobool_from_user(user_buf, count, &enable);
if (err)
return err;
/* When the diagnostic flags are not persistent and the transport
* is not active or in user channel operation, then there is no need
* for the vendor callback. Instead just store the desired value and
* the setting will be programmed when the controller gets powered on.
*/
if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
(!test_bit(HCI_RUNNING, &hdev->flags) ||
hci_dev_test_flag(hdev, HCI_USER_CHANNEL)))
goto done;
hci_req_sync_lock(hdev);
err = hdev->set_diag(hdev, enable);
hci_req_sync_unlock(hdev);
if (err < 0)
return err;
done:
if (enable)
hci_dev_set_flag(hdev, HCI_VENDOR_DIAG);
else
hci_dev_clear_flag(hdev, HCI_VENDOR_DIAG);
return count;
}
static const struct file_operations vendor_diag_fops = {
.open = simple_open,
.read = vendor_diag_read,
.write = vendor_diag_write,
.llseek = default_llseek,
};
static void hci_debugfs_create_basic(struct hci_dev *hdev)
{
debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
&dut_mode_fops);
if (hdev->set_diag)
debugfs_create_file("vendor_diag", 0644, hdev->debugfs, hdev,
&vendor_diag_fops);
}
static int hci_reset_req(struct hci_request *req, unsigned long opt)
{
BT_DBG("%s %ld", req->hdev->name, opt);

View File

@ -27,6 +27,7 @@
#include <net/bluetooth/hci_core.h>
#include "smp.h"
#include "hci_request.h"
#include "hci_debugfs.h"
#define DEFINE_QUIRK_ATTRIBUTE(__name, __quirk) \
@ -1250,3 +1251,125 @@ void hci_debugfs_create_conn(struct hci_conn *conn)
snprintf(name, sizeof(name), "%u", conn->handle);
conn->debugfs = debugfs_create_dir(name, hdev->debugfs);
}
static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y' : 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
struct sk_buff *skb;
bool enable;
int err;
if (!test_bit(HCI_UP, &hdev->flags))
return -ENETDOWN;
err = kstrtobool_from_user(user_buf, count, &enable);
if (err)
return err;
if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE))
return -EALREADY;
hci_req_sync_lock(hdev);
if (enable)
skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
HCI_CMD_TIMEOUT);
else
skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
HCI_CMD_TIMEOUT);
hci_req_sync_unlock(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
kfree_skb(skb);
hci_dev_change_flag(hdev, HCI_DUT_MODE);
return count;
}
static const struct file_operations dut_mode_fops = {
.open = simple_open,
.read = dut_mode_read,
.write = dut_mode_write,
.llseek = default_llseek,
};
static ssize_t vendor_diag_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) ? 'Y' : 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
bool enable;
int err;
err = kstrtobool_from_user(user_buf, count, &enable);
if (err)
return err;
/* When the diagnostic flags are not persistent and the transport
* is not active or in user channel operation, then there is no need
* for the vendor callback. Instead just store the desired value and
* the setting will be programmed when the controller gets powered on.
*/
if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
(!test_bit(HCI_RUNNING, &hdev->flags) ||
hci_dev_test_flag(hdev, HCI_USER_CHANNEL)))
goto done;
hci_req_sync_lock(hdev);
err = hdev->set_diag(hdev, enable);
hci_req_sync_unlock(hdev);
if (err < 0)
return err;
done:
if (enable)
hci_dev_set_flag(hdev, HCI_VENDOR_DIAG);
else
hci_dev_clear_flag(hdev, HCI_VENDOR_DIAG);
return count;
}
static const struct file_operations vendor_diag_fops = {
.open = simple_open,
.read = vendor_diag_read,
.write = vendor_diag_write,
.llseek = default_llseek,
};
void hci_debugfs_create_basic(struct hci_dev *hdev)
{
debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
&dut_mode_fops);
if (hdev->set_diag)
debugfs_create_file("vendor_diag", 0644, hdev->debugfs, hdev,
&vendor_diag_fops);
}

View File

@ -26,6 +26,7 @@ void hci_debugfs_create_common(struct hci_dev *hdev);
void hci_debugfs_create_bredr(struct hci_dev *hdev);
void hci_debugfs_create_le(struct hci_dev *hdev);
void hci_debugfs_create_conn(struct hci_conn *conn);
void hci_debugfs_create_basic(struct hci_dev *hdev);
#else
@ -45,4 +46,8 @@ static inline void hci_debugfs_create_conn(struct hci_conn *conn)
{
}
static inline void hci_debugfs_create_basic(struct hci_dev *hdev)
{
}
#endif