diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-04-01 07:36:31 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-04-01 07:36:31 -0300 |
commit | e149dc20dba1c192f28fbeab92aac7f004a41273 (patch) | |
tree | 18aaa82ffabd3790e47ef35e2f631932ef5c46e8 /linux/drivers/media/video/hdpvr | |
parent | fdab553be22b01acd8124650ed75da649169596f (diff) | |
parent | e8b1f94e600957e27366e37a729126388c705c7d (diff) | |
download | mediapointer-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.c | 22 | ||||
-rw-r--r-- | linux/drivers/media/video/hdpvr/hdpvr-core.c | 69 | ||||
-rw-r--r-- | linux/drivers/media/video/hdpvr/hdpvr-video.c | 133 | ||||
-rw-r--r-- | linux/drivers/media/video/hdpvr/hdpvr.h | 7 |
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); |