--- /dev/null
+From stable-bounces@linux.kernel.org Fri Jul 18 16:37:37 2008
+From: Pierre Ossman <drzeus@drzeus.cx>
+Date: Fri, 18 Jul 2008 19:04:27 -0400
+Subject: ALSA: trident - pause s/pdif output
+To: stable@kernel.org
+Cc: Takashi Iwai <tiwai@suse.de>, cebbert@redhat.com
+Message-ID: <20080718190427.7cdfe1da@redhat.com>
+
+
+From: Pierre Ossman <drzeus@drzeus.cx>
+
+Commit 981bcead3f2279a1ec6fb5f2c57aff79ed61a700 upstream.
+
+Stop the S/PDIF DMA engine and output when the device is told to pause.
+It will keep on looping the current buffer contents if this isn't done.
+
+Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
+Tested-by: Rene Herman <rene.herman@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Jaroslav Kysela <perex@perex.cz>
+Cc: Chuck Ebbert <cebbert@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/trident/trident_main.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/trident/trident_main.c
++++ b/sound/pci/trident/trident_main.c
+@@ -1590,7 +1590,10 @@ static int snd_trident_trigger(struct sn
+ if (spdif_flag) {
+ if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
+ outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
+- outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
++ val = trident->spdif_pcm_ctrl;
++ if (!go)
++ val &= ~(0x28);
++ outb(val, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
+ } else {
+ outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
+ val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN;
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jul 21 19:39:04 2008
+From: Michael Krufky <mkrufky@linuxtv.org>
+Date: Mon, 21 Jul 2008 21:53:44 -0400
+Subject: DVB: dib0700: add support for Hauppauge Nova-TD Stick 52009
+To: stable@kernel.org
+Cc: v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>, Mauro Carvalho Chehab <mchehab@infradead.org>
+Message-ID: <48853DA8.8040609@linuxtv.org>
+
+From: Michael Krufky <mkrufky@linuxtv.org>
+
+(cherry picked from commit d01eb2dc7d5265ec3bee9ec1b8ab79155e1310d6)
+
+DVB: dib0700: add support for Hauppauge Nova-TD Stick 52009
+
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++-
+ drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 +
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
++++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
+@@ -1117,6 +1117,7 @@ struct usb_device_id dib0700_usb_id_tabl
+ { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
+ { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
+ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
++ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
+ { 0 } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
+@@ -1372,7 +1373,7 @@ struct dvb_usb_device_properties dib0700
+ }
+ },
+
+- .num_device_descs = 2,
++ .num_device_descs = 3,
+ .devices = {
+ { "DiBcom STK7070PD reference design",
+ { &dib0700_usb_id_table[17], NULL },
+@@ -1381,6 +1382,10 @@ struct dvb_usb_device_properties dib0700
+ { "Pinnacle PCTV Dual DVB-T Diversity Stick",
+ { &dib0700_usb_id_table[18], NULL },
+ { NULL },
++ },
++ { "Hauppauge Nova-TD Stick (52009)",
++ { &dib0700_usb_id_table[35], NULL },
++ { NULL },
+ }
+ }
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
++++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+@@ -132,6 +132,7 @@
+ #define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070
+ #define USB_PID_HAUPPAUGE_MYTV_T 0x7080
+ #define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580
++#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200
+ #define USB_PID_AVERMEDIA_EXPRESS 0xb568
+ #define USB_PID_AVERMEDIA_VOLAR 0xa807
+ #define USB_PID_AVERMEDIA_VOLAR_2 0xb808
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jul 23 01:47:42 2008
+From: Brice Goglin <brice@myri.com>
+Date: Wed, 23 Jul 2008 10:16:13 +0200
+Subject: myri10ge: do not use mgp->max_intr_slots before loading the firmware
+To: stable@kernel.org
+Message-ID: <4886E8CD.60306@myri.com>
+
+From: Brice Goglin <brice@myri.com>
+
+part of commit 0dcffac1a329be69bab0ac604bf7283737108e68 upstream
+(the upstream multislice patch contains this fix within a large
+ rework of the code since there is one rx_done ring per slice. The
+ old allocating is replaced by a call to myri10ge_probe_slices())
+
+
+Allocating the rx_done ring requires mgp->max_intr_slots to
+be valid, which requires that we already loaded the firmware
+we are going to use with this ring.
+So move the allocating after myri10ge_load_firmware()
+(but keep it before myri10ge_reset() which already needs the
+ rx_done ring).
+
+If fixedsa regression where loading the driver would not
+appear to do anything. Regression introduced in 2.6.26-rc3 by
+commit 014377a1df693ff30a9e8b69f0bbb0a38e601f75
+
+Reported and patch tested by Lukas Hejtmanek at
+http://lkml.org/lkml/2008/7/22/305
+Reproduced and patch tested also by me.
+
+Signed-off-by: Brice Goglin <brice@myri.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/myri10ge/myri10ge.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/myri10ge/myri10ge.c
++++ b/drivers/net/myri10ge/myri10ge.c
+@@ -3215,26 +3215,26 @@ static int myri10ge_probe(struct pci_dev
+ for (i = 0; i < ETH_ALEN; i++)
+ netdev->dev_addr[i] = mgp->mac_addr[i];
+
+- /* allocate rx done ring */
+- bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
+- mgp->ss.rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
+- &mgp->ss.rx_done.bus, GFP_KERNEL);
+- if (mgp->ss.rx_done.entry == NULL)
+- goto abort_with_ioremap;
+- memset(mgp->ss.rx_done.entry, 0, bytes);
+-
+ myri10ge_select_firmware(mgp);
+
+ status = myri10ge_load_firmware(mgp);
+ if (status != 0) {
+ dev_err(&pdev->dev, "failed to load firmware\n");
+- goto abort_with_rx_done;
++ goto abort_with_ioremap;
+ }
+
++ /* allocate rx done ring */
++ bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
++ mgp->ss.rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
++ &mgp->ss.rx_done.bus, GFP_KERNEL);
++ if (mgp->ss.rx_done.entry == NULL)
++ goto abort_with_firmware;
++ memset(mgp->ss.rx_done.entry, 0, bytes);
++
+ status = myri10ge_reset(mgp);
+ if (status != 0) {
+ dev_err(&pdev->dev, "failed reset\n");
+- goto abort_with_firmware;
++ goto abort_with_rx_done;
+ }
+
+ pci_set_drvdata(pdev, mgp);
+@@ -3260,7 +3260,7 @@ static int myri10ge_probe(struct pci_dev
+ * is set to correct value if MSI is enabled */
+ status = myri10ge_request_irq(mgp);
+ if (status != 0)
+- goto abort_with_firmware;
++ goto abort_with_rx_done;
+ netdev->irq = pdev->irq;
+ myri10ge_free_irq(mgp);
+
+@@ -3289,14 +3289,14 @@ static int myri10ge_probe(struct pci_dev
+ abort_with_state:
+ pci_restore_state(pdev);
+
+-abort_with_firmware:
+- myri10ge_dummy_rdma(mgp, 0);
+-
+ abort_with_rx_done:
+ bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
+ dma_free_coherent(&pdev->dev, bytes,
+ mgp->ss.rx_done.entry, mgp->ss.rx_done.bus);
+
++abort_with_firmware:
++ myri10ge_dummy_rdma(mgp, 0);
++
+ abort_with_ioremap:
+ iounmap(mgp->sram);
+
sparc64-do-not-define-bio_vmerge_boundary.patch
iop-adma-fix-platform-driver-hotplug-coldplug.patch
myri10ge-do-not-forget-to-setup-the-single-slice-pointers.patch
+myri10ge-do-not-use-mgp-max_intr_slots-before-loading-the-firmware.patch
+alsa-trident-pause-s-pdif-output.patch
+v4l-cx18-upgrade-to-newer-firmware-update-documentation.patch
+dvb-dib0700-add-support-for-hauppauge-nova-td-stick-52009.patch
+v4l-uvcvideo-fix-a-buffer-overflow-in-format-descriptor-parsing.patch
+v4l-uvcvideo-use-gfp_noio-when-allocating-memory-during-resume.patch
+v4l-uvcvideo-don-t-free-urb-buffers-on-suspend.patch
+v4l-uvcvideo-make-input-device-support-optional.patch
+v4l-uvcvideo-add-support-for-medion-akoya-mini-e1210-integrated-webcam.patch
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jul 21 19:36:58 2008
+From: Hans Verkuil <hverkuil@xs4all.nl>
+Date: Mon, 21 Jul 2008 21:53:43 -0400
+Subject: V4L: cx18: Upgrade to newer firmware & update documentation
+To: stable@kernel.org
+Cc: Hans Verkuil <hverkuil@xs4all.nl>, v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>, Mauro Carvalho Chehab <mchehab@infradead.org>
+Message-ID: <48853DA7.60302@linuxtv.org>
+
+From: Hans Verkuil <hverkuil@xs4all.nl>
+
+(cherry picked from commit 1a3932e0ed9ca46db2b76ce067e4ebaf04d91ea1)
+
+V4L: cx18: Upgrade to newer firmware & update cx18 documentation
+
+Conexant graciously gave us permission to redistribute the
+firmware. Update the documentation where the firmware can be
+downloaded.
+
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/video4linux/cx18.txt | 12 +++---------
+ drivers/media/video/cx18/cx18-firmware.c | 2 +-
+ 2 files changed, 4 insertions(+), 10 deletions(-)
+
+--- a/Documentation/video4linux/cx18.txt
++++ b/Documentation/video4linux/cx18.txt
+@@ -23,14 +23,8 @@ encoder chip:
+
+ Firmware:
+
+-The firmware needs to be extracted from the Windows Hauppauge HVR-1600
+-driver, available here:
++You can obtain the firmware files here:
+
+-http://hauppauge.lightpath.net/software/install_cd/hauppauge_cd_3.4d1.zip
++http://dl.ivtvdriver.org/ivtv/firmware/cx18-firmware.tar.gz
+
+-Unzip, then copy the following files to the firmware directory
+-and rename them as follows:
+-
+-Drivers/Driver18/hcw18apu.rom -> v4l-cx23418-apu.fw
+-Drivers/Driver18/hcw18enc.rom -> v4l-cx23418-cpu.fw
+-Drivers/Driver18/hcw18mlC.rom -> v4l-cx23418-dig.fw
++Untar and copy the .fw files to your firmware directory.
+--- a/drivers/media/video/cx18/cx18-firmware.c
++++ b/drivers/media/video/cx18/cx18-firmware.c
+@@ -90,7 +90,7 @@
+ #define CX18_DSP0_INTERRUPT_MASK 0xd0004C
+
+ /* Encoder/decoder firmware sizes */
+-#define CX18_FW_CPU_SIZE (174716)
++#define CX18_FW_CPU_SIZE (158332)
+ #define CX18_FW_APU_SIZE (141200)
+
+ #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jul 21 19:39:16 2008
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+Date: Mon, 21 Jul 2008 21:53:49 -0400
+Subject: V4L: uvcvideo: Add support for Medion Akoya Mini E1210 integrated webcam
+To: stable@kernel.org
+Cc: v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>, Tim Gardner <tim.gardner@canonical.com>, Laurent Pinchart <laurent.pinchart@skynet.be>, Mauro Carvalho Chehab <mchehab@infradead.org>
+Message-ID: <48853DAD.6040601@linuxtv.org>
+
+
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+
+(cherry picked from commit bdf2fe4a0b9d23e69c77eaec76212216c9a957ef)
+
+V4L: uvcvideo: Add support for Medion Akoya Mini E1210 integrated webcam
+
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/uvc/uvc_driver.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/media/video/uvc/uvc_driver.c
++++ b/drivers/media/video/uvc/uvc_driver.c
+@@ -1892,6 +1892,15 @@ static struct usb_device_id uvc_ids[] =
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
++ /* Medion Akoya Mini E1210 */
++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
++ | USB_DEVICE_ID_MATCH_INT_INFO,
++ .idVendor = 0x5986,
++ .idProduct = 0x0141,
++ .bInterfaceClass = USB_CLASS_VIDEO,
++ .bInterfaceSubClass = 1,
++ .bInterfaceProtocol = 0,
++ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Acer OrbiCam - Unknown vendor */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jul 21 19:39:10 2008
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+Date: Mon, 21 Jul 2008 21:53:47 -0400
+Subject: V4L: uvcvideo: Don't free URB buffers on suspend
+To: stable@kernel.org
+Cc: v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>, Laurent Pinchart <laurent.pinchart@skynet.be>, Mauro Carvalho Chehab <mchehab@infradead.org>
+Message-ID: <48853DAB.3000608@linuxtv.org>
+
+
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+
+(cherry picked from commit e01117c81676dc9897f567e32cdc13a26e85280b)
+
+V4L: uvcvideo: Don't free URB buffers on suspend.
+
+All submitted URBs must be killed at suspend time, but URB buffers don't
+have to be freed. Avoiding a free on suspend/reallocate on resume lowers
+the pressure on system memory.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/uvc/uvc_video.c | 96 ++++++++++++++++++++++++------------
+ drivers/media/video/uvc/uvcvideo.h | 2
+ 2 files changed, 66 insertions(+), 32 deletions(-)
+
+--- a/drivers/media/video/uvc/uvc_video.c
++++ b/drivers/media/video/uvc/uvc_video.c
+@@ -554,9 +554,56 @@ static void uvc_video_complete(struct ur
+ }
+
+ /*
++ * Free transfer buffers.
++ */
++static void uvc_free_urb_buffers(struct uvc_video_device *video)
++{
++ unsigned int i;
++
++ for (i = 0; i < UVC_URBS; ++i) {
++ if (video->urb_buffer[i]) {
++ usb_buffer_free(video->dev->udev, video->urb_size,
++ video->urb_buffer[i], video->urb_dma[i]);
++ video->urb_buffer[i] = NULL;
++ }
++ }
++
++ video->urb_size = 0;
++}
++
++/*
++ * Allocate transfer buffers. This function can be called with buffers
++ * already allocated when resuming from suspend, in which case it will
++ * return without touching the buffers.
++ *
++ * Return 0 on success or -ENOMEM when out of memory.
++ */
++static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
++ unsigned int size)
++{
++ unsigned int i;
++
++ /* Buffers are already allocated, bail out. */
++ if (video->urb_size)
++ return 0;
++
++ for (i = 0; i < UVC_URBS; ++i) {
++ video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
++ size, GFP_KERNEL, &video->urb_dma[i]);
++ if (video->urb_buffer[i] == NULL) {
++ uvc_free_urb_buffers(video);
++ return -ENOMEM;
++ }
++ }
++
++ video->urb_size = size;
++ return 0;
++}
++
++/*
+ * Uninitialize isochronous/bulk URBs and free transfer buffers.
+ */
+-static void uvc_uninit_video(struct uvc_video_device *video)
++static void uvc_uninit_video(struct uvc_video_device *video, int free_buffers)
+ {
+ struct urb *urb;
+ unsigned int i;
+@@ -566,19 +613,12 @@ static void uvc_uninit_video(struct uvc_
+ continue;
+
+ usb_kill_urb(urb);
+- /* urb->transfer_buffer_length is not touched by USB core, so
+- * we can use it here as the buffer length.
+- */
+- if (video->urb_buffer[i]) {
+- usb_buffer_free(video->dev->udev,
+- urb->transfer_buffer_length,
+- video->urb_buffer[i], urb->transfer_dma);
+- video->urb_buffer[i] = NULL;
+- }
+-
+ usb_free_urb(urb);
+ video->urb[i] = NULL;
+ }
++
++ if (free_buffers)
++ uvc_free_urb_buffers(video);
+ }
+
+ /*
+@@ -610,18 +650,13 @@ static int uvc_init_video_isoc(struct uv
+
+ size = npackets * psize;
+
++ if (uvc_alloc_urb_buffers(video, size) < 0)
++ return -ENOMEM;
++
+ for (i = 0; i < UVC_URBS; ++i) {
+ urb = usb_alloc_urb(npackets, gfp_flags);
+ if (urb == NULL) {
+- uvc_uninit_video(video);
+- return -ENOMEM;
+- }
+-
+- video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
+- size, gfp_flags, &urb->transfer_dma);
+- if (video->urb_buffer[i] == NULL) {
+- usb_free_urb(urb);
+- uvc_uninit_video(video);
++ uvc_uninit_video(video, 1);
+ return -ENOMEM;
+ }
+
+@@ -632,6 +667,7 @@ static int uvc_init_video_isoc(struct uv
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+ urb->interval = ep->desc.bInterval;
+ urb->transfer_buffer = video->urb_buffer[i];
++ urb->transfer_dma = video->urb_dma[i];
+ urb->complete = uvc_video_complete;
+ urb->number_of_packets = npackets;
+ urb->transfer_buffer_length = size;
+@@ -671,20 +707,15 @@ static int uvc_init_video_bulk(struct uv
+ if (size > psize * UVC_MAX_ISO_PACKETS)
+ size = psize * UVC_MAX_ISO_PACKETS;
+
++ if (uvc_alloc_urb_buffers(video, size) < 0)
++ return -ENOMEM;
++
+ pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress);
+
+ for (i = 0; i < UVC_URBS; ++i) {
+ urb = usb_alloc_urb(0, gfp_flags);
+ if (urb == NULL) {
+- uvc_uninit_video(video);
+- return -ENOMEM;
+- }
+-
+- video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
+- size, gfp_flags, &urb->transfer_dma);
+- if (video->urb_buffer[i] == NULL) {
+- usb_free_urb(urb);
+- uvc_uninit_video(video);
++ uvc_uninit_video(video, 1);
+ return -ENOMEM;
+ }
+
+@@ -692,6 +723,7 @@ static int uvc_init_video_bulk(struct uv
+ video->urb_buffer[i], size, uvc_video_complete,
+ video);
+ urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
++ urb->transfer_dma = video->urb_dma[i];
+
+ video->urb[i] = urb;
+ }
+@@ -766,7 +798,7 @@ static int uvc_init_video(struct uvc_vid
+ if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) {
+ uvc_printk(KERN_ERR, "Failed to submit URB %u "
+ "(%d).\n", i, ret);
+- uvc_uninit_video(video);
++ uvc_uninit_video(video, 1);
+ return ret;
+ }
+ }
+@@ -791,7 +823,7 @@ int uvc_video_suspend(struct uvc_video_d
+ return 0;
+
+ video->frozen = 1;
+- uvc_uninit_video(video);
++ uvc_uninit_video(video, 0);
+ usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
+ return 0;
+ }
+@@ -920,7 +952,7 @@ int uvc_video_enable(struct uvc_video_de
+ int ret;
+
+ if (!enable) {
+- uvc_uninit_video(video);
++ uvc_uninit_video(video, 1);
+ usb_set_interface(video->dev->udev,
+ video->streaming->intfnum, 0);
+ uvc_queue_enable(&video->queue, 0);
+--- a/drivers/media/video/uvc/uvcvideo.h
++++ b/drivers/media/video/uvc/uvcvideo.h
+@@ -602,6 +602,8 @@ struct uvc_video_device {
+
+ struct urb *urb[UVC_URBS];
+ char *urb_buffer[UVC_URBS];
++ dma_addr_t urb_dma[UVC_URBS];
++ unsigned int urb_size;
+
+ __u8 last_fid;
+ };
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jul 21 19:39:04 2008
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+Date: Mon, 21 Jul 2008 21:53:45 -0400
+Subject: V4L: uvcvideo: Fix a buffer overflow in format descriptor parsing
+To: stable@kernel.org
+Cc: v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>, Laurent Pinchart <laurent.pinchart@skynet.be>, Mauro Carvalho Chehab <mchehab@infradead.org>
+Message-ID: <48853DA9.8040700@linuxtv.org>
+
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+
+(cherry picked from commit 233548a2fd934a0220db8b1521c0bc88c82e5e53)
+
+V4L: uvcvideo: Fix a buffer overflow in format descriptor parsing
+
+Thanks to Oliver Neukum for catching and reporting this bug.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/uvc/uvc_driver.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/video/uvc/uvc_driver.c
++++ b/drivers/media/video/uvc/uvc_driver.c
+@@ -298,7 +298,8 @@ static int uvc_parse_format(struct uvc_d
+ switch (buffer[2]) {
+ case VS_FORMAT_UNCOMPRESSED:
+ case VS_FORMAT_FRAME_BASED:
+- if (buflen < 27) {
++ n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28;
++ if (buflen < n) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ "interface %d FORMAT error\n",
+ dev->udev->devnum,
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jul 21 19:37:00 2008
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+Date: Mon, 21 Jul 2008 22:07:22 -0400
+Subject: V4L: uvcvideo: Make input device support optional
+To: stable@kernel.org
+Cc: v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>, Laurent Pinchart <laurent.pinchart@skynet.be>, Mauro Carvalho Chehab <mchehab@infradead.org>
+Message-ID: <488540DA.8080200@linuxtv.org>
+
+
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+
+(cherry picked from commit 6833c917b4de1757febdbf946d709ece6dc7a86f)
+
+V4L: uvcvideo: Make input device support optional
+
+UVC devices can report button events. The uvcvideo driver depends on
+CONFIG_INPUT to report events to the input layer. This patch removes the hard
+dependency by introducing a new CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV option.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/Kconfig | 8 +-------
+ drivers/media/video/uvc/Kconfig | 17 +++++++++++++++++
+ drivers/media/video/uvc/uvc_status.c | 17 +++++++++++++++--
+ 3 files changed, 33 insertions(+), 9 deletions(-)
+
+--- a/drivers/media/video/Kconfig
++++ b/drivers/media/video/Kconfig
+@@ -793,13 +793,7 @@ menuconfig V4L_USB_DRIVERS
+
+ if V4L_USB_DRIVERS && USB
+
+-config USB_VIDEO_CLASS
+- tristate "USB Video Class (UVC)"
+- ---help---
+- Support for the USB Video Class (UVC). Currently only video
+- input devices, such as webcams, are supported.
+-
+- For more information see: <http://linux-uvc.berlios.de/>
++source "drivers/media/video/uvc/Kconfig"
+
+ source "drivers/media/video/pvrusb2/Kconfig"
+
+--- /dev/null
++++ b/drivers/media/video/uvc/Kconfig
+@@ -0,0 +1,17 @@
++config USB_VIDEO_CLASS
++ tristate "USB Video Class (UVC)"
++ ---help---
++ Support for the USB Video Class (UVC). Currently only video
++ input devices, such as webcams, are supported.
++
++ For more information see: <http://linux-uvc.berlios.de/>
++
++config USB_VIDEO_CLASS_INPUT_EVDEV
++ bool "UVC input events device support"
++ default y
++ depends on USB_VIDEO_CLASS && INPUT
++ ---help---
++ This option makes USB Video Class devices register an input device
++ to report button events.
++
++ If you are in doubt, say Y.
+--- a/drivers/media/video/uvc/uvc_status.c
++++ b/drivers/media/video/uvc/uvc_status.c
+@@ -22,6 +22,7 @@
+ /* --------------------------------------------------------------------------
+ * Input device
+ */
++#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
+ static int uvc_input_init(struct uvc_device *dev)
+ {
+ struct usb_device *udev = dev->udev;
+@@ -67,6 +68,19 @@ static void uvc_input_cleanup(struct uvc
+ input_unregister_device(dev->input);
+ }
+
++static void uvc_input_report_key(struct uvc_device *dev, unsigned int code,
++ int value)
++{
++ if (dev->input)
++ input_report_key(dev->input, code, value);
++}
++
++#else
++#define uvc_input_init(dev)
++#define uvc_input_cleanup(dev)
++#define uvc_input_report_key(dev, code, value)
++#endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */
++
+ /* --------------------------------------------------------------------------
+ * Status interrupt endpoint
+ */
+@@ -83,8 +97,7 @@ static void uvc_event_streaming(struct u
+ return;
+ uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n",
+ data[1], data[3] ? "pressed" : "released", len);
+- if (dev->input)
+- input_report_key(dev->input, BTN_0, data[3]);
++ uvc_input_report_key(dev, BTN_0, data[3]);
+ } else {
+ uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x "
+ "len %d.\n", data[1], data[2], data[3], len);
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jul 21 19:39:07 2008
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+Date: Mon, 21 Jul 2008 21:53:46 -0400
+Subject: V4L: uvcvideo: Use GFP_NOIO when allocating memory during resume
+To: stable@kernel.org
+Cc: v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>, Laurent Pinchart <laurent.pinchart@skynet.be>, Mauro Carvalho Chehab <mchehab@infradead.org>
+Message-ID: <48853DAA.2050206@linuxtv.org>
+
+
+From: Laurent Pinchart <laurent.pinchart@skynet.be>
+
+(cherry picked from commit 291358785cde5536d98a4f3cae77efd8ca626486)
+
+V4L: uvcvideo: Use GFP_NOIO when allocating memory during resume
+
+The swap device might still be asleep, so memory allocated in the resume
+handler must use GFP_NOIO. Thanks to Oliver Neukum for catching and reporting
+this bug.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/uvc/uvc_status.c | 2 +-
+ drivers/media/video/uvc/uvc_video.c | 24 ++++++++++++------------
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+
+--- a/drivers/media/video/uvc/uvc_status.c
++++ b/drivers/media/video/uvc/uvc_status.c
+@@ -203,5 +203,5 @@ int uvc_status_resume(struct uvc_device
+ if (dev->int_urb == NULL)
+ return 0;
+
+- return usb_submit_urb(dev->int_urb, GFP_KERNEL);
++ return usb_submit_urb(dev->int_urb, GFP_NOIO);
+ }
+--- a/drivers/media/video/uvc/uvc_video.c
++++ b/drivers/media/video/uvc/uvc_video.c
+@@ -586,7 +586,7 @@ static void uvc_uninit_video(struct uvc_
+ * is given by the endpoint.
+ */
+ static int uvc_init_video_isoc(struct uvc_video_device *video,
+- struct usb_host_endpoint *ep)
++ struct usb_host_endpoint *ep, gfp_t gfp_flags)
+ {
+ struct urb *urb;
+ unsigned int npackets, i, j;
+@@ -611,14 +611,14 @@ static int uvc_init_video_isoc(struct uv
+ size = npackets * psize;
+
+ for (i = 0; i < UVC_URBS; ++i) {
+- urb = usb_alloc_urb(npackets, GFP_KERNEL);
++ urb = usb_alloc_urb(npackets, gfp_flags);
+ if (urb == NULL) {
+ uvc_uninit_video(video);
+ return -ENOMEM;
+ }
+
+ video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
+- size, GFP_KERNEL, &urb->transfer_dma);
++ size, gfp_flags, &urb->transfer_dma);
+ if (video->urb_buffer[i] == NULL) {
+ usb_free_urb(urb);
+ uvc_uninit_video(video);
+@@ -652,7 +652,7 @@ static int uvc_init_video_isoc(struct uv
+ * given by the endpoint.
+ */
+ static int uvc_init_video_bulk(struct uvc_video_device *video,
+- struct usb_host_endpoint *ep)
++ struct usb_host_endpoint *ep, gfp_t gfp_flags)
+ {
+ struct urb *urb;
+ unsigned int pipe, i;
+@@ -674,14 +674,14 @@ static int uvc_init_video_bulk(struct uv
+ pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress);
+
+ for (i = 0; i < UVC_URBS; ++i) {
+- urb = usb_alloc_urb(0, GFP_KERNEL);
++ urb = usb_alloc_urb(0, gfp_flags);
+ if (urb == NULL) {
+ uvc_uninit_video(video);
+ return -ENOMEM;
+ }
+
+ video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
+- size, GFP_KERNEL, &urb->transfer_dma);
++ size, gfp_flags, &urb->transfer_dma);
+ if (video->urb_buffer[i] == NULL) {
+ usb_free_urb(urb);
+ uvc_uninit_video(video);
+@@ -702,7 +702,7 @@ static int uvc_init_video_bulk(struct uv
+ /*
+ * Initialize isochronous/bulk URBs and allocate transfer buffers.
+ */
+-static int uvc_init_video(struct uvc_video_device *video)
++static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
+ {
+ struct usb_interface *intf = video->streaming->intf;
+ struct usb_host_interface *alts;
+@@ -747,7 +747,7 @@ static int uvc_init_video(struct uvc_vid
+ if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0)
+ return ret;
+
+- ret = uvc_init_video_isoc(video, ep);
++ ret = uvc_init_video_isoc(video, ep, gfp_flags);
+ } else {
+ /* Bulk endpoint, proceed to URB initialization. */
+ ep = uvc_find_endpoint(&intf->altsetting[0],
+@@ -755,7 +755,7 @@ static int uvc_init_video(struct uvc_vid
+ if (ep == NULL)
+ return -EIO;
+
+- ret = uvc_init_video_bulk(video, ep);
++ ret = uvc_init_video_bulk(video, ep, gfp_flags);
+ }
+
+ if (ret < 0)
+@@ -763,7 +763,7 @@ static int uvc_init_video(struct uvc_vid
+
+ /* Submit the URBs. */
+ for (i = 0; i < UVC_URBS; ++i) {
+- if ((ret = usb_submit_urb(video->urb[i], GFP_KERNEL)) < 0) {
++ if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) {
+ uvc_printk(KERN_ERR, "Failed to submit URB %u "
+ "(%d).\n", i, ret);
+ uvc_uninit_video(video);
+@@ -818,7 +818,7 @@ int uvc_video_resume(struct uvc_video_de
+ if (!uvc_queue_streaming(&video->queue))
+ return 0;
+
+- if ((ret = uvc_init_video(video)) < 0)
++ if ((ret = uvc_init_video(video, GFP_NOIO)) < 0)
+ uvc_queue_enable(&video->queue, 0);
+
+ return ret;
+@@ -930,5 +930,5 @@ int uvc_video_enable(struct uvc_video_de
+ if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
+ return ret;
+
+- return uvc_init_video(video);
++ return uvc_init_video(video, GFP_KERNEL);
+ }