[media] hdpvr: remove hdpvr_fh and just use v4l2_fh

This prepares the driver for priority and control event handling.
This patch also checks for correct streaming ownership and it makes a
small improvement to the encoder_cmd ioctls: always zero 'flags' and
drop the memset of 'raw' as that is already done by the v4l2 core.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Hans Verkuil 2013-04-06 06:00:17 -03:00 committed by Mauro Carvalho Chehab
parent 99c77aa428
commit ede197aac0
2 changed files with 46 additions and 73 deletions

View file

@ -35,10 +35,6 @@
list_size(&dev->free_buff_list), \
list_size(&dev->rec_buff_list)); }
struct hdpvr_fh {
struct hdpvr_device *dev;
};
static uint list_size(struct list_head *list)
{
struct list_head *tmp;
@ -358,55 +354,21 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev)
* video 4 linux 2 file operations
*/
static int hdpvr_open(struct file *file)
{
struct hdpvr_device *dev;
struct hdpvr_fh *fh;
int retval = -ENOMEM;
dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
if (!dev) {
pr_err("open failing with with ENODEV\n");
retval = -ENODEV;
goto err;
}
fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
if (!fh) {
v4l2_err(&dev->v4l2_dev, "Out of memory\n");
goto err;
}
/* lock the device to allow correctly handling errors
* in resumption */
mutex_lock(&dev->io_mutex);
dev->open_count++;
mutex_unlock(&dev->io_mutex);
fh->dev = dev;
/* save our object in the file's private structure */
file->private_data = fh;
retval = 0;
err:
return retval;
}
static int hdpvr_release(struct file *file)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(file);
if (!dev)
return -ENODEV;
mutex_lock(&dev->io_mutex);
if (!(--dev->open_count) && dev->status == STATUS_STREAMING)
if (file->private_data == dev->owner) {
hdpvr_stop_streaming(dev);
dev->owner = NULL;
}
mutex_unlock(&dev->io_mutex);
return 0;
return v4l2_fh_release(file);
}
/*
@ -416,8 +378,7 @@ static int hdpvr_release(struct file *file)
static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
loff_t *pos)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(file);
struct hdpvr_buffer *buf = NULL;
struct urb *urb;
unsigned int ret = 0;
@ -440,6 +401,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
mutex_unlock(&dev->io_mutex);
goto err;
}
dev->owner = file->private_data;
print_buffer_status();
}
mutex_unlock(&dev->io_mutex);
@ -518,8 +480,7 @@ err:
static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
{
struct hdpvr_buffer *buf = NULL;
struct hdpvr_fh *fh = filp->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(filp);
unsigned int mask = 0;
mutex_lock(&dev->io_mutex);
@ -534,6 +495,8 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
"start_streaming failed\n");
dev->status = STATUS_IDLE;
} else {
dev->owner = filp->private_data;
}
print_buffer_status();
@ -555,7 +518,7 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
static const struct v4l2_file_operations hdpvr_fops = {
.owner = THIS_MODULE,
.open = hdpvr_open,
.open = v4l2_fh_open,
.release = hdpvr_release,
.read = hdpvr_read,
.poll = hdpvr_poll,
@ -584,8 +547,7 @@ static int vidioc_querycap(struct file *file, void *priv,
static int vidioc_s_std(struct file *file, void *private_data,
v4l2_std_id std)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(file);
u8 std_type = 1;
if (std & (V4L2_STD_NTSC | V4L2_STD_PAL_60))
@ -603,8 +565,7 @@ static const char *iname[] = {
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *i)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(file);
unsigned int n;
n = i->index;
@ -626,8 +587,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
static int vidioc_s_input(struct file *file, void *private_data,
unsigned int index)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(file);
int retval;
if (index >= HDPVR_VIDEO_INPUTS)
@ -646,8 +606,7 @@ static int vidioc_s_input(struct file *file, void *private_data,
static int vidioc_g_input(struct file *file, void *private_data,
unsigned int *index)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(file);
*index = dev->options.video_input;
return 0;
@ -680,8 +639,7 @@ static int vidioc_enumaudio(struct file *file, void *priv,
static int vidioc_s_audio(struct file *file, void *private_data,
const struct v4l2_audio *audio)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(file);
int retval;
if (audio->index >= HDPVR_AUDIO_INPUTS)
@ -700,8 +658,7 @@ static int vidioc_s_audio(struct file *file, void *private_data,
static int vidioc_g_audio(struct file *file, void *private_data,
struct v4l2_audio *audio)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(file);
audio->index = dev->options.audio_input;
audio->capability = V4L2_AUDCAP_STEREO;
@ -833,8 +790,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
struct v4l2_format *f)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
struct hdpvr_device *dev = video_drvdata(file);
struct hdpvr_video_info *vid_info;
if (!dev)
@ -860,26 +816,44 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
static int vidioc_encoder_cmd(struct file *filp, void *priv,
struct v4l2_encoder_cmd *a)
{
struct hdpvr_fh *fh = filp->private_data;
struct hdpvr_device *dev = fh->dev;
int res;
struct hdpvr_device *dev = video_drvdata(filp);
int res = 0;
mutex_lock(&dev->io_mutex);
a->flags = 0;
memset(&a->raw, 0, sizeof(a->raw));
switch (a->cmd) {
case V4L2_ENC_CMD_START:
a->flags = 0;
if (dev->owner && filp->private_data != dev->owner) {
res = -EBUSY;
break;
}
if (dev->status == STATUS_STREAMING)
break;
res = hdpvr_start_streaming(dev);
if (!res)
dev->owner = filp->private_data;
else
dev->status = STATUS_IDLE;
break;
case V4L2_ENC_CMD_STOP:
if (dev->owner && filp->private_data != dev->owner) {
res = -EBUSY;
break;
}
if (dev->status == STATUS_IDLE)
break;
res = hdpvr_stop_streaming(dev);
if (!res)
dev->owner = NULL;
break;
default:
v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"Unsupported encoder cmd %d\n", a->cmd);
res = -EINVAL;
break;
}
mutex_unlock(&dev->io_mutex);
return res;
}
@ -887,6 +861,7 @@ static int vidioc_encoder_cmd(struct file *filp, void *priv,
static int vidioc_try_encoder_cmd(struct file *filp, void *priv,
struct v4l2_encoder_cmd *a)
{
a->flags = 0;
switch (a->cmd) {
case V4L2_ENC_CMD_START:
case V4L2_ENC_CMD_STOP:
@ -935,8 +910,6 @@ static void hdpvr_device_release(struct video_device *vdev)
}
static const struct video_device hdpvr_video_template = {
/* .type = VFL_TYPE_GRABBER, */
/* .type2 = VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
.fops = &hdpvr_fops,
.release = hdpvr_device_release,
.ioctl_ops = &hdpvr_ioctl_ops,
@ -1031,9 +1004,9 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
goto error;
}
*(dev->video_dev) = hdpvr_video_template;
*dev->video_dev = hdpvr_video_template;
strcpy(dev->video_dev->name, "Hauppauge HD PVR");
dev->video_dev->parent = parent;
dev->video_dev->v4l2_dev = &dev->v4l2_dev;
video_set_drvdata(dev->video_dev, dev);
res = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum);

View file

@ -85,8 +85,6 @@ struct hdpvr_device {
/* holds the current device status */
__u8 status;
/* count the number of openers */
uint open_count;
/* holds the cureent set options */
struct hdpvr_options options;
@ -107,6 +105,8 @@ struct hdpvr_device {
struct workqueue_struct *workqueue;
/**/
struct work_struct worker;
/* current stream owner */
struct v4l2_fh *owner;
/* I2C adapter */
struct i2c_adapter i2c_adapter;