rpms/kernel/devel kernel.spec, 1.1441, 1.1442 linux-2.6-hdpvr.patch, 1.5, 1.6 linux-2.6-v4l-dvb-experimental.patch, 1.2, 1.3 linux-2.6-v4l-dvb-update.patch, 1.8, 1.9

Jarod Wilson jwilson at fedoraproject.org
Wed Mar 18 12:36:58 UTC 2009


Author: jwilson

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv7511

Modified Files:
	kernel.spec linux-2.6-hdpvr.patch 
	linux-2.6-v4l-dvb-experimental.patch 
	linux-2.6-v4l-dvb-update.patch 
Log Message:
* Wed Mar 18 2009 Jarod Wilson <jarod at redhat.com>
- Update hdpvr patch to version targeted for v4l-dvb merge
- Re-sort patches to add hdpvr after v4l-dvb updates



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.1441
retrieving revision 1.1442
diff -u -r1.1441 -r1.1442
--- kernel.spec	18 Mar 2009 06:47:17 -0000	1.1441
+++ kernel.spec	18 Mar 2009 12:36:26 -0000	1.1442
@@ -677,11 +677,10 @@
 # silence the ACPI blacklist code
 Patch2802: linux-2.6-silence-acpi-blacklist.patch
 
-Patch2897: linux-2.6-hdpvr.patch
-
 Patch2899: linux-2.6-v4l-dvb-fixes.patch
 Patch2900: linux-2.6-v4l-dvb-update.patch
 Patch2901: linux-2.6-v4l-dvb-experimental.patch
+Patch2902: linux-2.6-hdpvr.patch
 
 # fs fixes
 Patch2910: linux-2.6-ext4-extent-header-check-fix.patch
@@ -1196,8 +1195,6 @@
 
 # http://www.lirc.org/
 ApplyPatch linux-2.6.29-lirc.patch
-# http://hg.jannau.net/hdpvr/
-ApplyPatch linux-2.6-hdpvr.patch
 
 # Fix the return code CD accesses when the CDROM drive door is closed
 # but the drive isn't yet ready.
@@ -1233,6 +1230,8 @@
 ApplyPatch linux-2.6-v4l-dvb-fixes.patch
 ApplyPatch linux-2.6-v4l-dvb-update.patch
 ApplyPatch linux-2.6-v4l-dvb-experimental.patch
+# http://hg.jannau.net/hdpvr/
+ApplyPatch linux-2.6-hdpvr.patch
 
 # revert 8b249b6856f16f09b0e5b79ce5f4d435e439b9d6
 ApplyPatch revert-fix-modules_install-via-nfs.patch
@@ -1822,6 +1821,10 @@
 # and build.
 
 %changelog
+* Wed Mar 18 2009 Jarod Wilson <jarod at redhat.com>
+- Update hdpvr patch to version targeted for v4l-dvb merge
+- Re-sort patches to add hdpvr after v4l-dvb updates
+
 * Wed Mar 18 2009 Dave Airlie <airlied at redhat.com>
 - drm-next.patch: fix rs600 GART setup
 - drm-modesetting-radeon.patch: allocator fixups

linux-2.6-hdpvr.patch:

Index: linux-2.6-hdpvr.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-hdpvr.patch,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- linux-2.6-hdpvr.patch	27 Feb 2009 17:03:34 -0000	1.5
+++ linux-2.6-hdpvr.patch	18 Mar 2009 12:36:26 -0000	1.6
@@ -1,29 +1,7 @@
-Video capture driver for the Hauppauge HD PVR
-
-upstream: http://hg.jannau.net/hdpvr/
-product info: http://hauppauge.com/site/products/data_hdpvr.html
-
-Signed-off-by: Jarod Wilson <jarod at redhat.com>
-
----
- drivers/media/video/Kconfig               |    2 +
- drivers/media/video/Makefile              |    2 +
- drivers/media/video/hdpvr/Kconfig         |   10 +
- drivers/media/video/hdpvr/Makefile        |    7 +
- drivers/media/video/hdpvr/hdpvr-control.c |  212 +++++
- drivers/media/video/hdpvr/hdpvr-core.c    |  461 +++++++++++
- drivers/media/video/hdpvr/hdpvr-i2c.c     |  145 ++++
- drivers/media/video/hdpvr/hdpvr-video.c   | 1258 +++++++++++++++++++++++++++++
- drivers/media/video/hdpvr/hdpvr.h         |  326 ++++++++
- drivers/media/video/v4l2-common.c         |    3 +
- include/linux/i2c-id.h                    |    1 +
- 11 files changed, 2427 insertions(+), 0 deletions(-)
-
-diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
-index 19cf3b8..4f29e1a 100644
---- a/drivers/media/video/Kconfig
-+++ b/drivers/media/video/Kconfig
-@@ -817,6 +817,8 @@ source "drivers/media/video/gspca/Kconfig"
+diff -r 626c136ec221 drivers/media/video/Kconfig
+--- a/drivers/media/video/Kconfig	Fri Mar 13 14:35:14 2009 -0700
++++ b/drivers/media/video/Kconfig	Tue Mar 17 14:28:02 2009 -0400
+@@ -789,6 +789,8 @@
  
  source "drivers/media/video/pvrusb2/Kconfig"
  
@@ -31,25 +9,22 @@
 +
  source "drivers/media/video/em28xx/Kconfig"
  
- source "drivers/media/video/usbvision/Kconfig"
-diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
-index 72f6d03..e7e4508 100644
---- a/drivers/media/video/Makefile
-+++ b/drivers/media/video/Makefile
-@@ -128,6 +128,8 @@ obj-$(CONFIG_USB_VICAM)         += usbvideo/
- obj-$(CONFIG_USB_QUICKCAM_MESSENGER)	+= usbvideo/
- obj-$(CONFIG_USB_S2255)		+= s2255drv.o
+ source "drivers/media/video/cx231xx/Kconfig"
+diff -r 626c136ec221 drivers/media/video/Makefile
+--- a/drivers/media/video/Makefile	Fri Mar 13 14:35:14 2009 -0700
++++ b/drivers/media/video/Makefile	Tue Mar 17 14:28:02 2009 -0400
+@@ -120,6 +120,8 @@
+ obj-$(CONFIG_USB_ZC0301)        += zc0301/
+ obj-$(CONFIG_USB_GSPCA)         += gspca/
  
-+obj-$(CONFIG_VIDEO_HDPVR)       += hdpvr/
++obj-$(CONFIG_VIDEO_HDPVR)	+= hdpvr/
 +
- obj-$(CONFIG_VIDEO_IVTV) += ivtv/
- obj-$(CONFIG_VIDEO_CX18) += cx18/
- 
-diff --git a/drivers/media/video/hdpvr/Kconfig b/drivers/media/video/hdpvr/Kconfig
-new file mode 100644
-index 0000000..de247f3
---- /dev/null
-+++ b/drivers/media/video/hdpvr/Kconfig
+ obj-$(CONFIG_USB_IBMCAM)        += usbvideo/
+ obj-$(CONFIG_USB_KONICAWC)      += usbvideo/
+ obj-$(CONFIG_USB_VICAM)         += usbvideo/
+diff -r 626c136ec221 drivers/media/video/hdpvr/Kconfig
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/drivers/media/video/hdpvr/Kconfig	Tue Mar 17 14:28:02 2009 -0400
 @@ -0,0 +1,10 @@
 +
 +config VIDEO_HDPVR
