]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
some v4l patches for .26
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 30 Jul 2008 19:11:19 +0000 (12:11 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 30 Jul 2008 19:11:19 +0000 (12:11 -0700)
queue-2.6.26/alsa-trident-pause-s-pdif-output.patch [new file with mode: 0644]
queue-2.6.26/dvb-dib0700-add-support-for-hauppauge-nova-td-stick-52009.patch [new file with mode: 0644]
queue-2.6.26/myri10ge-do-not-use-mgp-max_intr_slots-before-loading-the-firmware.patch [new file with mode: 0644]
queue-2.6.26/series
queue-2.6.26/v4l-cx18-upgrade-to-newer-firmware-update-documentation.patch [new file with mode: 0644]
queue-2.6.26/v4l-uvcvideo-add-support-for-medion-akoya-mini-e1210-integrated-webcam.patch [new file with mode: 0644]
queue-2.6.26/v4l-uvcvideo-don-t-free-urb-buffers-on-suspend.patch [new file with mode: 0644]
queue-2.6.26/v4l-uvcvideo-fix-a-buffer-overflow-in-format-descriptor-parsing.patch [new file with mode: 0644]
queue-2.6.26/v4l-uvcvideo-make-input-device-support-optional.patch [new file with mode: 0644]
queue-2.6.26/v4l-uvcvideo-use-gfp_noio-when-allocating-memory-during-resume.patch [new file with mode: 0644]

diff --git a/queue-2.6.26/alsa-trident-pause-s-pdif-output.patch b/queue-2.6.26/alsa-trident-pause-s-pdif-output.patch
new file mode 100644 (file)
index 0000000..b43da77
--- /dev/null
@@ -0,0 +1,41 @@
+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;
diff --git a/queue-2.6.26/dvb-dib0700-add-support-for-hauppauge-nova-td-stick-52009.patch b/queue-2.6.26/dvb-dib0700-add-support-for-hauppauge-nova-td-stick-52009.patch
new file mode 100644 (file)
index 0000000..1345bda
--- /dev/null
@@ -0,0 +1,63 @@
+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
diff --git a/queue-2.6.26/myri10ge-do-not-use-mgp-max_intr_slots-before-loading-the-firmware.patch b/queue-2.6.26/myri10ge-do-not-use-mgp-max_intr_slots-before-loading-the-firmware.patch
new file mode 100644 (file)
index 0000000..df902ee
--- /dev/null
@@ -0,0 +1,103 @@
+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);
index 4c952c763faeeed0adfba149c4bf852813daad99..70a1ac8b52338ab11f7466c4cd9e70dbad3e0a1f 100644 (file)
@@ -33,3 +33,12 @@ sparc64-fix-cpufreq-notifier-registry.patch
 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
diff --git a/queue-2.6.26/v4l-cx18-upgrade-to-newer-firmware-update-documentation.patch b/queue-2.6.26/v4l-cx18-upgrade-to-newer-firmware-update-documentation.patch
new file mode 100644 (file)
index 0000000..1878370
--- /dev/null
@@ -0,0 +1,59 @@
+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" */
diff --git a/queue-2.6.26/v4l-uvcvideo-add-support-for-medion-akoya-mini-e1210-integrated-webcam.patch b/queue-2.6.26/v4l-uvcvideo-add-support-for-medion-akoya-mini-e1210-integrated-webcam.patch
new file mode 100644 (file)
index 0000000..4c66ca4
--- /dev/null
@@ -0,0 +1,43 @@
+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,
diff --git a/queue-2.6.26/v4l-uvcvideo-don-t-free-urb-buffers-on-suspend.patch b/queue-2.6.26/v4l-uvcvideo-don-t-free-urb-buffers-on-suspend.patch
new file mode 100644 (file)
index 0000000..7cb3dfb
--- /dev/null
@@ -0,0 +1,214 @@
+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;
+ };
diff --git a/queue-2.6.26/v4l-uvcvideo-fix-a-buffer-overflow-in-format-descriptor-parsing.patch b/queue-2.6.26/v4l-uvcvideo-fix-a-buffer-overflow-in-format-descriptor-parsing.patch
new file mode 100644 (file)
index 0000000..e7db3c2
--- /dev/null
@@ -0,0 +1,37 @@
+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,
diff --git a/queue-2.6.26/v4l-uvcvideo-make-input-device-support-optional.patch b/queue-2.6.26/v4l-uvcvideo-make-input-device-support-optional.patch
new file mode 100644 (file)
index 0000000..0f8c92d
--- /dev/null
@@ -0,0 +1,107 @@
+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);
diff --git a/queue-2.6.26/v4l-uvcvideo-use-gfp_noio-when-allocating-memory-during-resume.patch b/queue-2.6.26/v4l-uvcvideo-use-gfp_noio-when-allocating-memory-during-resume.patch
new file mode 100644 (file)
index 0000000..615ddbe
--- /dev/null
@@ -0,0 +1,144 @@
+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);
+ }