#include #include #include #include #include #include #include #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");