aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@s-opensource.com>2018-02-19 13:23:39 -0500
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2018-02-23 11:44:09 -0500
commit3dd6b560dc5d59e7cb6dbda6e85dc9af7925fcf8 (patch)
tree01e74d71a2a2a57736fa33a50582f04905bdcd65
parentfdbeb96258141d911ca8ba98931b9024038b84e0 (diff)
media: Don't let tvp5150_get_vbi() go out of vbi_ram_default array
As pointed by Dan, possible values for bits[3:0] of te Line Mode Registers can range from 0x0 to 0xf, but the check logic allow values ranging from 0x0 to 0xe. As static arrays are initialized with zero, using a value without an explicit initializer at the array won't cause any harm. Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-rw-r--r--drivers/media/i2c/tvp5150.c88
1 files changed, 45 insertions, 43 deletions
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 3c1851984b90..2476d812f669 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -505,80 +505,77 @@ static struct i2c_vbi_ram_value vbi_ram_default[] =
505 /* FIXME: Current api doesn't handle all VBI types, those not 505 /* FIXME: Current api doesn't handle all VBI types, those not
506 yet supported are placed under #if 0 */ 506 yet supported are placed under #if 0 */
507#if 0 507#if 0
508 {0x010, /* Teletext, SECAM, WST System A */ 508 [0] = {0x010, /* Teletext, SECAM, WST System A */
509 {V4L2_SLICED_TELETEXT_SECAM,6,23,1}, 509 {V4L2_SLICED_TELETEXT_SECAM,6,23,1},
510 { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26, 510 { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26,
511 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 } 511 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 }
512 }, 512 },
513#endif 513#endif
514 {0x030, /* Teletext, PAL, WST System B */ 514 [1] = {0x030, /* Teletext, PAL, WST System B */
515 {V4L2_SLICED_TELETEXT_B,6,22,1}, 515 {V4L2_SLICED_TELETEXT_B,6,22,1},
516 { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b, 516 { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b,
517 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 } 517 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 }
518 }, 518 },
519#if 0 519#if 0
520 {0x050, /* Teletext, PAL, WST System C */ 520 [2] = {0x050, /* Teletext, PAL, WST System C */
521 {V4L2_SLICED_TELETEXT_PAL_C,6,22,1}, 521 {V4L2_SLICED_TELETEXT_PAL_C,6,22,1},
522 { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, 522 { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
523 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } 523 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
524 }, 524 },
525 {0x070, /* Teletext, NTSC, WST System B */ 525 [3] = {0x070, /* Teletext, NTSC, WST System B */
526 {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1}, 526 {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1},
527 { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23, 527 { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23,
528 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } 528 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
529 }, 529 },
530 {0x090, /* Tetetext, NTSC NABTS System C */ 530 [4] = {0x090, /* Tetetext, NTSC NABTS System C */
531 {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1}, 531 {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1},
532 { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, 532 { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
533 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 } 533 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 }
534 }, 534 },
535 {0x0b0, /* Teletext, NTSC-J, NABTS System D */ 535 [5] = {0x0b0, /* Teletext, NTSC-J, NABTS System D */
536 {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1}, 536 {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1},
537 { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23, 537 { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23,
538 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } 538 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
539 }, 539 },
540 {0x0d0, /* Closed Caption, PAL/SECAM */ 540 [6] = {0x0d0, /* Closed Caption, PAL/SECAM */
541 {V4L2_SLICED_CAPTION_625,22,22,1}, 541 {V4L2_SLICED_CAPTION_625,22,22,1},
542 { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, 542 { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
543 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } 543 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
544 }, 544 },
545#endif 545#endif
546 {0x0f0, /* Closed Caption, NTSC */ 546 [7] = {0x0f0, /* Closed Caption, NTSC */
547 {V4L2_SLICED_CAPTION_525,21,21,1}, 547 {V4L2_SLICED_CAPTION_525,21,21,1},
548 { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, 548 { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
549 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } 549 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
550 }, 550 },
551 {0x110, /* Wide Screen Signal, PAL/SECAM */ 551 [8] = {0x110, /* Wide Screen Signal, PAL/SECAM */
552 {V4L2_SLICED_WSS_625,23,23,1}, 552 {V4L2_SLICED_WSS_625,23,23,1},
553 { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42, 553 { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42,
554 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 } 554 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 }
555 }, 555 },
556#if 0 556#if 0
557 {0x130, /* Wide Screen Signal, NTSC C */ 557 [9] = {0x130, /* Wide Screen Signal, NTSC C */
558 {V4L2_SLICED_WSS_525,20,20,1}, 558 {V4L2_SLICED_WSS_525,20,20,1},
559 { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43, 559 { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43,
560 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 } 560 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 }
561 }, 561 },
562 {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */ 562 [10] = {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */
563 {V4l2_SLICED_VITC_625,6,22,0}, 563 {V4l2_SLICED_VITC_625,6,22,0},
564 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, 564 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
565 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } 565 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
566 }, 566 },
567 {0x170, /* Vertical Interval Timecode (VITC), NTSC */ 567 [11] = {0x170, /* Vertical Interval Timecode (VITC), NTSC */
568 {V4l2_SLICED_VITC_525,10,20,0}, 568 {V4l2_SLICED_VITC_525,10,20,0},
569 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, 569 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
570 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } 570 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
571 }, 571 },
572#endif 572#endif
573 {0x190, /* Video Program System (VPS), PAL */ 573 [12] = {0x190, /* Video Program System (VPS), PAL */
574 {V4L2_SLICED_VPS,16,16,0}, 574 {V4L2_SLICED_VPS,16,16,0},
575 { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d, 575 { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d,
576 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 } 576 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 }
577 }, 577 },
578 /* 0x1d0 User programmable */ 578 /* 0x1d0 User programmable */
579
580 /* End of struct */
581 { (u16)-1 }
582}; 579};
583 580
584static int tvp5150_write_inittab(struct v4l2_subdev *sd, 581static int tvp5150_write_inittab(struct v4l2_subdev *sd,
@@ -591,10 +588,10 @@ static int tvp5150_write_inittab(struct v4l2_subdev *sd,
591 return 0; 588 return 0;
592} 589}
593 590
594static int tvp5150_vdp_init(struct v4l2_subdev *sd, 591static int tvp5150_vdp_init(struct v4l2_subdev *sd)
595 const struct i2c_vbi_ram_value *regs)
596{ 592{
597 unsigned int i; 593 unsigned int i;
594 int j;
598 595
599 /* Disable Full Field */ 596 /* Disable Full Field */
600 tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0); 597 tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
@@ -604,14 +601,17 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd,
604 tvp5150_write(sd, i, 0xff); 601 tvp5150_write(sd, i, 0xff);
605 602
606 /* Load Ram Table */ 603 /* Load Ram Table */
607 while (regs->reg != (u16)-1) { 604 for (j = 0; j < ARRAY_SIZE(vbi_ram_default); j++) {
605 const struct i2c_vbi_ram_value *regs = &vbi_ram_default[j];
606
607 if (!regs->type.vbi_type)
608 continue;
609
608 tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8); 610 tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
609 tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg); 611 tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
610 612
611 for (i = 0; i < 16; i++) 613 for (i = 0; i < 16; i++)
612 tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]); 614 tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]);
613
614 regs++;
615 } 615 }
616 return 0; 616 return 0;
617} 617}
@@ -620,19 +620,23 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd,
620static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, 620static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
621 struct v4l2_sliced_vbi_cap *cap) 621 struct v4l2_sliced_vbi_cap *cap)
622{ 622{
623 const struct i2c_vbi_ram_value *regs = vbi_ram_default; 623 int line, i;
624 int line;
625 624
626 dev_dbg_lvl(sd->dev, 1, debug, "g_sliced_vbi_cap\n"); 625 dev_dbg_lvl(sd->dev, 1, debug, "g_sliced_vbi_cap\n");
627 memset(cap, 0, sizeof *cap); 626 memset(cap, 0, sizeof *cap);
628 627
629 while (regs->reg != (u16)-1 ) { 628 for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) {
630 for (line=regs->type.ini_line;line<=regs->type.end_line;line++) { 629 const struct i2c_vbi_ram_value *regs = &vbi_ram_default[i];
630
631 if (!regs->type.vbi_type)
632 continue;
633
634 for (line = regs->type.ini_line;
635 line <= regs->type.end_line;
636 line++) {
631 cap->service_lines[0][line] |= regs->type.vbi_type; 637 cap->service_lines[0][line] |= regs->type.vbi_type;
632 } 638 }
633 cap->service_set |= regs->type.vbi_type; 639 cap->service_set |= regs->type.vbi_type;
634
635 regs++;
636 } 640 }
637 return 0; 641 return 0;
638} 642}
@@ -651,14 +655,13 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
651 * MSB = field2 655 * MSB = field2
652 */ 656 */
653static int tvp5150_set_vbi(struct v4l2_subdev *sd, 657static int tvp5150_set_vbi(struct v4l2_subdev *sd,
654 const struct i2c_vbi_ram_value *regs,
655 unsigned int type,u8 flags, int line, 658 unsigned int type,u8 flags, int line,
656 const int fields) 659 const int fields)
657{ 660{
658 struct tvp5150 *decoder = to_tvp5150(sd); 661 struct tvp5150 *decoder = to_tvp5150(sd);
659 v4l2_std_id std = decoder->norm; 662 v4l2_std_id std = decoder->norm;
660 u8 reg; 663 u8 reg;
661 int pos = 0; 664 int i, pos = 0;
662 665
663 if (std == V4L2_STD_ALL) { 666 if (std == V4L2_STD_ALL) {
664 dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n"); 667 dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n");
@@ -671,19 +674,19 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
671 if (line < 6 || line > 27) 674 if (line < 6 || line > 27)
672 return 0; 675 return 0;
673 676
674 while (regs->reg != (u16)-1) { 677 for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) {
678 const struct i2c_vbi_ram_value *regs = &vbi_ram_default[i];
679
680 if (!regs->type.vbi_type)
681 continue;
682
675 if ((type & regs->type.vbi_type) && 683 if ((type & regs->type.vbi_type) &&
676 (line >= regs->type.ini_line) && 684 (line >= regs->type.ini_line) &&
677 (line <= regs->type.end_line)) 685 (line <= regs->type.end_line))
678 break; 686 break;
679
680 regs++;
681 pos++; 687 pos++;
682 } 688 }
683 689
684 if (regs->reg == (u16)-1)
685 return 0;
686
687 type = pos | (flags & 0xf0); 690 type = pos | (flags & 0xf0);
688 reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI; 691 reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
689 692
@@ -696,8 +699,7 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
696 return type; 699 return type;
697} 700}
698 701
699static int tvp5150_get_vbi(struct v4l2_subdev *sd, 702static int tvp5150_get_vbi(struct v4l2_subdev *sd, int line)
700 const struct i2c_vbi_ram_value *regs, int line)
701{ 703{
702 struct tvp5150 *decoder = to_tvp5150(sd); 704 struct tvp5150 *decoder = to_tvp5150(sd);
703 v4l2_std_id std = decoder->norm; 705 v4l2_std_id std = decoder->norm;
@@ -726,8 +728,8 @@ static int tvp5150_get_vbi(struct v4l2_subdev *sd,
726 return 0; 728 return 0;
727 } 729 }
728 pos = ret & 0x0f; 730 pos = ret & 0x0f;
729 if (pos < 0x0f) 731 if (pos < ARRAY_SIZE(vbi_ram_default))
730 type |= regs[pos].type.vbi_type; 732 type |= vbi_ram_default[pos].type.vbi_type;
731 } 733 }
732 734
733 return type; 735 return type;
@@ -788,7 +790,7 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
788 tvp5150_write_inittab(sd, tvp5150_init_default); 790 tvp5150_write_inittab(sd, tvp5150_init_default);
789 791
790 /* Initializes VDP registers */ 792 /* Initializes VDP registers */
791 tvp5150_vdp_init(sd, vbi_ram_default); 793 tvp5150_vdp_init(sd);
792 794
793 /* Selects decoder input */ 795 /* Selects decoder input */
794 tvp5150_selmux(sd); 796 tvp5150_selmux(sd);
@@ -1121,8 +1123,8 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
1121 for (i = 0; i <= 23; i++) { 1123 for (i = 0; i <= 23; i++) {
1122 svbi->service_lines[1][i] = 0; 1124 svbi->service_lines[1][i] = 0;
1123 svbi->service_lines[0][i] = 1125 svbi->service_lines[0][i] =
1124 tvp5150_set_vbi(sd, vbi_ram_default, 1126 tvp5150_set_vbi(sd, svbi->service_lines[0][i],
1125 svbi->service_lines[0][i], 0xf0, i, 3); 1127 0xf0, i, 3);
1126 } 1128 }
1127 /* Enables FIFO */ 1129 /* Enables FIFO */
1128 tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1); 1130 tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1);
@@ -1148,7 +1150,7 @@ static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
1148 1150
1149 for (i = 0; i <= 23; i++) { 1151 for (i = 0; i <= 23; i++) {
1150 svbi->service_lines[0][i] = 1152 svbi->service_lines[0][i] =
1151 tvp5150_get_vbi(sd, vbi_ram_default, i); 1153 tvp5150_get_vbi(sd, i);
1152 mask |= svbi->service_lines[0][i]; 1154 mask |= svbi->service_lines[0][i];
1153 } 1155 }
1154 svbi->service_set = mask; 1156 svbi->service_set = mask;