Commit f303810c authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

media: mb86a16: avoid division by zero

As warned by smatch:
	drivers/media/dvb-frontends/mb86a16.c:1690 mb86a16_read_ber() error: uninitialized symbol 'timer'.
	drivers/media/dvb-frontends/mb86a16.c:1706 mb86a16_read_ber() error: uninitialized symbol 'timer'.

There is a potential risk of doing a division by zero if
timer is not handled well. Enforce it by setting a bit mask
for the values used to select the timer.

It should be noticed that I don't have mb86a16 datasheet. So,
the bitmask was guessed based on the existing checks for
the field. At worse case scenario, it will just show a
badly calculated bit error rate, but it won't crash.

While here, optimize the logic to prevent uneeded tests.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 15e3145a
...@@ -1677,15 +1677,15 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber) ...@@ -1677,15 +1677,15 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
* the deinterleaver output. * the deinterleaver output.
* monitored BER is expressed as a 20 bit output in total * monitored BER is expressed as a 20 bit output in total
*/ */
ber_rst = ber_mon >> 3; ber_rst = (ber_mon >> 3) & 0x03;
*ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb; *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
if (ber_rst == 0) if (ber_rst == 0)
timer = 12500000; timer = 12500000;
if (ber_rst == 1) else if (ber_rst == 1)
timer = 25000000; timer = 25000000;
if (ber_rst == 2) else if (ber_rst == 2)
timer = 50000000; timer = 50000000;
if (ber_rst == 3) else /* ber_rst == 3 */
timer = 100000000; timer = 100000000;
*ber /= timer; *ber /= timer;
...@@ -1697,11 +1697,11 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber) ...@@ -1697,11 +1697,11 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
* QPSK demodulator output. * QPSK demodulator output.
* monitored BER is expressed as a 24 bit output in total * monitored BER is expressed as a 24 bit output in total
*/ */
ber_tim = ber_mon >> 1; ber_tim = (ber_mon >> 1) & 0x01;
*ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb; *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
if (ber_tim == 0) if (ber_tim == 0)
timer = 16; timer = 16;
if (ber_tim == 1) else /* ber_tim == 1 */
timer = 24; timer = 24;
*ber /= 2 ^ timer; *ber /= 2 ^ timer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment