From 556a0442e08a8bc8541587a349cbf26ed14ec6de Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Fri, 6 Apr 2012 18:38:18 -0300 Subject: [media] dvb_frontend: regression fix: userspace ABI broken for xine The commit e399ce77e6e has broken the DVB ABI for xine: The problem is that xine is expecting every event after a successful FE_SET_FRONTEND ioctl to have a non-zero frequency parameter, regardless of whether the tuning process has LOCKed yet. What used to happen is that the events inherited the initial tuning parameters from the FE_SET_FRONTEND call. However, the fepriv->parameters_out struct is now not initialised until the status contains the FE_HAS_LOCK bit. You might argue that this behaviour is intentional, except that if an application other than xine uses the DVB adapter and manages to set the parameters_out.frequency field to something other than zero, then xine no longer has any problems until either the adapter is replugged or the kernel modules reloaded. This can only mean that the fepriv->parameters_out struct still contains the (stale) tuning information from the previous application. Signed-off-by: Chris Rankin Cc: stable@kernel.org # for kernel version 3.3 Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 4555baa..e721975 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -143,6 +143,8 @@ struct dvb_frontend_private { static void dvb_frontend_wakeup(struct dvb_frontend *fe); static int dtv_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p_out); +static int dtv_property_legacy_params_sync(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p); static bool has_get_frontend(struct dvb_frontend *fe) { @@ -697,6 +699,7 @@ restart: fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; fepriv->delay = HZ / 2; } + dtv_property_legacy_params_sync(fe, &fepriv->parameters_out); fe->ops.read_status(fe, &s); if (s != fepriv->status) { dvb_frontend_add_event(fe, s); /* update event list */ @@ -1833,6 +1836,13 @@ static int dtv_set_frontend(struct dvb_frontend *fe) return -EINVAL; /* + * Initialize output parameters to match the values given by + * the user. FE_SET_FRONTEND triggers an initial frontend event + * with status = 0, which copies output parameters to userspace. + */ + dtv_property_legacy_params_sync(fe, &fepriv->parameters_out); + + /* * Be sure that the bandwidth will be filled for all * non-satellite systems, as tuners need to know what * low pass/Nyquist half filter should be applied, in -- cgit v0.10.2 From bc169e35e3a72c6888b7d12f50f2c4063436d834 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 31 Mar 2012 05:18:19 -0300 Subject: [media] ivtv: Fix AUDIO_(BILINGUAL_)CHANNEL_SELECT regression When I converted ivtv to the new decoder API I introduced a regression in the support of the old channel select API. Thanks to Martin Dauskardt for reporting this. Signed-off-by: Hans Verkuil Reviewed-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 5452bee..989e556 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1763,13 +1763,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); if (iarg > AUDIO_STEREO_SWAPPED) return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg); + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1); case AUDIO_BILINGUAL_CHANNEL_SELECT: IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); if (iarg > AUDIO_STEREO_SWAPPED) return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg); + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1); default: return -EINVAL; -- cgit v0.10.2 From 4da28766140449e04270246fae310c137180652d Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 25 Mar 2012 06:57:49 -0300 Subject: [media] it913x: fix firmware loading errors On some systems the device does not respond or give obscure values after cold, warm or firmware reboot. This patch retries to get chip version and type 5 times. If it fails it applies chip version 0x1 and type 0x9135. This patch does not fix warm cycle problems from other operating systems and indeed the reverse applies. Users should power off cold boot. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index 3b7b102..482d249 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -238,12 +238,27 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg) static u32 it913x_query(struct usb_device *udev, u8 pro) { - int ret; + int ret, i; u8 data[4]; - ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, - 0x1222, 0, &data[0], 3); + u8 ver; + + for (i = 0; i < 5; i++) { + ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, + 0x1222, 0, &data[0], 3); + ver = data[0]; + if (ver > 0 && ver < 3) + break; + msleep(100); + } - it913x_config.chip_ver = data[0]; + if (ver < 1 || ver > 2) { + info("Failed to identify chip version applying 1"); + it913x_config.chip_ver = 0x1; + it913x_config.chip_type = 0x9135; + return 0; + } + + it913x_config.chip_ver = ver; it913x_config.chip_type = (u16)(data[2] << 8) + data[1]; info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver, @@ -660,30 +675,41 @@ static int it913x_download_firmware(struct usb_device *udev, if ((packet_size > min_pkt) || (i == fw->size)) { fw_data = (u8 *)(fw->data + pos); pos += packet_size; - if (packet_size > 0) - ret |= it913x_io(udev, WRITE_DATA, + if (packet_size > 0) { + ret = it913x_io(udev, WRITE_DATA, DEV_0, CMD_SCATTER_WRITE, 0, 0, fw_data, packet_size); + if (ret < 0) + break; + } udelay(1000); } } i++; } - ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); - - msleep(100); - if (ret < 0) - info("FRM Firmware Download Failed (%04x)" , ret); + info("FRM Firmware Download Failed (%d)" , ret); else info("FRM Firmware Download Completed - Resetting Device"); - ret |= it913x_return_status(udev); + msleep(30); + + ret = it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); + if (ret < 0) + info("FRM Device not responding to reboot"); + + ret = it913x_return_status(udev); + if (ret == 0) { + info("FRM Failed to reboot device"); + return -ENODEV; + } msleep(30); - ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); + ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); + + msleep(30); /* Tuner function */ if (it913x_config.dual_mode) @@ -901,5 +927,5 @@ module_usb_driver(it913x_driver); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.27"); +MODULE_VERSION("1.28"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From c065f5b4ee4487bbd411049be6eea1b59a90db96 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Tue, 27 Mar 2012 12:53:19 -0300 Subject: [media] dvb_frontend: fix compiler warning has_get_frontend() should return a boolean, not a pointer. Signed-off-by: Hans Petter Selasky Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index e721975..39696c6 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -148,7 +148,7 @@ static int dtv_property_legacy_params_sync(struct dvb_frontend *fe, static bool has_get_frontend(struct dvb_frontend *fe) { - return fe->ops.get_frontend; + return fe->ops.get_frontend != NULL; } /* -- cgit v0.10.2 From d3a92d624806a7964ca3122f917ff2ba69e4cdd8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 1 Apr 2012 15:24:48 -0300 Subject: [media] Drivers/media/radio: Fix build error On Sunday, April 01, 2012 21:09:34 Tracey Dent wrote: > radio-maxiradio depends on SND_FM801_TEA575X_BOOL to build or will > result in an build error such as: > > Kernel: arch/x86/boot/bzImage is ready (#1) > ERROR: "snd_tea575x_init" [drivers/media/radio/radio-maxiradio.ko] undefined! > ERROR: "snd_tea575x_exit" [drivers/media/radio/radio-maxiradio.ko] undefined! > WARNING: modpost: Found 6 section mismatch(es). > To see full details build your kernel with: > 'make CONFIG_DEBUG_SECTION_MISMATCH=y' > make[1]: *** [__modpost] Error 1 > make: *** [modules] Error 2 > > Select CONFIG_SND_TEA575X to fixes problem and enable > the driver to be built as desired. > > v2: > instead of selecting CONFIG_SND_FM801_TEA575X_BOOL, select > CONFIG_SND_TEA575X, which in turns selects CONFIG_SND_FM801_TEA575X_BOOL > and any other dependencies for it to build. No, this is the correct patch: RADIO_MAXIRADIO should be treated just like RADIO_SF16FMR2, I just didn't realize at the time that it had to be added as a SND_TEA575X dependency. Signed-off-by: Hans Verkuil Tested-by: Shea Levy Acked-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 8816804..5ca0939 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -2,8 +2,8 @@ config SND_TEA575X tristate - depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 - default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 + depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO + default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO menuconfig SND_PCI bool "PCI sound devices" -- cgit v0.10.2 From ed0ee0ce0a3224dab5caa088a5f8b6df25924276 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 27 Mar 2012 05:51:00 -0300 Subject: [media] uvcvideo: Fix race-related crash in uvc_video_clock_update() The driver frees the clock samples buffer before stopping the video buffers queue. If a DQBUF call arrives in-between, uvc_video_clock_update() will be called with a NULL clock samples buffer, leading to a crash. This occurs very frequently when using the webcam with the flash browser plugin. Move clock initialization/cleanup to uvc_video_enable() in order to free the clock samples buffer after the queue is stopped. Make sure the clock is reset at resume time to avoid miscalculating timestamps. Signed-off-by: Laurent Pinchart Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 4a44f9a..b76b0ac 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -468,22 +468,30 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, spin_unlock_irqrestore(&stream->clock.lock, flags); } -static int uvc_video_clock_init(struct uvc_streaming *stream) +static void uvc_video_clock_reset(struct uvc_streaming *stream) { struct uvc_clock *clock = &stream->clock; - spin_lock_init(&clock->lock); clock->head = 0; clock->count = 0; - clock->size = 32; clock->last_sof = -1; clock->sof_offset = -1; +} + +static int uvc_video_clock_init(struct uvc_streaming *stream) +{ + struct uvc_clock *clock = &stream->clock; + + spin_lock_init(&clock->lock); + clock->size = 32; clock->samples = kmalloc(clock->size * sizeof(*clock->samples), GFP_KERNEL); if (clock->samples == NULL) return -ENOMEM; + uvc_video_clock_reset(stream); + return 0; } @@ -1424,8 +1432,6 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) if (free_buffers) uvc_free_urb_buffers(stream); - - uvc_video_clock_cleanup(stream); } /* @@ -1555,10 +1561,6 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) uvc_video_stats_start(stream); - ret = uvc_video_clock_init(stream); - if (ret < 0) - return ret; - if (intf->num_altsetting > 1) { struct usb_host_endpoint *best_ep = NULL; unsigned int best_psize = 3 * 1024; @@ -1683,6 +1685,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) stream->frozen = 0; + uvc_video_clock_reset(stream); + ret = uvc_commit_video(stream, &stream->ctrl); if (ret < 0) { uvc_queue_enable(&stream->queue, 0); @@ -1819,25 +1823,35 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) uvc_uninit_video(stream, 1); usb_set_interface(stream->dev->udev, stream->intfnum, 0); uvc_queue_enable(&stream->queue, 0); + uvc_video_clock_cleanup(stream); return 0; } - ret = uvc_queue_enable(&stream->queue, 1); + ret = uvc_video_clock_init(stream); if (ret < 0) return ret; + ret = uvc_queue_enable(&stream->queue, 1); + if (ret < 0) + goto error_queue; + /* Commit the streaming parameters. */ ret = uvc_commit_video(stream, &stream->ctrl); - if (ret < 0) { - uvc_queue_enable(&stream->queue, 0); - return ret; - } + if (ret < 0) + goto error_commit; ret = uvc_init_video(stream, GFP_KERNEL); - if (ret < 0) { - usb_set_interface(stream->dev->udev, stream->intfnum, 0); - uvc_queue_enable(&stream->queue, 0); - } + if (ret < 0) + goto error_video; + + return 0; + +error_video: + usb_set_interface(stream->dev->udev, stream->intfnum, 0); +error_commit: + uvc_queue_enable(&stream->queue, 0); +error_queue: + uvc_video_clock_cleanup(stream); return ret; } -- cgit v0.10.2