1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/drivers/media/usb/uvc/uvc_debugfs.c
Thomas Gleixner 2874c5fd28 treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152
Based on 1 normalized pattern(s):

  this program is free software you can redistribute it and or modify
  it under the terms of the gnu general public license as published by
  the free software foundation either version 2 of the license or at
  your option any later version

extracted by the scancode license scanner the SPDX license identifier

  GPL-2.0-or-later

has been chosen to replace the boilerplate/reference in 3029 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-05-30 11:26:32 -07:00

124 lines
2.9 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* uvc_debugfs.c -- USB Video Class driver - Debugging support
*
* Copyright (C) 2011
* Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*/
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include "uvcvideo.h"
/* -----------------------------------------------------------------------------
* Statistics
*/
#define UVC_DEBUGFS_BUF_SIZE 1024
struct uvc_debugfs_buffer {
size_t count;
char data[UVC_DEBUGFS_BUF_SIZE];
};
static int uvc_debugfs_stats_open(struct inode *inode, struct file *file)
{
struct uvc_streaming *stream = inode->i_private;
struct uvc_debugfs_buffer *buf;
buf = kmalloc(sizeof(*buf), GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
buf->count = uvc_video_stats_dump(stream, buf->data, sizeof(buf->data));
file->private_data = buf;
return 0;
}
static ssize_t uvc_debugfs_stats_read(struct file *file, char __user *user_buf,
size_t nbytes, loff_t *ppos)
{
struct uvc_debugfs_buffer *buf = file->private_data;
return simple_read_from_buffer(user_buf, nbytes, ppos, buf->data,
buf->count);
}
static int uvc_debugfs_stats_release(struct inode *inode, struct file *file)
{
kfree(file->private_data);
file->private_data = NULL;
return 0;
}
static const struct file_operations uvc_debugfs_stats_fops = {
.owner = THIS_MODULE,
.open = uvc_debugfs_stats_open,
.llseek = no_llseek,
.read = uvc_debugfs_stats_read,
.release = uvc_debugfs_stats_release,
};
/* -----------------------------------------------------------------------------
* Global and stream initialization/cleanup
*/
static struct dentry *uvc_debugfs_root_dir;
void uvc_debugfs_init_stream(struct uvc_streaming *stream)
{
struct usb_device *udev = stream->dev->udev;
struct dentry *dent;
char dir_name[32];
if (uvc_debugfs_root_dir == NULL)
return;
sprintf(dir_name, "%u-%u", udev->bus->busnum, udev->devnum);
dent = debugfs_create_dir(dir_name, uvc_debugfs_root_dir);
if (IS_ERR_OR_NULL(dent)) {
uvc_printk(KERN_INFO, "Unable to create debugfs %s "
"directory.\n", dir_name);
return;
}
stream->debugfs_dir = dent;
dent = debugfs_create_file("stats", 0444, stream->debugfs_dir,
stream, &uvc_debugfs_stats_fops);
if (IS_ERR_OR_NULL(dent)) {
uvc_printk(KERN_INFO, "Unable to create debugfs stats file.\n");
uvc_debugfs_cleanup_stream(stream);
return;
}
}
void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream)
{
debugfs_remove_recursive(stream->debugfs_dir);
stream->debugfs_dir = NULL;
}
void uvc_debugfs_init(void)
{
struct dentry *dir;
dir = debugfs_create_dir("uvcvideo", usb_debug_root);
if (IS_ERR_OR_NULL(dir)) {
uvc_printk(KERN_INFO, "Unable to create debugfs directory\n");
return;
}
uvc_debugfs_root_dir = dir;
}
void uvc_debugfs_cleanup(void)
{
debugfs_remove_recursive(uvc_debugfs_root_dir);
}