diff options
Diffstat (limited to 'linux/drivers/media/video/hdpvr')
-rw-r--r-- | linux/drivers/media/video/hdpvr/hdpvr-core.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/hdpvr/hdpvr-video.c | 56 | ||||
-rw-r--r-- | linux/drivers/media/video/hdpvr/hdpvr.h | 3 |
3 files changed, 29 insertions, 34 deletions
diff --git a/linux/drivers/media/video/hdpvr/hdpvr-core.c b/linux/drivers/media/video/hdpvr/hdpvr-core.c index e96aed42d..547833eb6 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr-core.c +++ b/linux/drivers/media/video/hdpvr/hdpvr-core.c @@ -342,7 +342,7 @@ static int hdpvr_probe(struct usb_interface *interface, } mutex_unlock(&dev->io_mutex); - if (hdpvr_register_videodev(dev, + if (hdpvr_register_videodev(dev, &interface->dev, video_nr[atomic_inc_return(&dev_nr)])) { err("registering videodev failed"); goto error; @@ -390,8 +390,10 @@ static void hdpvr_disconnect(struct usb_interface *interface) video_unregister_device(dev->video_dev); wake_up_interruptible(&dev->wait_data); wake_up_interruptible(&dev->wait_buffer); + mutex_unlock(&dev->io_mutex); msleep(100); flush_workqueue(dev->workqueue); + mutex_lock(&dev->io_mutex); hdpvr_cancel_queue(dev); destroy_workqueue(dev->workqueue); mutex_unlock(&dev->io_mutex); diff --git a/linux/drivers/media/video/hdpvr/hdpvr-video.c b/linux/drivers/media/video/hdpvr/hdpvr-video.c index 235978003..2fe57303c 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr-video.c +++ b/linux/drivers/media/video/hdpvr/hdpvr-video.c @@ -28,6 +28,12 @@ #define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */ +#define print_buffer_status() v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,\ + "%s:%d buffer stat: %d free, %d proc\n",\ + __func__, __LINE__, \ + list_size(&dev->free_buff_list), \ + list_size(&dev->rec_buff_list)) + struct hdpvr_fh { struct hdpvr_device *dev; }; @@ -191,10 +197,7 @@ static int hdpvr_submit_buffers(struct hdpvr_device *dev) list_move_tail(&buf->buff_list, &dev->rec_buff_list); } err: - v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev, - "buffer queue stat: %d free, %d proc\n", - list_size(&dev->free_buff_list), - list_size(&dev->rec_buff_list)); + print_buffer_status(); mutex_unlock(&dev->io_mutex); return ret; } @@ -297,12 +300,14 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev) dev->status = STATUS_SHUTTING_DOWN; hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00); + mutex_unlock(&dev->io_mutex); wake_up_interruptible(&dev->wait_buffer); msleep(50); flush_workqueue(dev->workqueue); + mutex_lock(&dev->io_mutex); /* kill the still outstanding urbs */ hdpvr_cancel_queue(dev); @@ -399,11 +404,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, mutex_unlock(&dev->io_mutex); goto err; } - - v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev, - "buffer queue stat: %d free, %d proc\n", - list_size(&dev->free_buff_list), - list_size(&dev->rec_buff_list)); + print_buffer_status(); } mutex_unlock(&dev->io_mutex); @@ -463,10 +464,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, list_move_tail(&buf->buff_list, &dev->free_buff_list); - v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev, - "buffer queue stat: %d free, %d proc\n", - list_size(&dev->free_buff_list), - list_size(&dev->rec_buff_list)); + print_buffer_status(); mutex_unlock(&dev->io_mutex); @@ -483,6 +481,7 @@ err: static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) { + struct hdpvr_buffer *buf = NULL; struct hdpvr_fh *fh = (struct hdpvr_fh *)filp->private_data; struct hdpvr_device *dev = fh->dev; unsigned int mask = 0; @@ -499,26 +498,18 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) dev->status = STATUS_IDLE; } - v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev, - "buffer queue stat: %d free, %d proc\n", - list_size(&dev->free_buff_list), - list_size(&dev->rec_buff_list)); + print_buffer_status(); } mutex_unlock(&dev->io_mutex); - poll_wait(filp, &dev->wait_data, wait); - - mutex_lock(&dev->io_mutex); - if (!list_empty(&dev->rec_buff_list)) { - - struct hdpvr_buffer *buf = list_entry(dev->rec_buff_list.next, - struct hdpvr_buffer, - buff_list); - - if (buf->status == BUFSTAT_READY) - mask |= POLLIN | POLLRDNORM; + buf = hdpvr_get_next_buffer(dev); + /* only wait if no data is available */ + if (!buf || buf->status != BUFSTAT_READY) { + poll_wait(filp, &dev->wait_data, wait); + buf = hdpvr_get_next_buffer(dev); } - mutex_unlock(&dev->io_mutex); + if (buf && buf->status == BUFSTAT_READY) + mask |= POLLIN | POLLRDNORM; return mask; } @@ -1141,7 +1132,7 @@ static int vidioc_encoder_cmd(struct file *filp, void *priv, default: v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev, "Unsupported encoder cmd %d\n", a->cmd); - return -EINVAL; + res = -EINVAL; } mutex_unlock(&dev->io_mutex); return res; @@ -1200,7 +1191,8 @@ static const struct video_device hdpvr_video_template = { V4L2_STD_PAL_60, }; -int hdpvr_register_videodev(struct hdpvr_device *dev, int devnum) +int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, + int devnum) { /* setup and register video device */ dev->video_dev = video_device_alloc(); @@ -1211,7 +1203,7 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, int devnum) *(dev->video_dev) = hdpvr_video_template; strcpy(dev->video_dev->name, "Hauppauge HD PVR"); - dev->video_dev->parent = &dev->udev->dev; + dev->video_dev->parent = parent; video_set_drvdata(dev->video_dev, dev); if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) { diff --git a/linux/drivers/media/video/hdpvr/hdpvr.h b/linux/drivers/media/video/hdpvr/hdpvr.h index 9bc8051b5..3af415d81 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr.h +++ b/linux/drivers/media/video/hdpvr/hdpvr.h @@ -284,7 +284,8 @@ int get_input_lines_info(struct hdpvr_device *dev); /*========================================================================*/ /* v4l2 registration */ -int hdpvr_register_videodev(struct hdpvr_device *dev, int devnumber); +int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, + int devnumber); int hdpvr_cancel_queue(struct hdpvr_device *dev); |