media: cec: add core error injection support
Add two new ops (error_inj_show and error_inj_parse_line) to support error injection functionality for CEC adapters. If both are present, then the core will add a new error-inj debugfs file that can be used to see the current error injection commands and to set error injection commands. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Родитель
f7b0fa6923
Коммит
9ca400c18f
|
@ -195,6 +195,55 @@ void cec_register_cec_notifier(struct cec_adapter *adap,
|
|||
EXPORT_SYMBOL_GPL(cec_register_cec_notifier);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static ssize_t cec_error_inj_write(struct file *file,
|
||||
const char __user *ubuf, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct seq_file *sf = file->private_data;
|
||||
struct cec_adapter *adap = sf->private;
|
||||
char *buf;
|
||||
char *line;
|
||||
char *p;
|
||||
|
||||
buf = memdup_user_nul(ubuf, min_t(size_t, PAGE_SIZE, count));
|
||||
if (IS_ERR(buf))
|
||||
return PTR_ERR(buf);
|
||||
p = buf;
|
||||
while (p && *p && count >= 0) {
|
||||
p = skip_spaces(p);
|
||||
line = strsep(&p, "\n");
|
||||
if (!*line || *line == '#')
|
||||
continue;
|
||||
if (!adap->ops->error_inj_parse_line(adap, line)) {
|
||||
count = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
kfree(buf);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int cec_error_inj_show(struct seq_file *sf, void *unused)
|
||||
{
|
||||
struct cec_adapter *adap = sf->private;
|
||||
|
||||
return adap->ops->error_inj_show(adap, sf);
|
||||
}
|
||||
|
||||
static int cec_error_inj_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, cec_error_inj_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations cec_error_inj_fops = {
|
||||
.open = cec_error_inj_open,
|
||||
.write = cec_error_inj_write,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
#endif
|
||||
|
||||
struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
|
||||
void *priv, const char *name, u32 caps,
|
||||
u8 available_las)
|
||||
|
@ -334,7 +383,16 @@ int cec_register_adapter(struct cec_adapter *adap,
|
|||
pr_warn("cec-%s: Failed to create status file\n", adap->name);
|
||||
debugfs_remove_recursive(adap->cec_dir);
|
||||
adap->cec_dir = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (!adap->ops->error_inj_show || !adap->ops->error_inj_parse_line)
|
||||
return 0;
|
||||
adap->error_inj_file = debugfs_create_file("error-inj", 0644,
|
||||
adap->cec_dir, adap,
|
||||
&cec_error_inj_fops);
|
||||
if (IS_ERR_OR_NULL(adap->error_inj_file))
|
||||
pr_warn("cec-%s: Failed to create error-inj file\n",
|
||||
adap->name);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -117,6 +117,10 @@ struct cec_adap_ops {
|
|||
void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
|
||||
void (*adap_free)(struct cec_adapter *adap);
|
||||
|
||||
/* Error injection callbacks */
|
||||
int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
|
||||
bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
|
||||
|
||||
/* High-level CEC message callback */
|
||||
int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
|
||||
};
|
||||
|
@ -189,6 +193,7 @@ struct cec_adapter {
|
|||
|
||||
struct dentry *cec_dir;
|
||||
struct dentry *status_file;
|
||||
struct dentry *error_inj_file;
|
||||
|
||||
u16 phys_addrs[15];
|
||||
u32 sequence;
|
||||
|
|
Загрузка…
Ссылка в новой задаче