Revert most of 15cc2bb [media] DVB: dtv_property_cache_submit shouldn't modifiy the cache

Message ID 1320506379.1731.12.camel@gagarin (mailing list archive)
State Rejected, archived
Headers

Commit Message

lawrence rust Nov. 5, 2011, 3:19 p.m. UTC
  Hi,

I believe that I have found a problem with dtv_property_cache updating
when handling the legacy API.  This was introduced between 2.6.39 and
3.0.

dtv_property_cache_submit() in dvb_frontend.c tests the field
delivery_system and if it's a legacy type (including SYS_UNDEFINED) then
it calls dtv_property_legacy_params_sync().

The original patch removed the assignment to delivery_system in this
function.  However, the legacy API allows delivery_system to be
SYS_UNDEFINED - in fact is_legacy_delivery_system() tests for this
value.

If the delivery_system field is left as SYS_UNDEFINED then when tuning
is started, fe->ops.set_frontend() fails.

The current version of MythTV 0.24.1 is affected by this bug when using
a dvb-s2 card (tbs6981) tuned to a dvb-s channel.

Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk>
---
 drivers/media/dvb/dvb-core/dvb_frontend.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)
  

Comments

Andreas Oberritter Nov. 5, 2011, 4:39 p.m. UTC | #1
On 05.11.2011 16:19, Lawrence Rust wrote:
> Hi,
> 
> I believe that I have found a problem with dtv_property_cache updating
> when handling the legacy API.  This was introduced between 2.6.39 and
> 3.0.
> 
> dtv_property_cache_submit() in dvb_frontend.c tests the field
> delivery_system and if it's a legacy type (including SYS_UNDEFINED) then
> it calls dtv_property_legacy_params_sync().
> 
> The original patch removed the assignment to delivery_system in this
> function.  However, the legacy API allows delivery_system to be
> SYS_UNDEFINED - in fact is_legacy_delivery_system() tests for this
> value.
> 
> If the delivery_system field is left as SYS_UNDEFINED then when tuning
> is started, fe->ops.set_frontend() fails.
> 
> The current version of MythTV 0.24.1 is affected by this bug when using
> a dvb-s2 card (tbs6981) tuned to a dvb-s channel.

How does MythTV set the parameters (i.e. using which interface, calls)?
If using S2API, it should also set DTV_DELIVERY_SYSTEM.

SYS_UNDEFINED get's set by dvb_frontend_clear_cache() only. I think it
would be better to call dtv_property_cache_init() from there to get rid
of it.

> Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk>
> ---
>  drivers/media/dvb/dvb-core/dvb_frontend.c |    9 ++++++++-
>  1 files changed, 8 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
> index 5b6b451..06c3975 100644
> --- a/drivers/media/dvb/dvb-core/dvb_frontend.c
> +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
> @@ -1076,7 +1076,7 @@ static void dtv_property_cache_sync(struct dvb_frontend *fe,
>   */
>  static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
>  {
> -	const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
> +	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
>  	struct dvb_frontend_private *fepriv = fe->frontend_priv;
>  	struct dvb_frontend_parameters *p = &fepriv->parameters_in;
>  
> @@ -1088,12 +1088,14 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
>  		dprintk("%s() Preparing QPSK req\n", __func__);
>  		p->u.qpsk.symbol_rate = c->symbol_rate;
>  		p->u.qpsk.fec_inner = c->fec_inner;
> +		c->delivery_system = SYS_DVBS;
>  		break;
>  	case FE_QAM:
>  		dprintk("%s() Preparing QAM req\n", __func__);
>  		p->u.qam.symbol_rate = c->symbol_rate;
>  		p->u.qam.fec_inner = c->fec_inner;
>  		p->u.qam.modulation = c->modulation;
> +		c->delivery_system = SYS_DVBC_ANNEX_AC;
>  		break;
>  	case FE_OFDM:
>  		dprintk("%s() Preparing OFDM req\n", __func__);
> @@ -1111,10 +1113,15 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
>  		p->u.ofdm.transmission_mode = c->transmission_mode;
>  		p->u.ofdm.guard_interval = c->guard_interval;
>  		p->u.ofdm.hierarchy_information = c->hierarchy;
> +		c->delivery_system = SYS_DVBT;
>  		break;
>  	case FE_ATSC:
>  		dprintk("%s() Preparing VSB req\n", __func__);
>  		p->u.vsb.modulation = c->modulation;
> +		if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
> +			c->delivery_system = SYS_ATSC;
> +		else
> +			c->delivery_system = SYS_DVBC_ANNEX_B;
>  		break;
>  	}
>  }

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  
lawrence rust Nov. 5, 2011, 5:20 p.m. UTC | #2
On Sat, 2011-11-05 at 17:39 +0100, Andreas Oberritter wrote:
[snip]
> How does MythTV set the parameters (i.e. using which interface, calls)?
> If using S2API, it should also set DTV_DELIVERY_SYSTEM.

