diff options
author | Janne Grunau <j@jannau.net> | 2009-09-01 18:23:09 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-12 11:20:03 -0400 |
commit | 01886255ddf440eb21d3388bfc5343c966904d0e (patch) | |
tree | 1357fb305de3fa62564b429843553ad2890a583d /drivers/media | |
parent | 4457ef1d6163533073efdebed82a049aad44e3b3 (diff) |
V4L/DVB (12685): dvb-core: check fe->ops.set_frontend return value
Various frontend driver have parameter checks in their set_frontend
functions and return an error if the parameters are not supported,
tda10021 and cx24116 to name two.
The tuning ioctls FE_SET_FRONTEND/FE_SET_PROPERTY only change values
in the property cache and return before set_frontend is called. If a
set_frontend call in software zigzag algorithm fails and the card was
previously locked it will report a lock and the new parameters but is
still tuned to the old transport. This is not detectable from
userspace.
This change checks the return values of fe->ops.set_frontend and
changes the state to the added FESTATE_ERROR for software zigzag.
No lock will be reported to userspace if the State is FESTATE_ERROR.
Signed-off-by: Janne Grunau <j@jannau.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index f50ca7292a7d..0cb6c09719f2 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -72,6 +72,7 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open( | |||
72 | #define FESTATE_ZIGZAG_FAST 32 | 72 | #define FESTATE_ZIGZAG_FAST 32 |
73 | #define FESTATE_ZIGZAG_SLOW 64 | 73 | #define FESTATE_ZIGZAG_SLOW 64 |
74 | #define FESTATE_DISEQC 128 | 74 | #define FESTATE_DISEQC 128 |
75 | #define FESTATE_ERROR 256 | ||
75 | #define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC) | 76 | #define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC) |
76 | #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) | 77 | #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) |
77 | #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) | 78 | #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) |
@@ -269,6 +270,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra | |||
269 | { | 270 | { |
270 | int autoinversion; | 271 | int autoinversion; |
271 | int ready = 0; | 272 | int ready = 0; |
273 | int fe_set_err = 0; | ||
272 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 274 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
273 | int original_inversion = fepriv->parameters.inversion; | 275 | int original_inversion = fepriv->parameters.inversion; |
274 | u32 original_frequency = fepriv->parameters.frequency; | 276 | u32 original_frequency = fepriv->parameters.frequency; |
@@ -345,7 +347,11 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra | |||
345 | if (autoinversion) | 347 | if (autoinversion) |
346 | fepriv->parameters.inversion = fepriv->inversion; | 348 | fepriv->parameters.inversion = fepriv->inversion; |
347 | if (fe->ops.set_frontend) | 349 | if (fe->ops.set_frontend) |
348 | fe->ops.set_frontend(fe, &fepriv->parameters); | 350 | fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters); |
351 | if (fe_set_err < 0) { | ||
352 | fepriv->state = FESTATE_ERROR; | ||
353 | return fe_set_err; | ||
354 | } | ||
349 | 355 | ||
350 | fepriv->parameters.frequency = original_frequency; | 356 | fepriv->parameters.frequency = original_frequency; |
351 | fepriv->parameters.inversion = original_inversion; | 357 | fepriv->parameters.inversion = original_inversion; |
@@ -357,6 +363,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra | |||
357 | static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | 363 | static void dvb_frontend_swzigzag(struct dvb_frontend *fe) |
358 | { | 364 | { |
359 | fe_status_t s = 0; | 365 | fe_status_t s = 0; |
366 | int retval = 0; | ||
360 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 367 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
361 | 368 | ||
362 | /* if we've got no parameters, just keep idling */ | 369 | /* if we've got no parameters, just keep idling */ |
@@ -370,8 +377,12 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
370 | if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { | 377 | if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { |
371 | if (fepriv->state & FESTATE_RETUNE) { | 378 | if (fepriv->state & FESTATE_RETUNE) { |
372 | if (fe->ops.set_frontend) | 379 | if (fe->ops.set_frontend) |
373 | fe->ops.set_frontend(fe, &fepriv->parameters); | 380 | retval = fe->ops.set_frontend(fe, |
374 | fepriv->state = FESTATE_TUNED; | 381 | &fepriv->parameters); |
382 | if (retval < 0) | ||
383 | fepriv->state = FESTATE_ERROR; | ||
384 | else | ||
385 | fepriv->state = FESTATE_TUNED; | ||
375 | } | 386 | } |
376 | fepriv->delay = 3*HZ; | 387 | fepriv->delay = 3*HZ; |
377 | fepriv->quality = 0; | 388 | fepriv->quality = 0; |
@@ -449,7 +460,11 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
449 | fepriv->delay = fepriv->min_delay; | 460 | fepriv->delay = fepriv->min_delay; |
450 | 461 | ||
451 | /* peform a tune */ | 462 | /* peform a tune */ |
452 | if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) { | 463 | retval = dvb_frontend_swzigzag_autotune(fe, |
464 | fepriv->check_wrapped); | ||
465 | if (retval < 0) { | ||
466 | return; | ||
467 | } else if (retval) { | ||
453 | /* OK, if we've run out of trials at the fast speed. | 468 | /* OK, if we've run out of trials at the fast speed. |
454 | * Drop back to slow for the _next_ attempt */ | 469 | * Drop back to slow for the _next_ attempt */ |
455 | fepriv->state = FESTATE_SEARCHING_SLOW; | 470 | fepriv->state = FESTATE_SEARCHING_SLOW; |
@@ -1499,7 +1514,8 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, | |||
1499 | 1514 | ||
1500 | /* if retune was requested but hasn't occured yet, prevent | 1515 | /* if retune was requested but hasn't occured yet, prevent |
1501 | * that user get signal state from previous tuning */ | 1516 | * that user get signal state from previous tuning */ |
1502 | if(fepriv->state == FESTATE_RETUNE) { | 1517 | if (fepriv->state == FESTATE_RETUNE || |
1518 | fepriv->state == FESTATE_ERROR) { | ||
1503 | err=0; | 1519 | err=0; |
1504 | *status = 0; | 1520 | *status = 0; |
1505 | break; | 1521 | break; |