@@ -61,11 +36,9 @@
 +	  To compile this driver as a module, choose M here: the
 +	  module will be called hdpvr
 +
-diff --git a/drivers/media/video/hdpvr/Makefile b/drivers/media/video/hdpvr/Makefile
-new file mode 100644
-index 0000000..79ad2e1
---- /dev/null
-+++ b/drivers/media/video/hdpvr/Makefile
+diff -r 626c136ec221 drivers/media/video/hdpvr/Makefile
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/drivers/media/video/hdpvr/Makefile	Tue Mar 17 14:28:02 2009 -0400
 @@ -0,0 +1,7 @@
 +hdpvr-objs	:= hdpvr-control.o hdpvr-core.o hdpvr-i2c.o hdpvr-video.o
 +
@@ -74,12 +47,10 @@
 +EXTRA_CFLAGS += -Idrivers/media/video
 +
 +EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
-diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/video/hdpvr/hdpvr-control.c
-new file mode 100644
-index 0000000..eee0cc6
---- /dev/null
-+++ b/drivers/media/video/hdpvr/hdpvr-control.c
-@@ -0,0 +1,212 @@
+diff -r 626c136ec221 drivers/media/video/hdpvr/hdpvr-control.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/drivers/media/video/hdpvr/hdpvr-control.c	Tue Mar 17 14:28:02 2009 -0400
+@@ -0,0 +1,201 @@
 +/*
 + * Hauppage HD PVR USB driver - video 4 linux 2 interface
 + *
@@ -96,13 +67,13 @@
 +#include <linux/init.h>
 +#include <linux/slab.h>
 +#include <linux/module.h>
-+#include <linux/kref.h>
-+#include <linux/uaccess.h>
 +#include <linux/usb.h>
 +#include <linux/mutex.h>
 +
 +#include <linux/videodev2.h>
 +
++#include <media/v4l2-common.h>
++
 +#include "hdpvr.h"
 +
 +
@@ -110,147 +81,135 @@
 +{
 +	int ret;
 +	char request_type = 0x38, snd_request = 0x01;
-+	char *buf = kmalloc(1, GFP_KERNEL);
-+	if (!buf)
-+		return -ENOMEM;
 +
 +	msleep(10);
 +
-+	*buf = valbuf;
++	mutex_lock(&dev->usbc_mutex);
++	dev->usbc_buf[0] = valbuf;
 +	ret = usb_control_msg(dev->udev,
 +			      usb_sndctrlpipe(dev->udev, 0),
 +			      snd_request, 0x00 | request_type,
 +			      value, CTRL_DEFAULT_INDEX,
-+			      buf, 1, 10000);
++			      dev->usbc_buf, 1, 10000);
 +
-+	hdpvr_info("config call request returned %d", ret);
-+
-+	kfree(buf);
++	mutex_unlock(&dev->usbc_mutex);
++	dev_dbg(&dev->udev->dev,
++		"config call request for value 0x%x returned %d\n", value,
++		ret);
 +
 +	return ret < 0 ? ret : 0;
 +}
 +
 +struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
 +{
-+	u8 *buffer;
 +	struct hdpvr_video_info *vidinf = NULL;
 +#ifdef HDPVR_DEBUG
 +	char print_buf[15];
 +#endif
 +	int ret;
 +
-+	buffer = kzalloc(5, GFP_KERNEL);
-+	if (!buffer) {
-+		err("out of memory");
-+		goto err;
-+	}
 +	vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
 +	if (!vidinf) {
-+		err("out of memory");
++		dev_err(&dev->udev->dev, "out of memory");
 +		goto err;
 +	}
 +
++	mutex_lock(&dev->usbc_mutex);
 +	ret = usb_control_msg(dev->udev,
 +			      usb_rcvctrlpipe(dev->udev, 0),
 +			      0x81, 0x80 | 0x38,
 +			      0x1400, 0x0003,
-+			      buffer, 5,
++			      dev->usbc_buf, 5,
 +			      1000);
 +	if (ret == 5) {
-+		vidinf->width	= buffer[1] << 8 | buffer[0];
-+		vidinf->height	= buffer[3] << 8 | buffer[2];
-+		vidinf->fps	= buffer[4];
++		vidinf->width	= dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
++		vidinf->height	= dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
++		vidinf->fps	= dev->usbc_buf[4];
 +	}
 +
 +#ifdef HDPVR_DEBUG
 +	if (hdpvr_debug & MSG_INFO) {
-+		print_bytes(print_buf, buffer, 5);
-+		hdpvr_info("get video info returned: %d, %s", ret, print_buf);
++		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);
 +	}
 +#endif
++	mutex_unlock(&dev->usbc_mutex);
 +
 +	if (!vidinf->width || !vidinf->height || !vidinf->fps) {
 +		kfree(vidinf);
 +		vidinf = NULL;
 +	}
 +err:
-+	kfree(buffer);
 +	return vidinf;
 +}
 +
 +int get_input_lines_info(struct hdpvr_device *dev)
 +{
-+	u8 buffer[3];
 +#ifdef HDPVR_DEBUG
 +	char print_buf[9];
 +#endif
-+	int ret;
++	int ret, lines;
 +
++	mutex_lock(&dev->usbc_mutex);
 +	ret = usb_control_msg(dev->udev,
 +			      usb_rcvctrlpipe(dev->udev, 0),
 +			      0x81, 0x80 | 0x38,
 +			      0x1800, 0x0003,
-+			      buffer, 3,
++			      dev->usbc_buf, 3,
 +			      1000);
 +
 +#ifdef HDPVR_DEBUG
 +	if (hdpvr_debug & MSG_INFO) {
-+		print_bytes(print_buf, buffer, 3);
-+		hdpvr_info("get input lines info returned: %d, %s", ret,
-+			   print_buf);
++		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);
 +	}
 +#endif
-+	return buffer[1] << 8 | buffer[0];
++	lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
++	mutex_unlock(&dev->usbc_mutex);
++	return lines;
 +}
 +
 +
 +int hdpvr_set_bitrate(struct hdpvr_device *dev)
 +{
 +	int ret;
-+	char *buf;
 +
-+	buf = kzalloc(4, GFP_KERNEL);
-+	if (!buf) {
-+		err("out of memory");
-+		ret = -ENOMEM;
-+		goto err;
-+	}
-+
-+	buf[0] = dev->options.bitrate;
-+	buf[2] = dev->options.peak_bitrate;
++	mutex_lock(&dev->usbc_mutex);
++	memset(dev->usbc_buf, 0, 4);
++	dev->usbc_buf[0] = dev->options.bitrate;
++	dev->usbc_buf[2] = dev->options.peak_bitrate;
 +
 +	ret = usb_control_msg(dev->udev,
 +			      usb_sndctrlpipe(dev->udev, 0),
 +			      0x01, 0x38, CTRL_BITRATE_VALUE,
-+			      CTRL_DEFAULT_INDEX, buf, 4, 1000);
++			      CTRL_DEFAULT_INDEX, dev->usbc_buf, 4, 1000);
++	mutex_unlock(&dev->usbc_mutex);
 +
-+err:
-+	kfree(buf);
 +	return ret;
 +}
 +
 +int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
 +		    enum v4l2_mpeg_audio_encoding codec)
 +{
-+
-+	int ret = 0, buflength = 2;
-+	char *buf = NULL;
++	int ret = 0;
 +
 +	if (dev->flags & HDPVR_FLAG_AC3_CAP) {
-+		buf = kzalloc(buflength, GFP_KERNEL);
-+		if (!buf) {
-+			hdpvr_err("out of memory");
-+			ret = -ENOMEM;
-+			goto error;
-+		}
-+
-+		buf[0] = input;
++		mutex_lock(&dev->usbc_mutex);
++		memset(dev->usbc_buf, 0, 2);
++		dev->usbc_buf[0] = input;
 +		if (codec == V4L2_MPEG_AUDIO_ENCODING_AAC)
-+			buf[1] = 0;
++			dev->usbc_buf[1] = 0;
 +		else if (codec == V4L2_MPEG_AUDIO_ENCODING_AC3)
-+			buf[1] = 1;
++			dev->usbc_buf[1] = 1;
 +		else {
-+			hdpvr_err("invalid audio codec %d", codec);
++			mutex_unlock(&dev->usbc_mutex);
++			dev_err(&dev->udev->dev, "invalid audio codec %d\n",
++				codec);
 +			ret = -EINVAL;
 +			goto error;
 +		}
@@ -258,14 +217,15 @@
 +		ret = usb_control_msg(dev->udev,
 +				      usb_sndctrlpipe(dev->udev, 0),
 +				      0x01, 0x38, CTRL_AUDIO_INPUT_VALUE,
-+				      CTRL_DEFAULT_INDEX, buf, buflength, 1000);
-+		if (ret == buflength)
++				      CTRL_DEFAULT_INDEX, dev->usbc_buf, 2,
++				      1000);
++		mutex_unlock(&dev->usbc_mutex);
++		if (ret == 2)
 +			ret = 0;
 +	} else
 +		ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE,
 +					dev->options.audio_input+1);
 +error:
-+	kfree(buf);
 +	return ret;
 +}
 +
@@ -292,12 +252,10 @@
 +
 +       return 0;
 +}
-diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
-new file mode 100644
-index 0000000..394309a
---- /dev/null
-+++ b/drivers/media/video/hdpvr/hdpvr-core.c
-@@ -0,0 +1,461 @@
+diff -r 626c136ec221 drivers/media/video/hdpvr/hdpvr-core.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/drivers/media/video/hdpvr/hdpvr-core.c	Tue Mar 17 14:28:02 2009 -0400
+@@ -0,0 +1,448 @@
 +/*
 + * Hauppage HD PVR USB driver
 + *
@@ -316,7 +274,6 @@
 +#include <linux/init.h>
 +#include <linux/slab.h>
 +#include <linux/module.h>
-+#include <linux/kref.h>
 +#include <linux/uaccess.h>
 +#include <asm/atomic.h>
 +#include <linux/usb.h>
@@ -325,6 +282,7 @@
 +
 +#include <linux/videodev2.h>
 +#include <media/v4l2-dev.h>
++#include <media/v4l2-common.h>
 +
 +#include "hdpvr.h"
 +
@@ -332,7 +290,7 @@
 +module_param_array(video_nr, int, NULL, 0);
 +MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
 +
-+/* holds the number if currently registered devices */
++/* holds the number of currently registered devices */
 +static atomic_t dev_nr = ATOMIC_INIT(-1);
 +
 +int hdpvr_debug;
