327 lines
8.3 KiB
C
327 lines
8.3 KiB
C
|
#include <linux/kernel.h>
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/slab.h>
|
||
|
#include <linux/debugfs.h>
|
||
|
#include <linux/uaccess.h>
|
||
|
#include <linux/seq_file.h>
|
||
|
#include <linux/proc_fs.h>
|
||
|
|
||
|
#define VERSION "1.0"
|
||
|
#define FILE_MODE 0666
|
||
|
#define BUF_LEN 2048
|
||
|
|
||
|
static struct dentry *fdi_root;
|
||
|
static struct dentry *dbghci;
|
||
|
static struct dentry *dbgacl;
|
||
|
static struct dentry *dbglmp;
|
||
|
static struct dentry *dbgker;
|
||
|
static struct dentry *dbglog;
|
||
|
static struct dentry *dbgctl;
|
||
|
|
||
|
static char debug_reg_bf[BUF_LEN];
|
||
|
static char debug_tag_bf[BUF_LEN];
|
||
|
static char debug_enm_bf[BUF_LEN];
|
||
|
static char debug_pkt_bf[BUF_LEN];
|
||
|
static char debug_lmp_bf[BUF_LEN];
|
||
|
|
||
|
static ssize_t reg_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
printk(KERN_DEBUG"loff_t:%lld,count:%d\n", *ppos, (int)count);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
if (copy_to_user(buffer, debug_reg_bf + *ppos, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
// memset(debug_reg_bf, 0 ,sizeof(debug_reg_bf));
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t reg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
printk(KERN_DEBUG"loff_t:%lld\n", *ppos);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
memset(debug_reg_bf, 0, BUF_LEN);
|
||
|
if (copy_from_user(debug_reg_bf + *ppos, buffer, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t tag_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
printk(KERN_DEBUG"loff_t:%lld,count:%d\n", *ppos, (int)count);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
if (copy_to_user(buffer, debug_tag_bf + *ppos, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t tag_write(struct file *filp, const char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
|
||
|
printk(KERN_DEBUG"loff_t:%lld\n", *ppos);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
memset(debug_tag_bf, 0, BUF_LEN);
|
||
|
if (copy_from_user(debug_tag_bf + *ppos, buffer, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t enm_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
|
||
|
printk(KERN_DEBUG"loff_t:%lld,count:%d\n", *ppos, (int)count);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
if (copy_to_user(buffer, debug_enm_bf + *ppos, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t enm_write(struct file *filp, const char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
printk(KERN_DEBUG"loff_t:%lld\n", *ppos);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
memset(debug_enm_bf, 0, BUF_LEN);
|
||
|
if (copy_from_user(debug_enm_bf + *ppos, buffer, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t pkt_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
|
||
|
printk(KERN_DEBUG"loff_t:%lld,count:%d\n", *ppos, (int)count);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
if (copy_to_user(buffer, debug_pkt_bf + *ppos, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t pkt_write(struct file *filp, const char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
printk(KERN_DEBUG"loff_t:%lld\n", *ppos);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
memset(debug_pkt_bf, 0, BUF_LEN);
|
||
|
if (copy_from_user(debug_pkt_bf + *ppos, buffer, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t lmp_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
printk(KERN_DEBUG"loff_t:%lld,count:%d\n", *ppos, (int)count);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
if (copy_to_user(buffer, debug_lmp_bf + *ppos, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static ssize_t lmp_write(struct file *filp, const char __user *buffer, size_t count, loff_t *ppos)
|
||
|
{
|
||
|
printk(KERN_DEBUG"loff_t:%lld\n", *ppos);//loff_t = 0
|
||
|
if (*ppos >= BUF_LEN)
|
||
|
return 0;
|
||
|
if (*ppos + count > BUF_LEN)
|
||
|
count = BUF_LEN - *ppos;
|
||
|
memset(debug_lmp_bf, 0, BUF_LEN);
|
||
|
if (copy_from_user(debug_lmp_bf + *ppos, buffer, count))
|
||
|
return -EFAULT;
|
||
|
*ppos += count;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
static int c_open(struct inode *inode, struct file *filp)
|
||
|
{
|
||
|
filp->private_data = inode->i_private;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static const struct file_operations reg_fops = {
|
||
|
.owner = THIS_MODULE,
|
||
|
.open = c_open,
|
||
|
.read = reg_read,
|
||
|
.write = reg_write,
|
||
|
};
|
||
|
|
||
|
static const struct file_operations tag_fops = {
|
||
|
.owner = THIS_MODULE,
|
||
|
.open = c_open,
|
||
|
.read = tag_read,
|
||
|
.write = tag_write,
|
||
|
};
|
||
|
|
||
|
static const struct file_operations enm_fops = {
|
||
|
.owner = THIS_MODULE,
|
||
|
.open = c_open,
|
||
|
.read = enm_read,
|
||
|
.write = enm_write,
|
||
|
};
|
||
|
|
||
|
static const struct file_operations pkt_fops = {
|
||
|
.owner = THIS_MODULE,
|
||
|
.open = c_open,
|
||
|
.read = pkt_read,
|
||
|
.write = pkt_write,
|
||
|
};
|
||
|
|
||
|
static const struct file_operations lmp_fops = {
|
||
|
.owner = THIS_MODULE,
|
||
|
.open = c_open,
|
||
|
.read = lmp_read,
|
||
|
.write = lmp_write,
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Init fw_debugfs
|
||
|
*
|
||
|
* @void
|
||
|
*
|
||
|
* Returns: 0 on success or non zero value on failure
|
||
|
*/
|
||
|
int fw_debugfs_init(void)
|
||
|
{
|
||
|
struct dentry *raw_hci_cmd;
|
||
|
struct dentry *raw_hci_result;
|
||
|
struct dentry *reg_val;
|
||
|
struct dentry *reg_val_result;
|
||
|
int line;
|
||
|
printk(KERN_DEBUG"bt_fdi debugfs_init\n");
|
||
|
fdi_root = debugfs_create_dir("xradio_bt_dbg", NULL);
|
||
|
if (fdi_root != NULL) {
|
||
|
dbghci = debugfs_create_dir("dbg_hci_val", fdi_root);
|
||
|
if (!dbghci)
|
||
|
goto Rm_ROOT;
|
||
|
dbgacl = debugfs_create_dir("dbg_acl_val", fdi_root);
|
||
|
if (!dbgacl)
|
||
|
goto Rm_ROOT;
|
||
|
dbglmp = debugfs_create_dir("dbg_lmp_val", fdi_root);
|
||
|
if (!dbglmp)
|
||
|
goto Rm_ROOT;
|
||
|
dbgker = debugfs_create_dir("dbg_ker_val", fdi_root);
|
||
|
if (!dbgker)
|
||
|
goto Rm_ROOT;
|
||
|
dbglog = debugfs_create_dir("dbg_log_val", fdi_root);
|
||
|
if (!dbglog)
|
||
|
goto Rm_ROOT;
|
||
|
dbgctl = debugfs_create_dir("dbg_ctl_val", fdi_root);
|
||
|
if (!dbgctl)
|
||
|
goto Rm_ROOT;
|
||
|
} else {
|
||
|
goto Fail;
|
||
|
}
|
||
|
|
||
|
#define ERR_LINE do { line = __LINE__; goto Rm_ROOT; } while (0)
|
||
|
|
||
|
raw_hci_cmd = debugfs_create_file("hci_val", FILE_MODE, dbghci, &debug_reg_bf, ®_fops);
|
||
|
if (!raw_hci_cmd)
|
||
|
ERR_LINE;
|
||
|
|
||
|
raw_hci_result = debugfs_create_file("hci_val_rsp", FILE_MODE, dbghci, &debug_reg_bf, ®_fops);
|
||
|
if (!raw_hci_result)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val_result = debugfs_create_file("lmp_val", FILE_MODE, dbglmp, &debug_lmp_bf, &lmp_fops);
|
||
|
if (!reg_val_result)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val = debugfs_create_file("reg_val", FILE_MODE, dbgctl, &debug_reg_bf, ®_fops);
|
||
|
if (!reg_val)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val_result = debugfs_create_file("reg_val_rsp", FILE_MODE, dbgctl, &debug_reg_bf, ®_fops);
|
||
|
if (!reg_val_result)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val = debugfs_create_file("tag_val", FILE_MODE, dbgctl, &debug_tag_bf, &tag_fops);
|
||
|
if (!reg_val)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val_result = debugfs_create_file("tag_val_rsp", FILE_MODE, dbgctl, &debug_tag_bf, &tag_fops);
|
||
|
if (!reg_val_result)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val = debugfs_create_file("ker_val", FILE_MODE, dbgctl, &debug_reg_bf, ®_fops);
|
||
|
if (!reg_val)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val_result = debugfs_create_file("ker_val_rsp", FILE_MODE, dbgctl, &debug_reg_bf, ®_fops);
|
||
|
if (!reg_val_result)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val = debugfs_create_file("pkt_val", FILE_MODE, dbgctl, &debug_pkt_bf, &pkt_fops);
|
||
|
if (!reg_val)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val = debugfs_create_file("pkt_val_rsp", FILE_MODE, dbgctl, &debug_pkt_bf, &pkt_fops);
|
||
|
if (!reg_val)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val = debugfs_create_file("enm_val", FILE_MODE, dbgctl, &debug_enm_bf, &enm_fops);
|
||
|
if (!reg_val)
|
||
|
ERR_LINE;
|
||
|
|
||
|
reg_val_result = debugfs_create_file("enm_val_rsp", FILE_MODE, dbgctl, &debug_enm_bf, &enm_fops);
|
||
|
if (!reg_val_result)
|
||
|
ERR_LINE;
|
||
|
return 0;
|
||
|
Rm_ROOT:
|
||
|
printk(KERN_DEBUG"bt_fdi debugfs_error:%d\n", line);
|
||
|
debugfs_remove_recursive(fdi_root);
|
||
|
fdi_root = NULL;
|
||
|
Fail:
|
||
|
return -ENOENT;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Exit fw_debugfs
|
||
|
*
|
||
|
* @void
|
||
|
*
|
||
|
* Returns: void
|
||
|
*/
|
||
|
void fw_debugfs_exit(void)
|
||
|
{
|
||
|
printk(KERN_DEBUG"bt_fdi debugfs exit\n");
|
||
|
debugfs_remove_recursive(fdi_root);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
module_init(fw_debugfs_init);
|
||
|
module_exit(fw_debugfs_exit);
|
||
|
MODULE_AUTHOR("XRadioTech");
|
||
|
MODULE_DESCRIPTION("Bluetooth Firmware Debug Interface ver. %s" VERSION);
|
||
|
MODULE_LICENSE("GPL");
|