#include <linux/bitfield.h>
#include <linux/debugfs.h>
#include <linux/pm_runtime.h>
#include <linux/uaccess.h>
#include "tb.h"
#include "sb_regs.h"
#define PORT_CAP_V1_PCIE_LEN …
#define PORT_CAP_V2_PCIE_LEN …
#define PORT_CAP_POWER_LEN …
#define PORT_CAP_LANE_LEN …
#define PORT_CAP_USB3_LEN …
#define PORT_CAP_DP_V1_LEN …
#define PORT_CAP_DP_V2_LEN …
#define PORT_CAP_TMU_V1_LEN …
#define PORT_CAP_TMU_V2_LEN …
#define PORT_CAP_BASIC_LEN …
#define PORT_CAP_USB4_LEN …
#define SWITCH_CAP_TMU_LEN …
#define SWITCH_CAP_BASIC_LEN …
#define PATH_LEN …
#define COUNTER_SET_LEN …
struct sb_reg { … };
#define SB_MAX_SIZE …
static const struct sb_reg port_sb_regs[] = …;
static const struct sb_reg retimer_sb_regs[] = …;
#define DEBUGFS_ATTR(__space, __write) …
#define DEBUGFS_ATTR_RO(__space) …
#define DEBUGFS_ATTR_RW(__space) …
static struct dentry *tb_debugfs_root;
static void *validate_and_copy_from_user(const void __user *user_buf,
size_t *count)
{ … }
static bool parse_line(char **line, u32 *offs, u32 *val, int short_fmt_len,
int long_fmt_len)
{ … }
#if IS_ENABLED(CONFIG_USB4_DEBUGFS_WRITE)
static ssize_t regs_write(struct tb_switch *sw, struct tb_port *port,
const char __user *user_buf, size_t count,
loff_t *ppos)
{ … }
static ssize_t port_regs_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t switch_regs_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static bool parse_sb_line(char **line, u8 *reg, u8 *data, size_t data_size,
size_t *bytes_read)
{ … }
static ssize_t sb_regs_write(struct tb_port *port, const struct sb_reg *sb_regs,
size_t size, enum usb4_sb_target target, u8 index,
char *buf, size_t count, loff_t *ppos)
{ … }
static ssize_t port_sb_regs_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t retimer_sb_regs_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
#define DEBUGFS_MODE …
#else
#define port_regs_write …
#define switch_regs_write …
#define port_sb_regs_write …
#define retimer_sb_regs_write …
#define DEBUGFS_MODE …
#endif
#if IS_ENABLED(CONFIG_USB4_DEBUGFS_MARGINING)
struct tb_margining { … };
static bool supports_software(const struct tb_margining *margining)
{ … }
static bool supports_hardware(const struct tb_margining *margining)
{ … }
static bool both_lanes(const struct tb_margining *margining)
{ … }
static unsigned int
independent_voltage_margins(const struct tb_margining *margining)
{ … }
static bool supports_time(const struct tb_margining *margining)
{ … }
static unsigned int
independent_time_margins(const struct tb_margining *margining)
{ … }
static ssize_t
margining_ber_level_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static void ber_level_show(struct seq_file *s, unsigned int val)
{ … }
static int margining_ber_level_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
static int margining_caps_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RO(…);
static ssize_t
margining_lanes_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static int margining_lanes_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
static ssize_t margining_mode_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static int margining_mode_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
static int margining_run_write(void *data, u64 val)
{ … }
DEFINE_DEBUGFS_ATTRIBUTE(…);
static ssize_t margining_results_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static void voltage_margin_show(struct seq_file *s,
const struct tb_margining *margining, u8 val)
{ … }
static void time_margin_show(struct seq_file *s,
const struct tb_margining *margining, u8 val)
{ … }
static int margining_results_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
static ssize_t margining_test_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static int margining_test_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
static ssize_t margining_margin_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static int margining_margin_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
static struct tb_margining *margining_alloc(struct tb_port *port,
struct device *dev,
enum usb4_sb_target target,
u8 index, struct dentry *parent)
{ … }
static void margining_port_init(struct tb_port *port)
{ … }
static void margining_port_remove(struct tb_port *port)
{ … }
static void margining_switch_init(struct tb_switch *sw)
{ … }
static void margining_switch_remove(struct tb_switch *sw)
{ … }
static void margining_xdomain_init(struct tb_xdomain *xd)
{ … }
static void margining_xdomain_remove(struct tb_xdomain *xd)
{ … }
static void margining_retimer_init(struct tb_retimer *rt, struct dentry *debugfs_dir)
{ … }
static void margining_retimer_remove(struct tb_retimer *rt)
{ … }
#else
static inline void margining_switch_init(struct tb_switch *sw) { }
static inline void margining_switch_remove(struct tb_switch *sw) { }
static inline void margining_xdomain_init(struct tb_xdomain *xd) { }
static inline void margining_xdomain_remove(struct tb_xdomain *xd) { }
static inline void margining_retimer_init(struct tb_retimer *rt,
struct dentry *debugfs_dir) { }
static inline void margining_retimer_remove(struct tb_retimer *rt) { }
#endif
static int port_clear_all_counters(struct tb_port *port)
{ … }
static ssize_t counters_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static void cap_show_by_dw(struct seq_file *s, struct tb_switch *sw,
struct tb_port *port, unsigned int cap,
unsigned int offset, u8 cap_id, u8 vsec_id,
int dwords)
{ … }
static void cap_show(struct seq_file *s, struct tb_switch *sw,
struct tb_port *port, unsigned int cap, u8 cap_id,
u8 vsec_id, int length)
{ … }
static void port_cap_show(struct tb_port *port, struct seq_file *s,
unsigned int cap)
{ … }
static void port_caps_show(struct tb_port *port, struct seq_file *s)
{ … }
static int port_basic_regs_show(struct tb_port *port, struct seq_file *s)
{ … }
static int port_regs_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
static void switch_cap_show(struct tb_switch *sw, struct seq_file *s,
unsigned int cap)
{ … }
static void switch_caps_show(struct tb_switch *sw, struct seq_file *s)
{ … }
static int switch_basic_regs_show(struct tb_switch *sw, struct seq_file *s)
{ … }
static int switch_regs_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
static int path_show_one(struct tb_port *port, struct seq_file *s, int hopid)
{ … }
static int path_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RO(…);
static int counter_set_regs_show(struct tb_port *port, struct seq_file *s,
int counter)
{ … }
static int counters_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
static int sb_regs_show(struct tb_port *port, const struct sb_reg *sb_regs,
size_t size, enum usb4_sb_target target, u8 index,
struct seq_file *s)
{ … }
static int port_sb_regs_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
void tb_switch_debugfs_init(struct tb_switch *sw)
{ … }
void tb_switch_debugfs_remove(struct tb_switch *sw)
{ … }
void tb_xdomain_debugfs_init(struct tb_xdomain *xd)
{ … }
void tb_xdomain_debugfs_remove(struct tb_xdomain *xd)
{ … }
void tb_service_debugfs_init(struct tb_service *svc)
{ … }
void tb_service_debugfs_remove(struct tb_service *svc)
{ … }
static int retimer_sb_regs_show(struct seq_file *s, void *not_used)
{ … }
DEBUGFS_ATTR_RW(…);
void tb_retimer_debugfs_init(struct tb_retimer *rt)
{ … }
void tb_retimer_debugfs_remove(struct tb_retimer *rt)
{ … }
void tb_debugfs_init(void)
{ … }
void tb_debugfs_exit(void)
{ … }