The following kern.log excerpt shows MythTV setting up the card:

Nov  5 11:54:52 cyclops kernel: [ 4139.489804] dvb_frontend_ioctl (82)  FE_SET_PROPERTY
Nov  5 11:54:52 cyclops kernel: [ 4139.489806] dvb_frontend_ioctl_properties
Nov  5 11:54:52 cyclops kernel: [ 4139.489808] dvb_frontend_ioctl_properties() properties.num = 1
Nov  5 11:54:52 cyclops kernel: [ 4139.489810] dvb_frontend_ioctl_properties() properties.props = bf95ec24
Nov  5 11:54:52 cyclops kernel: [ 4139.489813] dtv_property_dump() tvp.cmd    = 0x00000002 (DTV_CLEAR)
Nov  5 11:54:52 cyclops kernel: [ 4139.489814] dtv_property_dump() tvp.u.data = 0xb7819a31
Nov  5 11:54:52 cyclops kernel: [ 4139.489816] dtv_property_process_set() Flushing property cache
Nov  5 11:54:52 cyclops kernel: [ 4139.489841] dvb_frontend_ioctl (82) FE_SET_PROPERTY
Nov  5 11:54:52 cyclops kernel: [ 4139.489842] dvb_frontend_ioctl_properties
Nov  5 11:54:52 cyclops kernel: [ 4139.489843] dvb_frontend_ioctl_properties() properties.num = 7
Nov  5 11:54:52 cyclops kernel: [ 4139.489844] dvb_frontend_ioctl_properties() properties.props = 0a0acab0
Nov  5 11:54:52 cyclops kernel: [ 4139.489846] dtv_property_dump() tvp.cmd    = 0x00000011 (DTV_DELIVERY_SYSTEM)
Nov  5 11:54:52 cyclops kernel: [ 4139.489848] dtv_property_dump() tvp.u.data = 0x00000000
Nov  5 11:54:52 cyclops kernel: [ 4139.489850] dtv_property_dump() tvp.cmd    = 0x00000003 (DTV_FREQUENCY)
Nov  5 11:54:52 cyclops kernel: [ 4139.489851] dtv_property_dump() tvp.u.data = 0x0010104e
Nov  5 11:54:52 cyclops kernel: [ 4139.489853] dtv_property_dump() tvp.cmd    = 0x00000004 (DTV_MODULATION)
Nov  5 11:54:52 cyclops kernel: [ 4139.489854] dtv_property_dump() tvp.u.data = 0x00000000
Nov  5 11:54:52 cyclops kernel: [ 4139.489856] dtv_property_dump() tvp.cmd    = 0x00000006 (DTV_INVERSION)
Nov  5 11:54:52 cyclops kernel: [ 4139.489857] dtv_property_dump() tvp.u.data = 0x00000002
Nov  5 11:54:52 cyclops kernel: [ 4139.489859] dtv_property_dump() tvp.cmd    = 0x00000008 (DTV_SYMBOL_RATE)
Nov  5 11:54:52 cyclops kernel: [ 4139.489860] dtv_property_dump() tvp.u.data = 0x014fb180
Nov  5 11:54:52 cyclops kernel: [ 4139.489861] dtv_property_dump() tvp.cmd    = 0x00000009 (DTV_INNER_FEC)
Nov  5 11:54:52 cyclops kernel: [ 4139.489863] dtv_property_dump() tvp.u.data = 0x00000009
Nov  5 11:54:52 cyclops kernel: [ 4139.489864] dtv_property_dump() tvp.cmd    = 0x00000001 (DTV_TUNE)
Nov  5 11:54:52 cyclops kernel: [ 4139.489866] dtv_property_dump() tvp.u.data = 0x00000000
Nov  5 11:54:52 cyclops kernel: [ 4139.489867] dtv_property_process_set() Finalised property cache
Nov  5 11:54:52 cyclops kernel: [ 4139.489869] dtv_property_cache_submit() legacy, modulation = 0
Nov  5 11:54:52 cyclops kernel: [ 4139.489870] dtv_property_legacy_params_sync() Preparing QPSK req
Nov  5 11:54:52 cyclops kernel: [ 4139.489879] dvb_frontend_add_event
Nov  5 11:54:52 cyclops kernel: [ 4139.489880] dvb_frontend_ioctl_properties() Property cache is full, tuning
Nov  5 11:54:52 cyclops kernel: [ 4139.489897] dvb_frontend_thread: Frontend ALGO = DVBFE_ALGO_HW
Nov  5 11:54:52 cyclops kernel: [ 4139.489899] dvb_frontend_poll
Nov  5 11:54:52 cyclops kernel: [ 4139.489902] dvb_frontend_thread: Retune requested, FESTATE_RETUNE
Nov  5 11:54:52 cyclops kernel: [ 4139.489903] dvb_frontend_ioctl (69)  FE_READ_STATUS
Nov  5 11:54:52 cyclops kernel: [ 4139.489907] TurboSight TBS 6981 Frontend:
Nov  5 11:54:52 cyclops kernel: [ 4139.489907]  tbs6981fe - delivery system 0 is not supported