@@ -364,32 +322,15 @@
 +MODULE_DEVICE_TABLE(usb, hdpvr_table);
 +
 +
-+#define to_hdpvr_dev(d) container_of(d, struct hdpvr_device, kref)
-+
-+
-+void hdpvr_delete(struct kref *kref)
++void hdpvr_delete(struct hdpvr_device *dev)
 +{
-+	struct hdpvr_device *dev = to_hdpvr_dev(kref);
-+
 +	hdpvr_free_buffers(dev);
 +
-+	usb_put_dev(dev->udev);
-+	kfree(dev);
-+}
-+
-+#ifdef HDPVR_DEBUG
-+void print_bytes(char *string, unsigned char *buf, size_t len)
-+{
++	if (dev->video_dev)
++		video_device_release(dev->video_dev);
 +
-+	int i, pos = 0;
-+	for (i = 0; i < len; i++)
-+		pos += snprintf(string+pos, 4, "%02x ", buf[i]);
-+
-+	string[pos-1] = '\0';
-+
-+	return;
++	usb_put_dev(dev->udev);
 +}
-+#endif
 +
 +static void challenge(u8 *bytes)
 +{
@@ -437,67 +378,61 @@
 +
 +	int ret, retval = -ENOMEM;
 +	char request_type = 0x38, rcv_request = 0x81;
-+	size_t buf_size = 46;
-+	char *buf;
 +	char *response;
 +#ifdef HDPVR_DEBUG
++	size_t buf_size = 46;
 +	char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
 +	if (!print_buf) {
-+		err("Out of memory");
++		dev_err(&dev->udev->dev, "Out of memory");
 +		goto error;
 +	}
 +#endif
 +
-+	buf = kzalloc(buf_size, GFP_KERNEL);
-+	if (!buf) {
-+		err("Out of memory");
-+		goto error;
-+	}
-+
++	mutex_lock(&dev->usbc_mutex);
 +	ret = usb_control_msg(dev->udev,
 +			      usb_rcvctrlpipe(dev->udev, 0),
 +			      rcv_request, 0x80 | request_type,
 +			      0x0400, 0x0003,
-+			      buf, 46,
++			      dev->usbc_buf, 46,
 +			      10000);
 +	if (ret != 46) {
-+		err("unexpected answer of status request, len %d", ret);
++		dev_err(&dev->udev->dev,
++			"unexpected answer of status request, len %d", ret);
 +		goto error;
 +	}
 +#ifdef HDPVR_DEBUG
 +	else {
-+		print_bytes(print_buf, buf, 46);
-+		hdpvr_info("Status request returned, len %d: %s", ret,
-+			   print_buf);
++		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);
 +	}
 +#endif
-+	if (buf[1] == HDPVR_FIRMWARE_VERSION) {
++	if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION) {
 +		dev->flags &= ~HDPVR_FLAG_AC3_CAP;
-+	} else if (buf[1] == HDPVR_FIRMWARE_VERSION_AC3) {
++	} else if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION_AC3) {
 +		dev->flags |= HDPVR_FLAG_AC3_CAP;
-+	} else if (buf[1] > HDPVR_FIRMWARE_VERSION_AC3) {
-+		hdpvr_print("untested firmware version 0x%x, the driver might "
-+			    "not work", buf[1]);
++	} 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]);
 +		dev->flags |= HDPVR_FLAG_AC3_CAP;
 +	} else {
-+		hdpvr_err("unknown firmware version 0x%x", buf[1]);
++		dev_err(&dev->udev->dev, "unknown firmware version 0x%x\n",
++			dev->usbc_buf[1]);
 +		ret = -EINVAL;
 +		goto error;
 +	}
 +
-+	response = kmalloc(8, GFP_KERNEL);
-+	if (!response)
-+		goto error;
-+	memcpy(response, buf+38, 8);
-+
++	response = dev->usbc_buf+38;
 +#ifdef HDPVR_DEBUG
-+	print_bytes(print_buf, response, 8);
-+	hdpvr_info("challenge: %s", print_buf);
++	hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
++	dev_dbg(&dev->udev->dev, "challenge: %s\n", print_buf);
 +#endif
 +	challenge(response);
 +#ifdef HDPVR_DEBUG
-+	print_bytes(print_buf, response, 8);
-+	hdpvr_info(" response: %s", print_buf);
++	hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
++	dev_dbg(&dev->udev->dev, " response: %s\n", print_buf);
 +#endif
 +
 +	msleep(100);
@@ -507,8 +442,8 @@
 +			      0x0000, 0x0000,
 +			      response, 8,
 +			      10000);
-+	kfree(response);
-+	hdpvr_info("magic request returned %d", ret);
++	dev_dbg(&dev->udev->dev, "magic request returned %d\n", ret);
++	mutex_unlock(&dev->usbc_mutex);
 +
 +	retval = ret != 8;
 +error:
@@ -517,31 +452,19 @@
 +
 +static int hdpvr_device_init(struct hdpvr_device *dev)
 +{
-+	int retval = -ENOMEM, ret;
-+	size_t buf_size = 10;
-+	u8 *buf, *print_buf = NULL;
++	int ret;
++	u8 *buf;
 +	struct hdpvr_video_info *vidinf;
 +
-+	buf = kzalloc(buf_size, GFP_KERNEL);
-+	if (!buf) {
-+		err("Out of memory");
-+		goto error;
-+	}
-+	print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
-+	if (!print_buf) {
-+		err("Out of memory");
-+		goto error;
-+	}
-+
-+	if (device_authorization(dev)) {
-+		retval = -EACCES;
-+		goto error;
-+	}
++	if (device_authorization(dev))
++		return -EACCES;
 +
 +	/* default options for init */
 +	hdpvr_set_options(dev);
 +
 +	/* set filter options */
++	mutex_lock(&dev->usbc_mutex);
++	buf = dev->usbc_buf;
 +	buf[0] = 0x03; buf[1] = 0x03; buf[2] = 0x00; buf[3] = 0x00;
 +	ret = usb_control_msg(dev->udev,
 +			      usb_sndctrlpipe(dev->udev, 0),
@@ -549,21 +472,24 @@
 +			      CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX,
 +			      buf, 4,
 +			      1000);
-+	hdpvr_info("control request returned %d", ret);
++	dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
++	mutex_unlock(&dev->usbc_mutex);
 +
 +	vidinf = get_video_info(dev);
 +	if (!vidinf)
-+		hdpvr_info("no valid video signal or device init failed");
++		dev_dbg(&dev->udev->dev,
++			"no valid video signal or device init failed\n");
 +	else
 +		kfree(vidinf);
 +
 +	/* enable fan and bling leds */
++	mutex_lock(&dev->usbc_mutex);
 +	buf[0] = 0x1;
 +	ret = usb_control_msg(dev->udev,
 +			      usb_sndctrlpipe(dev->udev, 0),
 +			      0xd4, 0x38, 0, 0, buf, 1,
 +			      1000);
-+	hdpvr_info("control request returned %d", ret);
++	dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
 +
 +	/* boost analog audio */
 +	buf[0] = boost_audio;
@@ -571,15 +497,11 @@
 +			      usb_sndctrlpipe(dev->udev, 0),
 +			      0xd5, 0x38, 0, 0, buf, 1,
 +			      1000);
-+	hdpvr_info("control request returned %d", ret);
++	dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
++	mutex_unlock(&dev->usbc_mutex);
 +
 +	dev->status = STATUS_IDLE;
-+	retval = 0;
-+
-+error:
-+	kfree(buf);
-+	kfree(print_buf);
-+	return retval;
++	return 0;
 +}
 +
 +extern struct file_operations hdpvr_fops;
@@ -616,10 +538,21 @@
 +		err("Out of memory");
 +		goto error;
 +	}
-+	kref_init(&dev->kref);
 +	mutex_init(&dev->io_mutex);
 +	mutex_init(&dev->i2c_mutex);
-+	init_waitqueue_head(&dev->wait);
++	mutex_init(&dev->usbc_mutex);
++	dev->usbc_buf = kmalloc(64, GFP_KERNEL);
++	if (!dev->usbc_buf) {
++		dev_err(&dev->udev->dev, "Out of memory");
++		goto error;
++	}
++
++	init_waitqueue_head(&dev->wait_buffer);
++	init_waitqueue_head(&dev->wait_data);
++
++	dev->workqueue = create_singlethread_workqueue("hdpvr_buffer");
++	if (!dev->workqueue)
++		goto error;
 +
 +	/* init video transfer queues */
 +	INIT_LIST_HEAD(&dev->free_buff_list);
@@ -643,9 +576,9 @@
 +
 +		if (!dev->bulk_in_endpointAddr &&
 +		    usb_endpoint_is_bulk_in(endpoint)) {
-+			/* we found a bulk in endpoint */
-+			buffer_size = 8192; /*le16_to_cpu
-+					      (endpoint->wMaxPacketSize); */
++			/* USB interface description is buggy, reported max
++			 * packet size is 512 bytes, windows driver uses 8192 */
++			buffer_size = 8192;
 +			dev->bulk_in_size = buffer_size;
 +			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
 +		}
@@ -662,10 +595,12 @@
 +		goto error;
 +	}
 +
++	mutex_lock(&dev->io_mutex);
 +	if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
 +		err("allocating transfer buffers failed");
 +		goto error;
 +	}
++	mutex_unlock(&dev->io_mutex);
 +
 +	if (hdpvr_register_videodev(dev,
 +				    video_nr[atomic_inc_return(&dev_nr)])) {
@@ -676,7 +611,7 @@
 +#if 0 /* until i2c is working properly */
 +	retval =  hdpvr_register_i2c_adapter(dev);
 +	if (retval < 0) {
-+		hdpvr_err("registering videodev failed");
++		err("registering i2c adapter failed");
 +		goto error;
 +	}
 +#endif
@@ -685,14 +620,16 @@
 +	usb_set_intfdata(interface, dev);
 +
 +	/* let the user know what node this device is now attached to */
-+	hdpvr_print("USB HD PVR device now attached to /dev/video%d",
-+	     dev->video_dev->minor);
++	v4l2_info(dev->video_dev, "device now attached to /dev/video%d\n",
++		  dev->video_dev->minor);
 +	return 0;
 +
 +error:
-+	if (dev)
++	if (dev) {
++		mutex_unlock(&dev->io_mutex);
 +		/* this frees allocated memory */
-+		kref_put(&dev->kref, hdpvr_delete);
++		hdpvr_delete(dev);
++	}
 +	return retval;
 +}
 +
@@ -706,9 +643,16 @@
 +
 +	minor = dev->video_dev->minor;
 +
-+	/* prevent more I/O from starting */
++	/* prevent more I/O from starting and stop any ongoing */
 +	mutex_lock(&dev->io_mutex);
++	dev->status = STATUS_DISCONNECTED;
 +	video_unregister_device(dev->video_dev);
++	wake_up_interruptible(&dev->wait_data);
++	wake_up_interruptible(&dev->wait_buffer);
++	msleep(100);
++	flush_workqueue(dev->workqueue);
++	hdpvr_cancel_queue(dev);
++	destroy_workqueue(dev->workqueue);
 +	mutex_unlock(&dev->io_mutex);
 +
 +	/* deregister I2C adapter */
@@ -719,12 +663,13 @@
 +	dev->i2c_adapter = NULL;
 +	mutex_unlock(&dev->i2c_mutex);
 +
-+	/* decrement our usage count */
-+	kref_put(&dev->kref, hdpvr_delete);
-+
 +	atomic_dec(&dev_nr);
 +
-+	hdpvr_print("USB HD PVR /dev/video%d now disconnected", minor);
++	printk(KERN_INFO "Hauppauge HD PVR: device /dev/video%d disconnected\n",
++	       minor);
++
++	kfree(dev->usbc_buf);
++	kfree(dev);
 +}
 +
 +
@@ -759,11 +704,9 @@
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("Janne Grunau");
 +MODULE_DESCRIPTION("Hauppauge HD PVR driver");
-diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
-new file mode 100644
-index 0000000..35096de
---- /dev/null
-+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
+diff -r 626c136ec221 drivers/media/video/hdpvr/hdpvr-i2c.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/drivers/media/video/hdpvr/hdpvr-i2c.c	Tue Mar 17 14:28:02 2009 -0400
 @@ -0,0 +1,145 @@
 +
 +/*
@@ -910,12 +853,10 @@
 +error:
 +	return retval;
 +}
-diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
-new file mode 100644
-index 0000000..33788d0
---- /dev/null
-+++ b/drivers/media/video/hdpvr/hdpvr-video.c
-@@ -0,0 +1,1258 @@
+diff -r 626c136ec221 drivers/media/video/hdpvr/hdpvr-video.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/drivers/media/video/hdpvr/hdpvr-video.c	Tue Mar 17 14:28:02 2009 -0400
+@@ -0,0 +1,1225 @@
 +/*
 + * Hauppage HD PVR USB driver - video 4 linux 2 interface
 + *
@@ -932,11 +873,11 @@
 +#include <linux/init.h>
 +#include <linux/slab.h>
 +#include <linux/module.h>
-+#include <linux/kref.h>
 +#include <linux/uaccess.h>
 +#include <linux/usb.h>
 +#include <linux/mutex.h>
 +#include <linux/version.h>
++#include <linux/workqueue.h>
 +
 +#include <linux/videodev2.h>
 +#include <media/v4l2-dev.h>
@@ -971,19 +912,17 @@
 +
 +	/* marking buffer as received and wake waiting */
 +	buf->status = BUFSTAT_READY;
-+	wake_up_interruptible(&dev->wait);
++	wake_up_interruptible(&dev->wait_data);
 +}
 +
 +/*=========================================================================*/
 +/* bufffer bits */
 +
-+/* calling function should hold dev->io_mutex */
-+static int hdpvr_cancel_queue(struct hdpvr_device *dev)
++/* function expects dev->io_mutex to be hold by caller */
++int hdpvr_cancel_queue(struct hdpvr_device *dev)
 +{
 +	struct hdpvr_buffer *buf;
 +
-+	hdpvr_trace("status = %d", dev->status);
-+
 +	list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
 +		usb_kill_urb(buf->urb);
 +		buf->status = BUFSTAT_AVAILABLE;
@@ -1017,21 +956,18 @@
 +	return 0;
 +}
 +
++/* function expects dev->io_mutex to be hold by caller */
 +int hdpvr_free_buffers(struct hdpvr_device *dev)
 +{
-+	mutex_lock(&dev->io_mutex);
-+
 +	hdpvr_cancel_queue(dev);
 +
 +	hdpvr_free_queue(&dev->free_buff_list);
 +	hdpvr_free_queue(&dev->rec_buff_list);
 +
-+	mutex_unlock(&dev->io_mutex);
-+
 +	return 0;
 +}
 +
-+/* function expects dev->io_mutex to be held */
++/* function expects dev->io_mutex to be hold by caller */
 +int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
 +{
 +	uint i;
@@ -1040,8 +976,8 @@
 +	struct hdpvr_buffer *buf;
 +	struct urb *urb;
 +
-+	hdpvr_trace("status = %d", dev->status);
-+	hdpvr_info("allocating %u buffers", count);
++	v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
++		 "allocating %u buffers\n", count);
 +
 +	for (i = 0; i < count; i++) {
 +
@@ -1081,14 +1017,12 @@
 +	return retval;
 +}
 +
-+static int submit_pending_buffers(struct hdpvr_device *dev)
++static int hdpvr_submit_buffers(struct hdpvr_device *dev)
 +{
 +	struct hdpvr_buffer *buf;
 +	struct urb *urb;
 +	int ret = 0, err_count = 0;
 +
-+	hdpvr_trace("status = %d", dev->status);
-+
 +	mutex_lock(&dev->io_mutex);
 +
 +	while (dev->status == STATUS_STREAMING &&
@@ -1116,14 +1050,15 @@
 +		list_move_tail(&buf->buff_list, &dev->rec_buff_list);
 +	}
 +err:
-+	hdpvr_info_buffer("buffer queue stat: %d free, %d proc",
-+			  list_size(&dev->free_buff_list),
-+			  list_size(&dev->rec_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));
 +	mutex_unlock(&dev->io_mutex);
 +	return ret;
 +}
 +
-+static struct hdpvr_buffer *get_next_buffer(struct hdpvr_device *dev)
++static struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
 +{
 +	struct hdpvr_buffer *buf;
 +
@@ -1131,7 +1066,6 @@
 +
 +	if (list_empty(&dev->rec_buff_list)) {
 +		mutex_unlock(&dev->io_mutex);
-+		err("error: rec_buf_list is empty");
 +		return NULL;
 +	}
 +
@@ -1142,12 +1076,38 @@
 +	return buf;
 +}
 +
-+static int start_streaming(struct hdpvr_device *dev)
++static void hdpvr_transmit_buffers(struct work_struct *work)
++{
++	struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
++						worker);
++
++	while (dev->status == STATUS_STREAMING) {
++
++		if (hdpvr_submit_buffers(dev)) {
++			v4l2_err(dev->video_dev, "couldn't submit buffers\n");
++			goto error;
++		}
++		if (wait_event_interruptible(dev->wait_buffer,
++				!list_empty(&dev->free_buff_list) ||
++					     dev->status != STATUS_STREAMING))
++			goto error;
++	}
++
++	v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
++		 "transmit worker exited\n");
++	return;
++error:
++	v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
++		 "transmit buffers errored\n");
++	dev->status = STATUS_ERROR;
++}
++
++/* function expects dev->io_mutex to be hold by caller */
++static int hdpvr_start_streaming(struct hdpvr_device *dev)
 +{
 +	int ret;
 +	struct hdpvr_video_info *vidinf;
 +
-+	hdpvr_trace("status = %d", dev->status);
 +	if (dev->status == STATUS_STREAMING)
 +		return 0;
 +	else if (dev->status != STATUS_IDLE)
@@ -1156,81 +1116,56 @@
 +	vidinf = get_video_info(dev);
 +
 +	if (vidinf) {
-+		hdpvr_info("video signal: %dx%d@%dhz", vidinf->width,
-+			   vidinf->height, vidinf->fps);
++		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
++			 "video signal: %dx%d@%dhz\n", vidinf->width,
++			 vidinf->height, vidinf->fps);
 +		kfree(vidinf);
 +
 +		/* start streaming 2 request */
 +		ret = usb_control_msg(dev->udev,
 +				      usb_sndctrlpipe(dev->udev, 0),
 +				      0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
-+		hdpvr_info("encoder start control request returned %d", ret);
++		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
++			 "encoder start control request returned %d\n", ret);
 +
 +		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
 +
-+		hdpvr_info("streaming started");
++		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
++		queue_work(dev->workqueue, &dev->worker);
++
++		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
++			 "streaming started\n");
 +		dev->status = STATUS_STREAMING;
-+		msleep(25);
++
 +		return 0;
 +	}
-+	msleep(50);
-+	hdpvr_err("no video signal at input %d", dev->options.video_input);
++	msleep(100);
++	v4l2_err(dev->video_dev, "no video signal at input %d\n",
++		 dev->options.video_input);
 +	return -EAGAIN;
 +}
 +
-+static int stop_streaming(struct hdpvr_device *dev)
-+{
-+	int usb_stat, actual_length, c = 0;
-+	u8 *buf;
 +
-+	hdpvr_trace("status = %d", dev->status);
++/* function expects dev->io_mutex to be hold by caller */
++static int hdpvr_stop_streaming(struct hdpvr_device *dev)
++{
 +	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) {
-+		err("stop streaming failed, out of memory");
-+		return -ENOMEM;
-+	}
-+
++	dev->status = STATUS_SHUTTING_DOWN;
 +	hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
 +
-+	/* wait 100 msec to let in flight urb comming back */
-+	msleep(100);
++	wake_up_interruptible(&dev->wait_buffer);
++	msleep(50);
++
++	flush_workqueue(dev->workqueue);
 +
 +	/* kill the still outstanding urbs */
 +	hdpvr_cancel_queue(dev);
 +
-+	/* emptying the device buffer before shutting it down */
-+	while (++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);
-+		hdpvr_info_buffer("%2d: got %d bytes", c, actual_length);
-+	}
-+	kfree(buf);
-+	hdpvr_info("used %d urbs to empty device buffers", c-1);
-+
-+	msleep(10);
-+
-+	/* stop streaming 2 request */
-+	usb_stat = usb_control_msg(dev->udev,
-+			      usb_sndctrlpipe(dev->udev, 0),
-+			      0xb9, 0x38, 0x1, 0, NULL, 0, 8000);
-+	hdpvr_info("encoder shutdown control request returned %d", usb_stat);
-+
-+	hdpvr_info_buffer("buffer queue stat: %d free, %d proc",
-+		   list_size(&dev->free_buff_list),
-+		   list_size(&dev->rec_buff_list));
-+
 +	dev->status = STATUS_IDLE;
-+	msleep(15);
 +
 +	return 0;
 +}
@@ -1254,11 +1189,6 @@
 +		goto err;
 +	}
 +
-+	hdpvr_trace("status = %d", dev->status);
-+
-+	/* increment our usage count for the device */
-+	kref_get(&dev->kref);
-+
 +	fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
 +	if (!fh) {
 +		err("Out of memory?");
@@ -1280,33 +1210,6 @@
 +	return retval;
 +}
 +
-+
-+static void hdpvr_draw_down(struct hdpvr_device *dev)
-+{
-+	hdpvr_trace("status = %d", dev->status);
-+	/* hdpvr_cancel_queue(dev); */
-+}
-+
-+
-+static int hdpvr_flush(struct file *file, fl_owner_t id)
-+{
-+	struct hdpvr_fh *fh = (struct hdpvr_fh *)file->private_data;
-+	struct hdpvr_device *dev = fh->dev;
-+
-+	if (!dev)
-+		return -ENODEV;
-+
-+	hdpvr_trace("status = %d", dev->status);
-+
-+	/* wait for io to stop */
-+	mutex_lock(&dev->io_mutex);
-+	hdpvr_draw_down(dev);
-+
-+	mutex_unlock(&dev->io_mutex);
-+
-+	return 0;
-+}
-+
 +static int hdpvr_release(struct file *file)
 +{
 +	struct hdpvr_fh		*fh  = (struct hdpvr_fh *)file->private_data;
@@ -1315,16 +1218,12 @@
 +	if (!dev)
 +		return -ENODEV;
 +
-+	hdpvr_trace("status = %d", dev->status);
-+
 +	mutex_lock(&dev->io_mutex);
 +	if (!(--dev->open_count) && dev->status == STATUS_STREAMING)
-+		stop_streaming(dev);
++		hdpvr_stop_streaming(dev);
 +
 +	mutex_unlock(&dev->io_mutex);
 +
-+	/* decrement the count on our device */
-+	kref_put(&dev->kref, hdpvr_delete);
 +	return 0;
 +}
 +
@@ -1340,9 +1239,7 @@
 +	struct hdpvr_buffer *buf = NULL;
 +	struct urb *urb;
 +	unsigned int ret = 0;
-+	unsigned int processed = 0;
-+	int rem;
-+	int cnt;
++	int rem, cnt;
 +
 +	if (*pos)
 +		return -ESPIPE;
@@ -1350,38 +1247,36 @@
 +	if (!dev)
 +		return -ENODEV;
 +
-+	hdpvr_trace("status = %d", dev->status);
-+
 +	mutex_lock(&dev->io_mutex);
 +	if (dev->status == STATUS_IDLE) {
-+		if (start_streaming(dev)) {
++		if (hdpvr_start_streaming(dev)) {
 +			err("start_streaming failed");
-+			ret = -EFAULT;
++			ret = -EIO;
 +			dev->status = STATUS_IDLE;
 +			mutex_unlock(&dev->io_mutex);
 +			goto err;
 +		}
 +
-+		hdpvr_info_buffer("buffer queue stat: %d free, %d proc",
-+				  list_size(&dev->free_buff_list),
-+				  list_size(&dev->rec_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));
 +	}
 +	mutex_unlock(&dev->io_mutex);
 +
-+	if (submit_pending_buffers(dev)) {
-+		err("couldn't submit buffers");
-+		if (!ret)
-+			ret = -EFAULT;
-+		goto err;
++	/* wait for the first buffer */
++	if (!(file->f_flags & O_NONBLOCK)) {
++		if (wait_event_interruptible(dev->wait_data,
++					     hdpvr_get_next_buffer(dev)))
++			return -ERESTARTSYS;
 +	}
 +
-+	buf = get_next_buffer(dev);
++	buf = hdpvr_get_next_buffer(dev);
 +
 +	while (count > 0 && buf) {
 +
-+		urb = buf->urb;
-+
-+		if (buf->status != BUFSTAT_READY) {
++		if (buf->status != BUFSTAT_READY &&
++		    dev->status != STATUS_DISCONNECTED) {
 +			/* return nonblocking */
 +			if (file->f_flags & O_NONBLOCK) {
 +				if (!ret)
@@ -1389,14 +1284,18 @@
 +				goto err;
 +			}
 +
-+			if (wait_event_interruptible(dev->wait,
++			if (wait_event_interruptible(dev->wait_data,
 +					      buf->status == BUFSTAT_READY)) {
 +				ret = -ERESTARTSYS;
 +				goto err;
 +			}
 +		}
 +
++		if (buf->status != BUFSTAT_READY)
++			break;
++
 +		/* set remaining bytes to copy */
++		urb = buf->urb;
 +		rem = urb->actual_length - buf->pos;
 +		cnt = rem > count ? count : rem;
 +
@@ -1420,19 +1319,17 @@
 +			buf->status = BUFSTAT_AVAILABLE;
 +
 +			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));
 +
 +			mutex_unlock(&dev->io_mutex);
 +
-+			if (!(++processed % (NUM_BUFFERS/2))) {
-+				if (submit_pending_buffers(dev)) {
-+					err("couldn't submit buffers");
-+					if (!ret)
-+						ret = -EFAULT;
-+					goto err;
-+				}
-+			}
++			wake_up_interruptible(&dev->wait_buffer);
 +
-+			buf = get_next_buffer(dev);
++			buf = hdpvr_get_next_buffer(dev);
 +		}
 +	}
 +err:
@@ -1448,24 +1345,26 @@
 +	unsigned int mask = 0;
 +
 +	mutex_lock(&dev->io_mutex);
++
++	if (video_is_unregistered(dev->video_dev))
++		return -EIO;
++
 +	if (dev->status == STATUS_IDLE) {
-+		if (start_streaming(dev)) {
++		if (hdpvr_start_streaming(dev)) {
 +			err("start_streaming failed");
 +			dev->status = STATUS_IDLE;
 +		}
 +
-+		hdpvr_info_buffer("buffer queue stat: %d free, %d proc",
-+				  list_size(&dev->free_buff_list),
-+				  list_size(&dev->rec_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));
 +	}
 +	mutex_unlock(&dev->io_mutex);
 +
-+	submit_pending_buffers(dev);
++	poll_wait(filp, &dev->wait_data, wait);
 +
 +	mutex_lock(&dev->io_mutex);
-+
-+	poll_wait(filp, &dev->wait, wait);
-+
 +	if (!list_empty(&dev->rec_buff_list)) {
 +
 +		struct hdpvr_buffer *buf = list_entry(dev->rec_buff_list.next,
@@ -1475,7 +1374,6 @@
 +		if (buf->status == BUFSTAT_READY)
 +			mask |= POLLIN | POLLRDNORM;
 +	}
-+
 +	mutex_unlock(&dev->io_mutex);
 +
 +	return mask;
@@ -1488,6 +1386,9 @@
 +	struct hdpvr_device *dev = fh->dev;
 +	int res;
 +
++	if (video_is_unregistered(dev->video_dev))
++		return -EIO;
++
 +	mutex_lock(&dev->io_mutex);
 +	switch (cmd) {
 +	case VIDIOC_TRY_ENCODER_CMD:
@@ -1501,16 +1402,16 @@
 +			enc->flags = 0;
 +			if (try)
 +				return 0;
-+			res = start_streaming(dev);
++			res = hdpvr_start_streaming(dev);
 +			break;
 +		case V4L2_ENC_CMD_STOP:
 +			if (try)
 +				return 0;
-+			res = stop_streaming(dev);
++			res = hdpvr_stop_streaming(dev);
 +			break;
 +		default:
-+			hdpvr_ioctl_debug("Unsupported encoder cmd %d\n",
-+					  enc->cmd);
++			v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
++				 "Unsupported encoder cmd %d\n", enc->cmd);
 +			return -EINVAL;
 +		}
 +		break;
@@ -2138,11 +2039,18 @@
 +	.vidioc_g_fmt_vid_cap		= vidioc_g_fmt_vid_cap,
 +};
 +
++static void hdpvr_device_release(struct video_device *vdev)
++{
++	struct hdpvr_device *dev = video_get_drvdata(vdev);
++
++	hdpvr_delete(dev);
++}
++
 +static const struct video_device hdpvr_video_template = {
 +/* 	.type			= VFL_TYPE_GRABBER, */
 +/* 	.type2			= VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
 +	.fops			= &hdpvr_fops,
-+	.release		= video_device_release,
++	.release		= hdpvr_device_release,
 +	.ioctl_ops 		= &hdpvr_ioctl_ops,
 +	.tvnorms 		=
 +		V4L2_STD_NTSC  | V4L2_STD_SECAM | V4L2_STD_PAL_B |
@@ -2174,12 +2082,10 @@
 +error:
 +	return -ENOMEM;
 +}
-diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
-new file mode 100644
-index 0000000..1514742
---- /dev/null
-+++ b/drivers/media/video/hdpvr/hdpvr.h
-@@ -0,0 +1,326 @@
+diff -r 626c136ec221 drivers/media/video/hdpvr/hdpvr.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/drivers/media/video/hdpvr/hdpvr.h	Tue Mar 17 14:28:02 2009 -0400
+@@ -0,0 +1,298 @@
 +/*
 + * Hauppage HD PVR USB driver
 + *
@@ -2194,10 +2100,11 @@
 +#include <linux/usb.h>
 +#include <linux/i2c.h>
 +#include <linux/mutex.h>
++#include <linux/workqueue.h>
 +#include <linux/videodev2.h>
 +
 +#define HDPVR_MAJOR_VERSION 0
-+#define HDPVR_MINOR_VERSION 1
++#define HDPVR_MINOR_VERSION 2
 +#define HDPVR_RELEASE 0
 +#define HDPVR_VERSION \
 +	KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE)
@@ -2212,50 +2119,17 @@
 +
 +#define UNSET    (-1U)
 +
-+#define NUM_BUFFERS 16
++#define NUM_BUFFERS 64
 +
 +#define HDPVR_FIRMWARE_VERSION		0x8
 +#define HDPVR_FIRMWARE_VERSION_AC3	0xd
 +
-+#define HDPVR_DEBUG
++/* #define HDPVR_DEBUG */
 +
 +extern int hdpvr_debug;
 +
 +#define MSG_INFO	1
-+#define MSG_BUFFER	1<<1
-+#define MSG_TRACE	1<<2
-+#define MSG_IOCTL	1<<3
-+
-+#define hdpvr_err(fmt, arg...) do {\
-+	printk(KERN_ERR "hdpvr: ERROR %s: " fmt "\n", __func__, ##arg); } \
-+	while (0)
-+
-+#define hdpvr_print(fmt, arg...) do {\
-+	printk(KERN_NOTICE "hdpvr: " fmt "\n", ##arg); } while (0)
-+
-+#define hdpvr_info(fmt, arg...) do {\
-+	if (hdpvr_debug & MSG_INFO) \
-+		printk(KERN_INFO "hdpvr: INFO %s: " fmt "\n", __func__, \
-+		       ##arg); } \
-+	while (0)
-+
-+#define hdpvr_info_buffer(fmt, arg...) do {\
-+	if (hdpvr_debug & MSG_BUFFER) \
-+		printk(KERN_DEBUG "hdpvr: BUFFER %s: " fmt "\n", __func__, \
-+		       ##arg); } \
-+	while (0)
-+
-+#define hdpvr_trace(fmt, arg...) do {\
-+	if (hdpvr_debug & MSG_TRACE)				\
-+		printk(KERN_DEBUG "hdpvr: TRACE %s: " fmt "\n", __func__, \
-+		       ##arg); } \
-+	while (0)
-+
-+#define hdpvr_ioctl_debug(fmt, arg...) do {\
-+	if (hdpvr_debug & MSG_IOCTL)				\
-+		printk(KERN_DEBUG "hdpvr: IOCTL " fmt "\n", \
-+		       ##arg); } \
-+	while (0)
++#define MSG_BUFFER	2
 +
 +struct hdpvr_options {
 +	u8	video_std;
@@ -2290,8 +2164,6 @@
 +	/* count the number of openers */
 +	uint			open_count;
 +
-+	struct kref		kref;
-+
 +	/* holds the cureent set options */
 +	struct hdpvr_options	options;
 +
@@ -2304,12 +2176,22 @@
 +	/* in progress buffers */
 +	struct list_head	rec_buff_list;
 +	/* waitqueue for buffers */
-+	wait_queue_head_t	wait;
++	wait_queue_head_t	wait_buffer;
++	/* waitqueue for data */
++	wait_queue_head_t	wait_data;
++	/**/
++	struct workqueue_struct	*workqueue;
++	/**/
++	struct work_struct	worker;
 +
 +	/* I2C adapter */
 +	struct i2c_adapter	*i2c_adapter;
 +	/* I2C lock */
 +	struct mutex		i2c_mutex;
++
++	/* usb control transfer buffer and lock */
++	struct mutex		usbc_mutex;
++	u8			*usbc_buf;
 +};
 +
 +
@@ -2341,6 +2223,7 @@
 +	STATUS_SHUTTING_DOWN,
 +	STATUS_STREAMING,
 +	STATUS_ERROR,
++	STATUS_DISCONNECTED,
 +};
 +
 +enum {
@@ -2466,7 +2349,7 @@
 +	HDPVR_SIMPLE_NOIDR_GOP,
 +};
 +
-+void hdpvr_delete(struct kref *kref);
++void hdpvr_delete(struct hdpvr_device *dev);
 +
 +/*========================================================================*/
 +/* hardware control functions */
@@ -2491,6 +2374,7 @@
 +/* v4l2 registration */
 +int hdpvr_register_videodev(struct hdpvr_device *dev, int devnumber);
 +
++int hdpvr_cancel_queue(struct hdpvr_device *dev);
 +
 +/*========================================================================*/
 +/* i2c adapter registration */
@@ -2500,42 +2384,25 @@
 +/* buffer management */
 +int hdpvr_free_buffers(struct hdpvr_device *dev);
 +int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count);
-+
-+
-+
-+#ifdef HDPVR_DEBUG
-+void print_bytes(char *string, unsigned char *buf, size_t len);
-+#endif
-diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
-index b8f2be8..0e8bd98 100644
---- a/drivers/media/video/v4l2-common.c
-+++ b/drivers/media/video/v4l2-common.c
-@@ -547,6 +547,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
+diff -r 626c136ec221 drivers/media/video/v4l2-common.c
+--- a/drivers/media/video/v4l2-common.c	Fri Mar 13 14:35:14 2009 -0700
++++ b/drivers/media/video/v4l2-common.c	Tue Mar 17 14:28:02 2009 -0400
+@@ -567,6 +567,7 @@
  	case V4L2_CID_CONTRAST:
  	case V4L2_CID_SATURATION:
  	case V4L2_CID_HUE:
 +	case V4L2_CID_SHARPNESS:
- 		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
- 		break;
- 	}
-@@ -585,6 +586,8 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
- 		return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64);
- 	case V4L2_CID_HUE:
- 		return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0);
-+	case V4L2_CID_SHARPNESS:
-+		return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
- 
- 	/* MPEG controls */
- 	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
-diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
-index 1ffc23b..e77f81b 100644
---- a/include/linux/i2c-id.h
-+++ b/include/linux/i2c-id.h
-@@ -87,6 +87,7 @@
- #define I2C_HW_B_CX2341X	0x010020 /* Conexant CX2341X MPEG encoder cards */
+ 	case V4L2_CID_RED_BALANCE:
+ 	case V4L2_CID_BLUE_BALANCE:
+ 	case V4L2_CID_GAMMA:
+diff -r 626c136ec221 include/linux/i2c-id.h
+--- a/include/linux/i2c-id.h	Fri Mar 13 14:35:14 2009 -0700
++++ b/include/linux/i2c-id.h	Tue Mar 17 14:28:02 2009 -0400
+@@ -88,6 +88,7 @@
  #define I2C_HW_B_CX23885	0x010022 /* conexant 23885 based tv cards (bus1) */
  #define I2C_HW_B_AU0828		0x010023 /* auvitek au0828 usb bridge */
-+#define I2C_HW_B_HDPVR		0x010024 /* Hauppauge HD PVR */
+ #define I2C_HW_B_CX231XX	0x010024 /* Conexant CX231XX USB based cards */
++#define I2C_HW_B_HDPVR		0x010025 /* Hauppauge HD PVR */
  
  /* --- SGI adapters							*/
  #define I2C_HW_SGI_VINO		0x160000

linux-2.6-v4l-dvb-experimental.patch:

Index: linux-2.6-v4l-dvb-experimental.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-v4l-dvb-experimental.patch,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- linux-2.6-v4l-dvb-experimental.patch	14 Mar 2009 02:15:14 -0000	1.2
+++ linux-2.6-v4l-dvb-experimental.patch	18 Mar 2009 12:36:26 -0000	1.3
@@ -14621,9 +14621,7 @@
  #define I2C_HW_B_CX2341X	0x010020 /* Conexant CX2341X MPEG encoder cards */
  #define I2C_HW_B_CX23885	0x010022 /* conexant 23885 based tv cards (bus1) */
  #define I2C_HW_B_AU0828		0x010023 /* auvitek au0828 usb bridge */
--#define I2C_HW_B_HDPVR		0x010024 /* Hauppauge HD PVR */
 +#define I2C_HW_B_CX231XX	0x010024 /* Conexant CX231XX USB based cards */
-+#define I2C_HW_B_HDPVR		0x010025 /* Hauppauge HD PVR */
  
  /* --- SGI adapters							*/
  #define I2C_HW_SGI_VINO		0x160000

linux-2.6-v4l-dvb-update.patch:

Index: linux-2.6-v4l-dvb-update.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-v4l-dvb-update.patch,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- linux-2.6-v4l-dvb-update.patch	14 Mar 2009 02:15:14 -0000	1.8
+++ linux-2.6-v4l-dvb-update.patch	18 Mar 2009 12:36:27 -0000	1.9
@@ -73318,10 +73318,10 @@
  		qctrl->type = V4L2_CTRL_TYPE_MENU;
  		step = 1;
  		break;
-@@ -548,163 +567,28 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
+@@ -547,161 +566,28 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
+	case V4L2_CID_BRIGHTNESS:
  	case V4L2_CID_SATURATION:
  	case V4L2_CID_HUE:
- 	case V4L2_CID_SHARPNESS:
 +	case V4L2_CID_RED_BALANCE:
 +	case V4L2_CID_BLUE_BALANCE:
 +	case V4L2_CID_GAMMA:
@@ -73370,8 +73370,6 @@
 -		return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64);
 -	case V4L2_CID_HUE:
 -		return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0);
--	case V4L2_CID_SHARPNESS:
--		return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
 -
 -	/* MPEG controls */
 -	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:




More information about the fedora-extras-commits mailing list