On Sun Aug 30 17:08:47 2026 +0000, Alberto Pimpo wrote:
> The lists of frequencies the simulated tuner locks onto are module
> parameters, and were handed over to the tuner module without being
> checked first.
> 
> A terrestrial or cable frequency outside the range the demodulator
> reports to the DVB core is unreachable, as dvb_frontend_check_parameters()
> rejects such a tuning request before the tuner is ever asked about the
> frequency. A satellite frequency outside the Ku-band covered by the
> simulated LNBf is equally meaningless, since it is downconverted using
> the LNBf local oscillators before reaching the tuner.
> 
> In both cases vidtv used to initialize successfully and then never lock
> on anything, leaving no clue about the cause.
> 
> Check the terrestrial and cable frequencies against the range advertised
> by the demodulator, and the satellite ones against the Ku-band covered by
> the simulated LNBf, failing the probe with an explicit error message
> otherwise.
> 
> Signed-off-by: Alberto Pimpo <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/test-drivers/vidtv/vidtv_bridge.c | 71 ++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)

---

diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c 
b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
index f951b877ada6..4c98dfbd406f 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
@@ -44,6 +44,10 @@
 #define LNB_LOW_FREQ           9750000         /* low IF frequency */
 #define LNB_HIGH_FREQ          10600000        /* transition frequency */
 
+/* The Ku-band range covered by such an LNBf, in kHz */
+#define LNB_KU_BAND_MIN_FREQ   10700000
+#define LNB_KU_BAND_MAX_FREQ   12750000
+
 static unsigned int drop_tslock_prob_on_low_snr;
 module_param(drop_tslock_prob_on_low_snr, uint, 0444);
 MODULE_PARM_DESC(drop_tslock_prob_on_low_snr,
@@ -367,6 +371,36 @@ static int vidtv_bridge_probe_demod(struct vidtv_dvb *dvb, 
u32 n)
        return 0;
 }
 
+/*
+ * Reject frequencies the simulation could never tune into, as the module
+ * would otherwise load just fine and then never lock on anything, leaving
+ * no clue about what went wrong.
+ */
+static int vidtv_bridge_check_freqs(struct vidtv_dvb *dvb,
+                                   const unsigned int *freqs,
+                                   u32 array_sz,
+                                   u32 min_freq,
+                                   u32 max_freq,
+                                   const char *name)
+{
+       u32 i;
+
+       for (i = 0; i < array_sz; i++) {
+               /* a zeroed entry means an unused slot */
+               if (!freqs[i])
+                       continue;
+
+               if (freqs[i] < min_freq || freqs[i] > max_freq) {
+                       dev_err(&dvb->pdev->dev,
+                               "%s[%u]: %u is out of range (%u..%u)\n",
+                               name, i, freqs[i], min_freq, max_freq);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 static int vidtv_bridge_probe_tuner(struct vidtv_dvb *dvb, u32 n)
 {
        struct vidtv_tuner_config cfg = {
@@ -374,10 +408,45 @@ static int vidtv_bridge_probe_tuner(struct vidtv_dvb 
*dvb, u32 n)
                .mock_power_up_delay_msec = mock_power_up_delay_msec,
                .mock_tune_delay_msec     = mock_tune_delay_msec,
        };
+       u32 min_freq = dvb->fe[n]->ops.info.frequency_min_hz;
+       u32 max_freq = dvb->fe[n]->ops.info.frequency_max_hz;
        u32 freq;
+       int ret;
        int i;
 
-       /* TODO: check if the frequencies are at a valid range */
+       /*
+        * Terrestrial and cable frequencies are given in Hz and are used as
+        * is, so they have to fit within the range the demod reports to the
+        * DVB core: the core rejects a tuning request outside of it before
+        * the tuner is ever asked about the frequency.
+        */
+       ret = vidtv_bridge_check_freqs(dvb, vidtv_valid_dvb_t_freqs,
+                                      ARRAY_SIZE(vidtv_valid_dvb_t_freqs),
+                                      min_freq, max_freq,
+                                      "vidtv_valid_dvb_t_freqs");
+       if (ret)
+               return ret;
+
+       ret = vidtv_bridge_check_freqs(dvb, vidtv_valid_dvb_c_freqs,
+                                      ARRAY_SIZE(vidtv_valid_dvb_c_freqs),
+                                      min_freq, max_freq,
+                                      "vidtv_valid_dvb_c_freqs");
+       if (ret)
+               return ret;
+
+       /*
+        * Satellite frequencies are given in kHz at Ku-band and are
+        * downconverted below, so check them against the band the simulated
+        * LNBf covers instead. Doing so also ensures that the frequencies
+        * are above the LNBf local oscillators.
+        */
+       ret = vidtv_bridge_check_freqs(dvb, vidtv_valid_dvb_s_freqs,
+                                      ARRAY_SIZE(vidtv_valid_dvb_s_freqs),
+                                      LNB_KU_BAND_MIN_FREQ,
+                                      LNB_KU_BAND_MAX_FREQ,
+                                      "vidtv_valid_dvb_s_freqs");
+       if (ret)
+               return ret;
 
        memcpy(cfg.vidtv_valid_dvb_t_freqs,
               vidtv_valid_dvb_t_freqs,
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to