Note that DTV_DELIVERY_SYSTEM is set to 0 which worked OK in 2.6.39

> SYS_UNDEFINED get's set by dvb_frontend_clear_cache() only. I think it
> would be better to call dtv_property_cache_init() from there to get rid
> of it.

That doesn't fix this problem, which is explicitly setting
DTV_DELIVERY_SYSTEM.  A value of 0 (SYS_UNDEFINED) was accepted before
this change and should continue to be accepted.  In
dtv_property_cache_submit the comment reads:

/* For legacy delivery systems we don't need the delivery_system to
 * be specified, but we populate the older structures from the cache
 * so we can call set_frontend on older drivers.
 */
  
Andreas Oberritter Nov. 5, 2011, 5:38 p.m. UTC | #3
On 05.11.2011 18:20, Lawrence Rust wrote:
> On Sat, 2011-11-05 at 17:39 +0100, Andreas Oberritter wrote:
> [snip]
>> How does MythTV set the parameters (i.e. using which interface, calls)?
>> If using S2API, it should also set DTV_DELIVERY_SYSTEM.
> 
> The following kern.log excerpt shows MythTV setting up the card:
> 
> Nov  5 11:54:52 cyclops kernel: [ 4139.489804] dvb_frontend_ioctl (82)  FE_SET_PROPERTY
> Nov  5 11:54:52 cyclops kernel: [ 4139.489806] dvb_frontend_ioctl_properties
> Nov  5 11:54:52 cyclops kernel: [ 4139.489808] dvb_frontend_ioctl_properties() properties.num = 1
> Nov  5 11:54:52 cyclops kernel: [ 4139.489810] dvb_frontend_ioctl_properties() properties.props = bf95ec24
> Nov  5 11:54:52 cyclops kernel: [ 4139.489813] dtv_property_dump() tvp.cmd    = 0x00000002 (DTV_CLEAR)
> Nov  5 11:54:52 cyclops kernel: [ 4139.489814] dtv_property_dump() tvp.u.data = 0xb7819a31
> Nov  5 11:54:52 cyclops kernel: [ 4139.489816] dtv_property_process_set() Flushing property cache
> Nov  5 11:54:52 cyclops kernel: [ 4139.489841] dvb_frontend_ioctl (82) FE_SET_PROPERTY
> Nov  5 11:54:52 cyclops kernel: [ 4139.489842] dvb_frontend_ioctl_properties
> Nov  5 11:54:52 cyclops kernel: [ 4139.489843] dvb_frontend_ioctl_properties() properties.num = 7
> Nov  5 11:54:52 cyclops kernel: [ 4139.489844] dvb_frontend_ioctl_properties() properties.props = 0a0acab0
> Nov  5 11:54:52 cyclops kernel: [ 4139.489846] dtv_property_dump() tvp.cmd    = 0x00000011 (DTV_DELIVERY_SYSTEM)
> Nov  5 11:54:52 cyclops kernel: [ 4139.489848] dtv_property_dump() tvp.u.data = 0x00000000
> Nov  5 11:54:52 cyclops kernel: [ 4139.489850] dtv_property_dump() tvp.cmd    = 0x00000003 (DTV_FREQUENCY)
> Nov  5 11:54:52 cyclops kernel: [ 4139.489851] dtv_property_dump() tvp.u.data = 0x0010104e
> Nov  5 11:54:52 cyclops kernel: [ 4139.489853] dtv_property_dump() tvp.cmd    = 0x00000004 (DTV_MODULATION)
> Nov  5 11:54:52 cyclops kernel: [ 4139.489854] dtv_property_dump() tvp.u.data = 0x00000000
> Nov  5 11:54:52 cyclops kernel: [ 4139.489856] dtv_property_dump() tvp.cmd    = 0x00000006 (DTV_INVERSION)
> Nov  5 11:54:52 cyclops kernel: [ 4139.489857] dtv_property_dump() tvp.u.data = 0x00000002
> Nov  5 11:54:52 cyclops kernel: [ 4139.489859] dtv_property_dump() tvp.cmd    = 0x00000008 (DTV_SYMBOL_RATE)
> Nov  5 11:54:52 cyclops kernel: [ 4139.489860] dtv_property_dump() tvp.u.data = 0x014fb180
> Nov  5 11:54:52 cyclops kernel: [ 4139.489861] dtv_property_dump() tvp.cmd    = 0x00000009 (DTV_INNER_FEC)
> Nov  5 11:54:52 cyclops kernel: [ 4139.489863] dtv_property_dump() tvp.u.data = 0x00000009
> Nov  5 11:54:52 cyclops kernel: [ 4139.489864] dtv_property_dump() tvp.cmd    = 0x00000001 (DTV_TUNE)
> Nov  5 11:54:52 cyclops kernel: [ 4139.489866] dtv_property_dump() tvp.u.data = 0x00000000
> Nov  5 11:54:52 cyclops kernel: [ 4139.489867] dtv_property_process_set() Finalised property cache
> Nov  5 11:54:52 cyclops kernel: [ 4139.489869] dtv_property_cache_submit() legacy, modulation = 0
> Nov  5 11:54:52 cyclops kernel: [ 4139.489870] dtv_property_legacy_params_sync() Preparing QPSK req
> Nov  5 11:54:52 cyclops kernel: [ 4139.489879] dvb_frontend_add_event
> Nov  5 11:54:52 cyclops kernel: [ 4139.489880] dvb_frontend_ioctl_properties() Property cache is full, tuning
> Nov  5 11:54:52 cyclops kernel: [ 4139.489897] dvb_frontend_thread: Frontend ALGO = DVBFE_ALGO_HW
> Nov  5 11:54:52 cyclops kernel: [ 4139.489899] dvb_frontend_poll
> Nov  5 11:54:52 cyclops kernel: [ 4139.489902] dvb_frontend_thread: Retune requested, FESTATE_RETUNE
> Nov  5 11:54:52 cyclops kernel: [ 4139.489903] dvb_frontend_ioctl (69)  FE_READ_STATUS
> Nov  5 11:54:52 cyclops kernel: [ 4139.489907] TurboSight TBS 6981 Frontend:
> Nov  5 11:54:52 cyclops kernel: [ 4139.489907]  tbs6981fe - delivery system 0 is not supported
> 
> Note that DTV_DELIVERY_SYSTEM is set to 0 which worked OK in 2.6.39
> 
>> SYS_UNDEFINED get's set by dvb_frontend_clear_cache() only. I think it
>> would be better to call dtv_property_cache_init() from there to get rid
>> of it.
> 
> That doesn't fix this problem, which is explicitly setting
> DTV_DELIVERY_SYSTEM.  A value of 0 (SYS_UNDEFINED) was accepted before
> this change and should continue to be accepted.

