From: Greg Kroah-Hartman Date: Wed, 30 Jul 2008 19:11:19 +0000 (-0700) Subject: some v4l patches for .26 X-Git-Tag: v2.6.26.1~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=65043c8d154c50c3f6e86c73bc5c3dac3f07a080;p=thirdparty%2Fkernel%2Fstable-queue.git some v4l patches for .26 --- 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 index 00000000000..b43da77a43a --- /dev/null +++ b/queue-2.6.26/alsa-trident-pause-s-pdif-output.patch @@ -0,0 +1,41 @@ +From stable-bounces@linux.kernel.org Fri Jul 18 16:37:37 2008 +From: Pierre Ossman +Date: Fri, 18 Jul 2008 19:04:27 -0400 +Subject: ALSA: trident - pause s/pdif output +To: stable@kernel.org +Cc: Takashi Iwai , cebbert@redhat.com +Message-ID: <20080718190427.7cdfe1da@redhat.com> + + +From: Pierre Ossman + +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 +Tested-by: Rene Herman +Signed-off-by: Takashi Iwai +Signed-off-by: Jaroslav Kysela +Cc: Chuck Ebbert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1345bdaacd4 --- /dev/null +++ b/queue-2.6.26/dvb-dib0700-add-support-for-hauppauge-nova-td-stick-52009.patch @@ -0,0 +1,63 @@ +From stable-bounces@linux.kernel.org Mon Jul 21 19:39:04 2008 +From: Michael Krufky +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 , Mauro Carvalho Chehab +Message-ID: <48853DA8.8040609@linuxtv.org> + +From: Michael Krufky + +(cherry picked from commit d01eb2dc7d5265ec3bee9ec1b8ab79155e1310d6) + +DVB: dib0700: add support for Hauppauge Nova-TD Stick 52009 + +Signed-off-by: Michael Krufky +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..df902eeb42b --- /dev/null +++ b/queue-2.6.26/myri10ge-do-not-use-mgp-max_intr_slots-before-loading-the-firmware.patch @@ -0,0 +1,103 @@ +From stable-bounces@linux.kernel.org Wed Jul 23 01:47:42 2008 +From: Brice Goglin +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-2.6.26/series b/queue-2.6.26/series index 4c952c763fa..70a1ac8b523 100644 --- a/queue-2.6.26/series +++ b/queue-2.6.26/series @@ -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 index 00000000000..1878370d16b --- /dev/null +++ b/queue-2.6.26/v4l-cx18-upgrade-to-newer-firmware-update-documentation.patch @@ -0,0 +1,59 @@ +From stable-bounces@linux.kernel.org Mon Jul 21 19:36:58 2008 +From: Hans Verkuil +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 , v4l-dvb maintainer list , Mauro Carvalho Chehab +Message-ID: <48853DA7.60302@linuxtv.org> + +From: Hans Verkuil + +(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 +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4c66ca4e7a7 --- /dev/null +++ b/queue-2.6.26/v4l-uvcvideo-add-support-for-medion-akoya-mini-e1210-integrated-webcam.patch @@ -0,0 +1,43 @@ +From stable-bounces@linux.kernel.org Mon Jul 21 19:39:16 2008 +From: Laurent Pinchart +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 , Tim Gardner , Laurent Pinchart , Mauro Carvalho Chehab +Message-ID: <48853DAD.6040601@linuxtv.org> + + +From: Laurent Pinchart + +(cherry picked from commit bdf2fe4a0b9d23e69c77eaec76212216c9a957ef) + +V4L: uvcvideo: Add support for Medion Akoya Mini E1210 integrated webcam + +Signed-off-by: Tim Gardner +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7cb3dfb619b --- /dev/null +++ b/queue-2.6.26/v4l-uvcvideo-don-t-free-urb-buffers-on-suspend.patch @@ -0,0 +1,214 @@ +From stable-bounces@linux.kernel.org Mon Jul 21 19:39:10 2008 +From: Laurent Pinchart +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 , Laurent Pinchart , Mauro Carvalho Chehab +Message-ID: <48853DAB.3000608@linuxtv.org> + + +From: Laurent Pinchart + +(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 +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e7db3c28199 --- /dev/null +++ b/queue-2.6.26/v4l-uvcvideo-fix-a-buffer-overflow-in-format-descriptor-parsing.patch @@ -0,0 +1,37 @@ +From stable-bounces@linux.kernel.org Mon Jul 21 19:39:04 2008 +From: Laurent Pinchart +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 , Laurent Pinchart , Mauro Carvalho Chehab +Message-ID: <48853DA9.8040700@linuxtv.org> + +From: Laurent Pinchart + +(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 +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0f8c92d70e1 --- /dev/null +++ b/queue-2.6.26/v4l-uvcvideo-make-input-device-support-optional.patch @@ -0,0 +1,107 @@ +From stable-bounces@linux.kernel.org Mon Jul 21 19:37:00 2008 +From: Laurent Pinchart +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 , Laurent Pinchart , Mauro Carvalho Chehab +Message-ID: <488540DA.8080200@linuxtv.org> + + +From: Laurent Pinchart + +(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 +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + 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: ++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: ++ ++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 index 00000000000..615ddbeb01f --- /dev/null +++ b/queue-2.6.26/v4l-uvcvideo-use-gfp_noio-when-allocating-memory-during-resume.patch @@ -0,0 +1,144 @@ +From stable-bounces@linux.kernel.org Mon Jul 21 19:39:07 2008 +From: Laurent Pinchart +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 , Laurent Pinchart , Mauro Carvalho Chehab +Message-ID: <48853DAA.2050206@linuxtv.org> + + +From: Laurent Pinchart + +(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 +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + }