Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (5986): dvb_frontend: Fixed GET_INFO ioctl and check of frequency limits

The calculation of frequency limits ignored tuner-specific frequency limits.
Range checks and GET_INFO ioctl updated accordingly.

Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

authored by

Oliver Endriss and committed by
Mauro Carvalho Chehab
c471b331 a18255be

+25 -6
+25 -6
drivers/media/dvb/dvb-core/dvb_frontend.c
··· 697 697 return 0; 698 698 } 699 699 700 + static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe, 701 + u32 *freq_min, u32 *freq_max) 702 + { 703 + *freq_min = max(fe->ops.info.frequency_min, fe->ops.tuner_ops.info.frequency_min); 704 + 705 + if (fe->ops.info.frequency_max == 0) 706 + *freq_max = fe->ops.tuner_ops.info.frequency_max; 707 + else if (fe->ops.tuner_ops.info.frequency_max == 0) 708 + *freq_max = fe->ops.info.frequency_max; 709 + else 710 + *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max); 711 + 712 + if (*freq_min == 0 || *freq_max == 0) 713 + printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n", 714 + fe->dvb->num); 715 + } 716 + 700 717 static int dvb_frontend_check_parameters(struct dvb_frontend *fe, 701 718 struct dvb_frontend_parameters *parms) 702 719 { 720 + u32 freq_min; 721 + u32 freq_max; 722 + 703 723 /* range check: frequency */ 704 - if ((fe->ops.info.frequency_min && 705 - parms->frequency < fe->ops.info.frequency_min) || 706 - (fe->ops.info.frequency_max && 707 - parms->frequency > fe->ops.info.frequency_max)) { 724 + dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max); 725 + if ((freq_min && parms->frequency < freq_min) || 726 + (freq_max && parms->frequency > freq_max)) { 708 727 printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n", 709 - fe->dvb->num, parms->frequency, 710 - fe->ops.info.frequency_min, fe->ops.info.frequency_max); 728 + fe->dvb->num, parms->frequency, freq_min, freq_max); 711 729 return -EINVAL; 712 730 } 713 731 ··· 781 763 case FE_GET_INFO: { 782 764 struct dvb_frontend_info* info = parg; 783 765 memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info)); 766 + dvb_frontend_get_frequeny_limits(fe, &info->frequency_min, &info->frequency_max); 784 767 785 768 /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't 786 769 * do it, it is done for it. */