diff options
author | Andrew de Quincy <devnull@localhost> | 2004-02-26 23:47:11 +0000 |
---|---|---|
committer | Andrew de Quincy <devnull@localhost> | 2004-02-26 23:47:11 +0000 |
commit | bf4d949f68c34961e21f94a8de994d7642606034 (patch) | |
tree | 649ce1961315fb4f7175a8aaa79478041162b4af | |
parent | f0be68b4fed7a1583fa6242c39a5f77a86e54f6e (diff) | |
download | mediapointer-dvb-s2-bf4d949f68c34961e21f94a8de994d7642606034.tar.gz mediapointer-dvb-s2-bf4d949f68c34961e21f94a8de994d7642606034.tar.bz2 |
Fixed synchronisation problem where an app could issue
FE_SET_FRONTEND, but start reading data before the frontend was
actually set. This caused some really confusing errors.
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index cffbed5a5..aab5d41bc 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -547,19 +547,17 @@ static int dvb_frontend_thread (void *data) continue; } - // if we're in the RETUNE state, move immediately to the ZIGZAG_FAST state - // and, if we're sitting comfortably, begin + // if we're in the RETUNE state, set everything up for a brand new scan if (fe->state & FESTATE_RETUNE) { fe->lnb_drift = 0; fe->inversion = INVERSION_OFF; fe->auto_count = 0; fe->started_auto_count = 0; - fe->state = FESTATE_TUNING_FAST; clean_setup_count = 0; } - // fast zigzag - if (fe->state & FESTATE_SEARCHING_FAST) { + // fast zigzag. + if ((fe->state & FESTATE_SEARCHING_FAST) || (fe->state & FESTATE_RETUNE)) { delay = fe->min_delay; // OK, if we've run out of trials at the fast speed. Drop back to @@ -574,6 +572,12 @@ static int dvb_frontend_thread (void *data) if ((!(fe->info->caps & FE_CAN_CLEAN_SETUP)) && (clean_setup_count == 0)) { fe->state = FESTATE_CLEAN_SETUP; } + + // if we've just retuned, enter the ZIGZAG_FAST state. This ensures + // we cannot return from an FE_SET_FRONTEND before the retune occurs. + if (fe->state & FESTATE_RETUNE) { + fe->state = FESTATE_TUNING_FAST; + } } // slow zigzag @@ -744,14 +748,21 @@ static int dvb_frontend_ioctl (struct inode *inode, struct file *file, default: dvb_frontend_internal_ioctl (&fe->frontend, cmd, parg); }; - - // Force the CAN_INVERSION_AUTO bit on - if (cmd == FE_GET_INFO) { + + up (&fe->sem); + + // Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't do it, it is done for it. + if ((cmd == FE_GET_INFO) && (err == 0)) { struct dvb_frontend_info* tmp = (struct dvb_frontend_info*) parg; tmp->caps |= FE_CAN_INVERSION_AUTO; } - - up (&fe->sem); + + // if the frontend has just been set, wait until the first tune has finished. + // This ensures the app doesn't start reading data too quickly, perhaps from the + // previous lock, which is REALLY CONFUSING TO DEBUG! + if ((cmd == FE_SET_FRONTEND) && (err == 0)) { + err = wait_event_interruptible(fe->wait_queue, fe->state == FESTATE_RETUNE); + } return err; } |