Bluetooth: Add debugfs fields for hardware and firmware info
Some Bluetooth controllers allow for reading hardware and firmware related vendor specific infos. If they are available, then they can be exposed via debugfs now. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
f962fe32f2
commit
5177a83827
3 changed files with 63 additions and 0 deletions
|
@ -372,6 +372,8 @@ struct hci_dev {
|
|||
|
||||
atomic_t promisc;
|
||||
|
||||
const char *hw_info;
|
||||
const char *fw_info;
|
||||
struct dentry *debugfs;
|
||||
|
||||
struct device dev;
|
||||
|
@ -1024,6 +1026,8 @@ int hci_resume_dev(struct hci_dev *hdev);
|
|||
int hci_reset_dev(struct hci_dev *hdev);
|
||||
int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);
|
||||
int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb);
|
||||
void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...);
|
||||
void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...);
|
||||
int hci_dev_open(__u16 dev);
|
||||
int hci_dev_close(__u16 dev);
|
||||
int hci_dev_do_close(struct hci_dev *hdev);
|
||||
|
|
|
@ -3163,6 +3163,8 @@ void hci_unregister_dev(struct hci_dev *hdev)
|
|||
device_del(&hdev->dev);
|
||||
|
||||
debugfs_remove_recursive(hdev->debugfs);
|
||||
kfree_const(hdev->hw_info);
|
||||
kfree_const(hdev->fw_info);
|
||||
|
||||
destroy_workqueue(hdev->workqueue);
|
||||
destroy_workqueue(hdev->req_workqueue);
|
||||
|
@ -3266,6 +3268,28 @@ int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
}
|
||||
EXPORT_SYMBOL(hci_recv_diag);
|
||||
|
||||
void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
|
||||
{
|
||||
va_list vargs;
|
||||
|
||||
va_start(vargs, fmt);
|
||||
kfree_const(hdev->hw_info);
|
||||
hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
|
||||
va_end(vargs);
|
||||
}
|
||||
EXPORT_SYMBOL(hci_set_hw_info);
|
||||
|
||||
void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
|
||||
{
|
||||
va_list vargs;
|
||||
|
||||
va_start(vargs, fmt);
|
||||
kfree_const(hdev->fw_info);
|
||||
hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
|
||||
va_end(vargs);
|
||||
}
|
||||
EXPORT_SYMBOL(hci_set_fw_info);
|
||||
|
||||
/* ---- Interface to upper protocols ---- */
|
||||
|
||||
int hci_register_cb(struct hci_cb *cb)
|
||||
|
|
|
@ -76,6 +76,30 @@ static const struct file_operations __name ## _fops = { \
|
|||
.llseek = default_llseek, \
|
||||
} \
|
||||
|
||||
#define DEFINE_INFO_ATTRIBUTE(__name, __field) \
|
||||
static int __name ## _show(struct seq_file *f, void *ptr) \
|
||||
{ \
|
||||
struct hci_dev *hdev = f->private; \
|
||||
\
|
||||
hci_dev_lock(hdev); \
|
||||
seq_printf(f, "%s\n", hdev->__field ? : ""); \
|
||||
hci_dev_unlock(hdev); \
|
||||
\
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int __name ## _open(struct inode *inode, struct file *file) \
|
||||
{ \
|
||||
return single_open(file, __name ## _show, inode->i_private); \
|
||||
} \
|
||||
\
|
||||
static const struct file_operations __name ## _fops = { \
|
||||
.open = __name ## _open, \
|
||||
.read = seq_read, \
|
||||
.llseek = seq_lseek, \
|
||||
.release = single_release, \
|
||||
} \
|
||||
|
||||
static int features_show(struct seq_file *f, void *ptr)
|
||||
{
|
||||
struct hci_dev *hdev = f->private;
|
||||
|
@ -349,6 +373,9 @@ static const struct file_operations sc_only_mode_fops = {
|
|||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
DEFINE_INFO_ATTRIBUTE(hardware_info, hw_info);
|
||||
DEFINE_INFO_ATTRIBUTE(firmware_info, fw_info);
|
||||
|
||||
void hci_debugfs_create_common(struct hci_dev *hdev)
|
||||
{
|
||||
debugfs_create_file("features", 0444, hdev->debugfs, hdev,
|
||||
|
@ -382,6 +409,14 @@ void hci_debugfs_create_common(struct hci_dev *hdev)
|
|||
if (lmp_sc_capable(hdev) || lmp_le_capable(hdev))
|
||||
debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
|
||||
hdev, &sc_only_mode_fops);
|
||||
|
||||
if (hdev->hw_info)
|
||||
debugfs_create_file("hardware_info", 0444, hdev->debugfs,
|
||||
hdev, &hardware_info_fops);
|
||||
|
||||
if (hdev->fw_info)
|
||||
debugfs_create_file("firmware_info", 0444, hdev->debugfs,
|
||||
hdev, &firmware_info_fops);
|
||||
}
|
||||
|
||||
static int inquiry_cache_show(struct seq_file *f, void *p)
|
||||
|
|
Loading…
Reference in a new issue