From f3ac90549a85ff26ab911d4daf8d57ebb39293c9 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 27 Mar 2009 00:29:39 +0100 Subject: hdpvr: use debugging macro for buffer status From: Janne Grunau Priority: normal Signed-off-by: Janne Grunau --- linux/drivers/media/video/hdpvr/hdpvr-video.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'linux/drivers/media/video/hdpvr') diff --git a/linux/drivers/media/video/hdpvr/hdpvr-video.c b/linux/drivers/media/video/hdpvr/hdpvr-video.c index 235978003..d63bfccf7 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; } @@ -399,11 +402,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 +462,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); @@ -499,10 +495,7 @@ 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); -- cgit v1.2.3 From b16183f4e679f7248f72e89d10dfcf73cfb83d49 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 26 Mar 2009 18:40:55 +0100 Subject: hdpvr: set usb interface dev as parent in struct video_device From: Janne Grunau Priority: normal Signed-off-by: Janne Grunau --- linux/drivers/media/video/hdpvr/hdpvr-core.c | 2 +- linux/drivers/media/video/hdpvr/hdpvr-video.c | 5 +++-- linux/drivers/media/video/hdpvr/hdpvr.h | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/video/hdpvr') diff --git a/linux/drivers/media/video/hdpvr/hdpvr-core.c b/linux/drivers/media/video/hdpvr/hdpvr-core.c index e96aed42d..2c49862b6 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; diff --git a/linux/drivers/media/video/hdpvr/hdpvr-video.c b/linux/drivers/media/video/hdpvr/hdpvr-video.c index d63bfccf7..9560e19d7 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr-video.c +++ b/linux/drivers/media/video/hdpvr/hdpvr-video.c @@ -1193,7 +1193,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(); @@ -1204,7 +1205,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); -- cgit v1.2.3 From 3d73a21a3b0fb96a08c796016ae66cb734327490 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 26 Mar 2009 18:32:54 +0100 Subject: hdpvr: return immediately from hdpvr_poll if data is available From: Janne Grunau simplifies check for available data with hdpvr_get_next_buffer Priority: normal Signed-off-by: Janne Grunau --- linux/drivers/media/video/hdpvr/hdpvr-video.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'linux/drivers/media/video/hdpvr') diff --git a/linux/drivers/media/video/hdpvr/hdpvr-video.c b/linux/drivers/media/video/hdpvr/hdpvr-video.c index 9560e19d7..e9078cded 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr-video.c +++ b/linux/drivers/media/video/hdpvr/hdpvr-video.c @@ -479,6 +479,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,19 +500,14 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) } 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; } -- cgit v1.2.3 From fcf939c56e5b32cbd2f6e77d9de6d190186a4c1a Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 27 Mar 2009 00:56:06 +0100 Subject: hdpvr: locking fixes From: Janne Grunau unlock io_mutex in hdpvr_stop_streaming hdpvr_disconnect to allow the streaming worker to stop before we flush the workqueue. do not return to user space with mutex held in vidioc_encoder_cmd with an unknown encoder command. Priority: normal Signed-off-by: Janne Grunau --- linux/drivers/media/video/hdpvr/hdpvr-core.c | 2 ++ linux/drivers/media/video/hdpvr/hdpvr-video.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/video/hdpvr') diff --git a/linux/drivers/media/video/hdpvr/hdpvr-core.c b/linux/drivers/media/video/hdpvr/hdpvr-core.c index 2c49862b6..547833eb6 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr-core.c +++ b/linux/drivers/media/video/hdpvr/hdpvr-core.c @@ -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 e9078cded..2fe57303c 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr-video.c +++ b/linux/drivers/media/video/hdpvr/hdpvr-video.c @@ -300,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); @@ -1130,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; -- cgit v1.2.3 From e1b327c44494755c635ee8cd086c1cd070a4f20b Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 28 Mar 2009 00:01:40 +0100 Subject: hdpvr: add struct v4l2_device From: Janne Grunau Priority: normal Signed-off-by: Janne Grunau --- linux/drivers/media/video/hdpvr/hdpvr-core.c | 9 +++++++++ linux/drivers/media/video/hdpvr/hdpvr.h | 4 ++++ 2 files changed, 13 insertions(+) (limited to 'linux/drivers/media/video/hdpvr') diff --git a/linux/drivers/media/video/hdpvr/hdpvr-core.c b/linux/drivers/media/video/hdpvr/hdpvr-core.c index 547833eb6..3b19a259d 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr-core.c +++ b/linux/drivers/media/video/hdpvr/hdpvr-core.c @@ -278,6 +278,13 @@ 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); @@ -387,6 +394,7 @@ 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); @@ -413,6 +421,7 @@ static void hdpvr_disconnect(struct usb_interface *interface) printk(KERN_INFO "Hauppauge HD PVR: 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.h b/linux/drivers/media/video/hdpvr/hdpvr.h index 3af415d81..1edd87591 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr.h +++ b/linux/drivers/media/video/hdpvr/hdpvr.h @@ -15,6 +15,8 @@ #include #include +#include + #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; -- cgit v1.2.3 From 9cd596ebf1895fbde84391135359f7d7cc401fe4 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 28 Mar 2009 00:09:40 +0100 Subject: hdpvr: convert printing macros to v4l2_* with struct v4l2_device From: Janne Grunau it gives us a nice and unique prefix per device Priority: normal Signed-off-by: Janne Grunau --- linux/drivers/media/video/hdpvr/hdpvr-control.c | 22 ++++----- linux/drivers/media/video/hdpvr/hdpvr-core.c | 56 +++++++++++++---------- linux/drivers/media/video/hdpvr/hdpvr-video.c | 61 +++++++++++++------------ 3 files changed, 75 insertions(+), 64 deletions(-) (limited to 'linux/drivers/media/video/hdpvr') 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 3b19a259d..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; @@ -290,7 +296,7 @@ static int hdpvr_probe(struct usb_interface *interface, 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; } @@ -332,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, &interface->dev, video_nr[atomic_inc_return(&dev_nr)])) { - err("registering videodev failed"); + v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); goto error; } @@ -359,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 */ @@ -368,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; @@ -418,8 +425,7 @@ 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); diff --git a/linux/drivers/media/video/hdpvr/hdpvr-video.c b/linux/drivers/media/video/hdpvr/hdpvr-video.c index 2fe57303c..f6e1bcefd 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr-video.c +++ b/linux/drivers/media/video/hdpvr/hdpvr-video.c @@ -28,11 +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)) +#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; @@ -123,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; @@ -145,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; } @@ -178,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; } @@ -188,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; @@ -228,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, @@ -237,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; } @@ -260,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); @@ -269,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); @@ -277,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; } @@ -330,14 +335,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 @@ -396,8 +401,8 @@ 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; @@ -445,7 +450,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; @@ -493,8 +498,8 @@ 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; } @@ -1130,7 +1135,7 @@ 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); res = -EINVAL; } @@ -1197,7 +1202,7 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, /* 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; } @@ -1207,7 +1212,7 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *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; } -- cgit v1.2.3 From 1fcaa2a07d4c815b9f8a8bfdd738b22a46760ede Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 28 Mar 2009 00:21:17 +0100 Subject: hdpvr: empty internal device buffer after stopping streaming From: Janne Grunau Makes the next capturing starting faster and more reliable. Priority: normal Signed-off-by: Janne Grunau --- linux/drivers/media/video/hdpvr/hdpvr-video.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'linux/drivers/media/video/hdpvr') diff --git a/linux/drivers/media/video/hdpvr/hdpvr-video.c b/linux/drivers/media/video/hdpvr/hdpvr-video.c index f6e1bcefd..3e6ffee8d 100644 --- a/linux/drivers/media/video/hdpvr/hdpvr-video.c +++ b/linux/drivers/media/video/hdpvr/hdpvr-video.c @@ -298,11 +298,20 @@ 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); @@ -316,6 +325,23 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev) /* 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; -- cgit v1.2.3