aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJanne Grunau <j@jannau.net>2009-09-01 18:23:09 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-12 11:20:03 -0400
commit01886255ddf440eb21d3388bfc5343c966904d0e (patch)
tree1357fb305de3fa62564b429843553ad2890a583d /drivers/media
parent4457ef1d6163533073efdebed82a049aad44e3b3 (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.c26
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
357static void dvb_frontend_swzigzag(struct dvb_frontend *fe) 363static 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;