summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/hdpvr
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-04-01 07:36:31 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-04-01 07:36:31 -0300
commite149dc20dba1c192f28fbeab92aac7f004a41273 (patch)
tree18aaa82ffabd3790e47ef35e2f631932ef5c46e8 /linux/drivers/media/video/hdpvr
parentfdab553be22b01acd8124650ed75da649169596f (diff)
parente8b1f94e600957e27366e37a729126388c705c7d (diff)
downloadmediapointer-dvb-s2-e149dc20dba1c192f28fbeab92aac7f004a41273.tar.gz
mediapointer-dvb-s2-e149dc20dba1c192f28fbeab92aac7f004a41273.tar.bz2
merge: http://linuxtv.org/hg/~anttip/af9015/
From: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/media/video/hdpvr')
-rw-r--r--linux/drivers/media/video/hdpvr/hdpvr-control.c22
-rw-r--r--linux/drivers/media/video/hdpvr/hdpvr-core.c69
-rw-r--r--linux/drivers/media/video/hdpvr/hdpvr-video.c133
-rw-r--r--linux/drivers/media/video/hdpvr/hdpvr.h7
4 files changed, 138 insertions, 93 deletions
diff --git a/linux/drivers/media/video/hdpvr/hdpvr-control.c b/linux/drivers/media/video/hdpvr/hdpvr-control.c
index 51de74aeb..06791749d 100644
--- a/linux/drivers/media/video/hdpvr/hdpvr-control.c
+++ b/linux/drivers/media/video/hdpvr/hdpvr-control.c
@@ -40,9 +40,9 @@ int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf)
dev->usbc_buf, 1, 10000);
mutex_unlock(&dev->usbc_mutex);
- dev_dbg(&dev->udev->dev,
- "config call request for value 0x%x returned %d\n", value,
- ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "config call request for value 0x%x returned %d\n", value,
+ ret);
return ret < 0 ? ret : 0;
}
@@ -57,7 +57,7 @@ struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
if (!vidinf) {
- dev_err(&dev->udev->dev, "out of memory");
+ v4l2_err(&dev->v4l2_dev, "out of memory\n");
goto err;
}
@@ -78,8 +78,8 @@ struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
if (hdpvr_debug & MSG_INFO) {
hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,
sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev, "get video info returned: %d, %s\n",
- ret, print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "get video info returned: %d, %s\n", ret, print_buf);
}
#endif
mutex_unlock(&dev->usbc_mutex);
@@ -111,9 +111,9 @@ int get_input_lines_info(struct hdpvr_device *dev)
if (hdpvr_debug & MSG_INFO) {
hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf,
sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev,
- "get input lines info returned: %d, %s\n", ret,
- print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "get input lines info returned: %d, %s\n", ret,
+ print_buf);
}
#endif
lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
@@ -155,8 +155,8 @@ int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
dev->usbc_buf[1] = 1;
else {
mutex_unlock(&dev->usbc_mutex);
- dev_err(&dev->udev->dev, "invalid audio codec %d\n",
- codec);
+ v4l2_err(&dev->v4l2_dev, "invalid audio codec %d\n",
+ codec);
ret = -EINVAL;
goto error;
}
diff --git a/linux/drivers/media/video/hdpvr/hdpvr-core.c b/linux/drivers/media/video/hdpvr/hdpvr-core.c
index e96aed42d..188bd5aea 100644
--- a/linux/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/linux/drivers/media/video/hdpvr/hdpvr-core.c
@@ -125,7 +125,7 @@ static int device_authorization(struct hdpvr_device *dev)
size_t buf_size = 46;
char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
if (!print_buf) {
- dev_err(&dev->udev->dev, "Out of memory");
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
goto error;
}
#endif
@@ -138,17 +138,17 @@ static int device_authorization(struct hdpvr_device *dev)
dev->usbc_buf, 46,
10000);
if (ret != 46) {
- dev_err(&dev->udev->dev,
- "unexpected answer of status request, len %d", ret);
+ v4l2_err(&dev->v4l2_dev,
+ "unexpected answer of status request, len %d\n", ret);
goto error;
}
#ifdef HDPVR_DEBUG
else {
hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf,
sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev,
- "Status request returned, len %d: %s\n",
- ret, print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "Status request returned, len %d: %s\n",
+ ret, print_buf);
}
#endif
if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION) {
@@ -156,11 +156,11 @@ static int device_authorization(struct hdpvr_device *dev)
} else if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION_AC3) {
dev->flags |= HDPVR_FLAG_AC3_CAP;
} else if (dev->usbc_buf[1] > HDPVR_FIRMWARE_VERSION_AC3) {
- dev_notice(&dev->udev->dev, "untested firmware version 0x%x, "
- "the driver might not work\n", dev->usbc_buf[1]);
+ v4l2_info(&dev->v4l2_dev, "untested firmware version 0x%x, "
+ "the driver might not work\n", dev->usbc_buf[1]);
dev->flags |= HDPVR_FLAG_AC3_CAP;
} else {
- dev_err(&dev->udev->dev, "unknown firmware version 0x%x\n",
+ v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n",
dev->usbc_buf[1]);
ret = -EINVAL;
goto error;
@@ -169,12 +169,14 @@ static int device_authorization(struct hdpvr_device *dev)
response = dev->usbc_buf+38;
#ifdef HDPVR_DEBUG
hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev, "challenge: %s\n", print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n",
+ print_buf);
#endif
challenge(response);
#ifdef HDPVR_DEBUG
hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev, " response: %s\n", print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n",
+ print_buf);
#endif
msleep(100);
@@ -184,7 +186,8 @@ static int device_authorization(struct hdpvr_device *dev)
0x0000, 0x0000,
response, 8,
10000);
- dev_dbg(&dev->udev->dev, "magic request returned %d\n", ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "magic request returned %d\n", ret);
mutex_unlock(&dev->usbc_mutex);
retval = ret != 8;
@@ -214,12 +217,13 @@ static int hdpvr_device_init(struct hdpvr_device *dev)
CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX,
buf, 4,
1000);
- dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
mutex_unlock(&dev->usbc_mutex);
vidinf = get_video_info(dev);
if (!vidinf)
- dev_dbg(&dev->udev->dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"no valid video signal or device init failed\n");
else
kfree(vidinf);
@@ -231,7 +235,8 @@ static int hdpvr_device_init(struct hdpvr_device *dev)
usb_sndctrlpipe(dev->udev, 0),
0xd4, 0x38, 0, 0, buf, 1,
1000);
- dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
/* boost analog audio */
buf[0] = boost_audio;
@@ -239,7 +244,8 @@ static int hdpvr_device_init(struct hdpvr_device *dev)
usb_sndctrlpipe(dev->udev, 0),
0xd5, 0x38, 0, 0, buf, 1,
1000);
- dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
mutex_unlock(&dev->usbc_mutex);
dev->status = STATUS_IDLE;
@@ -278,12 +284,19 @@ static int hdpvr_probe(struct usb_interface *interface,
err("Out of memory");
goto error;
}
+
+ /* register v4l2_device early so it can be used for printks */
+ if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
+ err("v4l2_device_register failed");
+ goto error;
+ }
+
mutex_init(&dev->io_mutex);
mutex_init(&dev->i2c_mutex);
mutex_init(&dev->usbc_mutex);
dev->usbc_buf = kmalloc(64, GFP_KERNEL);
if (!dev->usbc_buf) {
- dev_err(&dev->udev->dev, "Out of memory");
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
goto error;
}
@@ -325,26 +338,27 @@ static int hdpvr_probe(struct usb_interface *interface,
}
if (!dev->bulk_in_endpointAddr) {
- err("Could not find bulk-in endpoint");
+ v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n");
goto error;
}
/* init the device */
if (hdpvr_device_init(dev)) {
- err("device init failed");
+ v4l2_err(&dev->v4l2_dev, "device init failed\n");
goto error;
}
mutex_lock(&dev->io_mutex);
if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
- err("allocating transfer buffers failed");
+ v4l2_err(&dev->v4l2_dev,
+ "allocating transfer buffers failed\n");
goto error;
}
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");
+ v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
goto error;
}
@@ -352,7 +366,7 @@ static int hdpvr_probe(struct usb_interface *interface,
/* until i2c is working properly */
retval = 0; /* hdpvr_register_i2c_adapter(dev); */
if (retval < 0) {
- err("registering i2c adapter failed");
+ v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
goto error;
}
#endif /* CONFIG_I2C */
@@ -361,7 +375,7 @@ static int hdpvr_probe(struct usb_interface *interface,
usb_set_intfdata(interface, dev);
/* let the user know what node this device is now attached to */
- v4l2_info(dev->video_dev, "device now attached to /dev/video%d\n",
+ v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n",
dev->video_dev->minor);
return 0;
@@ -387,11 +401,14 @@ static void hdpvr_disconnect(struct usb_interface *interface)
/* prevent more I/O from starting and stop any ongoing */
mutex_lock(&dev->io_mutex);
dev->status = STATUS_DISCONNECTED;
+ v4l2_device_disconnect(&dev->v4l2_dev);
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);
@@ -408,9 +425,9 @@ static void hdpvr_disconnect(struct usb_interface *interface)
atomic_dec(&dev_nr);
- printk(KERN_INFO "Hauppauge HD PVR: device /dev/video%d disconnected\n",
- minor);
+ v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor);
+ v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev->usbc_buf);
kfree(dev);
}
diff --git a/linux/drivers/media/video/hdpvr/hdpvr-video.c b/linux/drivers/media/video/hdpvr/hdpvr-video.c
index 235978003..3e6ffee8d 100644
--- a/linux/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/linux/drivers/media/video/hdpvr/hdpvr-video.c
@@ -28,6 +28,13 @@
#define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */
+#define print_buffer_status() { \
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_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;
};
@@ -117,21 +124,21 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
struct hdpvr_buffer *buf;
struct urb *urb;
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"allocating %u buffers\n", count);
for (i = 0; i < count; i++) {
buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
if (!buf) {
- err("cannot allocate buffer");
+ v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
goto exit;
}
buf->dev = dev;
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
- err("cannot allocate urb");
+ v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
goto exit;
}
buf->urb = urb;
@@ -139,7 +146,8 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL,
&urb->transfer_dma);
if (!mem) {
- err("cannot allocate usb transfer buffer");
+ v4l2_err(&dev->v4l2_dev,
+ "cannot allocate usb transfer buffer\n");
goto exit;
}
@@ -172,7 +180,8 @@ static int hdpvr_submit_buffers(struct hdpvr_device *dev)
buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
buff_list);
if (buf->status != BUFSTAT_AVAILABLE) {
- err("buffer not marked as availbale");
+ v4l2_err(&dev->v4l2_dev,
+ "buffer not marked as availbale\n");
ret = -EFAULT;
goto err;
}
@@ -182,7 +191,9 @@ static int hdpvr_submit_buffers(struct hdpvr_device *dev)
urb->actual_length = 0;
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret) {
- err("usb_submit_urb in %s returned %d", __func__, ret);
+ v4l2_err(&dev->v4l2_dev,
+ "usb_submit_urb in %s returned %d\n",
+ __func__, ret);
if (++err_count > 2)
break;
continue;
@@ -191,10 +202,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;
}
@@ -225,7 +233,7 @@ static void hdpvr_transmit_buffers(struct work_struct *work)
while (dev->status == STATUS_STREAMING) {
if (hdpvr_submit_buffers(dev)) {
- v4l2_err(dev->video_dev, "couldn't submit buffers\n");
+ v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
goto error;
}
if (wait_event_interruptible(dev->wait_buffer,
@@ -234,11 +242,11 @@ static void hdpvr_transmit_buffers(struct work_struct *work)
goto error;
}
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"transmit worker exited\n");
return;
error:
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"transmit buffers errored\n");
dev->status = STATUS_ERROR;
}
@@ -257,7 +265,7 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
vidinf = get_video_info(dev);
if (vidinf) {
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
"video signal: %dx%d@%dhz\n", vidinf->width,
vidinf->height, vidinf->fps);
kfree(vidinf);
@@ -266,7 +274,7 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
ret = usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, 0),
0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
"encoder start control request returned %d\n", ret);
hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
@@ -274,14 +282,14 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
queue_work(dev->workqueue, &dev->worker);
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
"streaming started\n");
dev->status = STATUS_STREAMING;
return 0;
}
msleep(250);
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"no video signal at input %d\n", dev->options.video_input);
return -EAGAIN;
}
@@ -290,22 +298,50 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
/* function expects dev->io_mutex to be hold by caller */
static int hdpvr_stop_streaming(struct hdpvr_device *dev)
{
+ uint actual_length, c = 0;
+ u8 *buf;
+
if (dev->status == STATUS_IDLE)
return 0;
else if (dev->status != STATUS_STREAMING)
return -EAGAIN;
+ buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
+ if (!buf)
+ v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer "
+ "for emptying the internal device buffer. "
+ "Next capture start will be slow\n");
+
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);
+ /* emptying the device buffer beforeshutting it down */
+ while (buf && ++c < 500 &&
+ !usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in_endpointAddr),
+ buf, dev->bulk_in_size, &actual_length,
+ BULK_URB_TIMEOUT)) {
+ /* wait */
+ msleep(5);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "%2d: got %d bytes\n", c, actual_length);
+ }
+ kfree(buf);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "used %d urbs to empty device buffers\n", c-1);
+ msleep(10);
+
dev->status = STATUS_IDLE;
return 0;
@@ -325,14 +361,14 @@ static int hdpvr_open(struct file *file)
dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
if (!dev) {
- err("open failing with with ENODEV");
+ v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n");
retval = -ENODEV;
goto err;
}
fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
if (!fh) {
- err("Out of memory?");
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
goto err;
}
/* lock the device to allow correctly handling errors
@@ -391,19 +427,15 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
mutex_lock(&dev->io_mutex);
if (dev->status == STATUS_IDLE) {
if (hdpvr_start_streaming(dev)) {
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
- "start_streaming failed");
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "start_streaming failed\n");
ret = -EIO;
msleep(200);
dev->status = STATUS_IDLE;
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);
@@ -444,7 +476,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
cnt)) {
- err("read: copy_to_user failed");
+ v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
if (!ret)
ret = -EFAULT;
goto err;
@@ -463,10 +495,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 +512,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;
@@ -494,31 +524,23 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
if (dev->status == STATUS_IDLE) {
if (hdpvr_start_streaming(dev)) {
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
- "start_streaming failed");
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "start_streaming failed\n");
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;
}
@@ -1139,9 +1161,9 @@ static int vidioc_encoder_cmd(struct file *filp, void *priv,
res = hdpvr_stop_streaming(dev);
break;
default:
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"Unsupported encoder cmd %d\n", a->cmd);
- return -EINVAL;
+ res = -EINVAL;
}
mutex_unlock(&dev->io_mutex);
return res;
@@ -1200,22 +1222,23 @@ 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();
if (!dev->video_dev) {
- err("video_device_alloc() failed");
+ v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n");
goto error;
}
*(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)) {
- err("V4L2 device registration failed");
+ v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
goto error;
}
diff --git a/linux/drivers/media/video/hdpvr/hdpvr.h b/linux/drivers/media/video/hdpvr/hdpvr.h
index 9bc8051b5..1edd87591 100644
--- a/linux/drivers/media/video/hdpvr/hdpvr.h
+++ b/linux/drivers/media/video/hdpvr/hdpvr.h
@@ -15,6 +15,8 @@
#include <linux/workqueue.h>
#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+
#define HDPVR_MAJOR_VERSION 0
#define HDPVR_MINOR_VERSION 2
#define HDPVR_RELEASE 0
@@ -65,6 +67,8 @@ struct hdpvr_device {
struct video_device *video_dev;
/* the usb device for this device */
struct usb_device *udev;
+ /* v4l2-device unused */
+ struct v4l2_device v4l2_dev;
/* the max packet size of the bulk endpoint */
size_t bulk_in_size;
@@ -284,7 +288,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);