I don't get how this could be useful. MythTV knows what delivery system
it wants to use, so it should pass this information to the kernel.
Trying to set an invalid delivery system must fail.

Using SYS_UNDEFINED as a pre-set default is different from setting
SYS_UNDEFINED from userspace, which should always generate an error IMO,
unless this is documented otherwise in the API specification.

Regards,
Andreas

> In
> dtv_property_cache_submit the comment reads:
> 
> /* For legacy delivery systems we don't need the delivery_system to
>  * be specified, but we populate the older structures from the cache
>  * so we can call set_frontend on older drivers.
>  */
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  
lawrence rust Nov. 5, 2011, 5:57 p.m. UTC | #4
On Sat, 2011-11-05 at 18:38 +0100, Andreas Oberritter wrote:
[snip]
> I don't get how this could be useful. MythTV knows what delivery system
> it wants to use, so it should pass this information to the kernel.
> Trying to set an invalid delivery system must fail.
> 
> Using SYS_UNDEFINED as a pre-set default is different from setting
> SYS_UNDEFINED from userspace, which should always generate an error IMO,
> unless this is documented otherwise in the API specification.

It's not ideal that MythTV is setting DTV_DELIVERY_SYSTEM to 0 and I
have filed a bug against this.  But that doesn't change the fact that
the original patch significantly changed user parameter handling for no
significant benefit.  MythTV is probably the biggest client of v4l and
will greatly hinder users upgrading to (Myth)Ubuntu 12.04 or Fedora 16
both of which use Linux 3.x.
  
Mauro Carvalho Chehab Nov. 24, 2011, 4:38 p.m. UTC | #5
Em 05-11-2011 15:57, Lawrence Rust escreveu:
> On Sat, 2011-11-05 at 18:38 +0100, Andreas Oberritter wrote:
> [snip]
>> I don't get how this could be useful. MythTV knows what delivery system
>> it wants to use, so it should pass this information to the kernel.
>> Trying to set an invalid delivery system must fail.
>>
>> Using SYS_UNDEFINED as a pre-set default is different from setting
>> SYS_UNDEFINED from userspace, which should always generate an error IMO,
>> unless this is documented otherwise in the API specification.
> 
> It's not ideal that MythTV is setting DTV_DELIVERY_SYSTEM to 0 and I
> have filed a bug against this.  But that doesn't change the fact that
> the original patch significantly changed user parameter handling for no
> significant benefit.  MythTV is probably the biggest client of v4l and
> will greatly hinder users upgrading to (Myth)Ubuntu 12.04 or Fedora 16
> both of which use Linux 3.x.

Regression is a bad thing. However, in this specific case, I agree with
Andreas: an assumption that the Kernel will replace SYS_UNDEFINED by something
else is a very bad thing. It also hides a bug, as there are no way for devices 
that support more than one delivery system to properly select the desired
one. 

So, this patch won't fix it.

So, I suspect that you'll need to open a BZ also at Ubuntu and Fedora, in
order to backport the MythTV fix into them.

Regards,
Mauro





--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  

Patch

diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 5b6b451..06c3975 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1076,7 +1076,7 @@  static void dtv_property_cache_sync(struct dvb_frontend *fe,
  */
 static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
 {
-	const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	struct dvb_frontend_parameters *p = &fepriv->parameters_in;
 
@@ -1088,12 +1088,14 @@  static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
 		dprintk("%s() Preparing QPSK req\n", __func__);
 		p->u.qpsk.symbol_rate = c->symbol_rate;
 		p->u.qpsk.fec_inner = c->fec_inner;
+		c->delivery_system = SYS_DVBS;
 		break;
 	case FE_QAM:
 		dprintk("%s() Preparing QAM req\n", __func__);
 		p->u.qam.symbol_rate = c->symbol_rate;
 		p->u.qam.fec_inner = c->fec_inner;
 		p->u.qam.modulation = c->modulation;
+		c->delivery_system = SYS_DVBC_ANNEX_AC;
 		break;
 	case FE_OFDM:
 		dprintk("%s() Preparing OFDM req\n", __func__);
@@ -1111,10 +1113,15 @@  static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
 		p->u.ofdm.transmission_mode = c->transmission_mode;
 		p->u.ofdm.guard_interval = c->guard_interval;
 		p->u.ofdm.hierarchy_information = c->hierarchy;
+		c->delivery_system = SYS_DVBT;
 		break;
 	case FE_ATSC:
 		dprintk("%s() Preparing VSB req\n", __func__);
 		p->u.vsb.modulation = c->modulation;
+		if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
+			c->delivery_system = SYS_ATSC;
+		else
+			c->delivery_system = SYS_DVBC_ANNEX_B;
 		break;
 	}
 }