diff options
author | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2018-02-19 13:23:39 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2018-02-23 11:44:09 -0500 |
commit | 3dd6b560dc5d59e7cb6dbda6e85dc9af7925fcf8 (patch) | |
tree | 01e74d71a2a2a57736fa33a50582f04905bdcd65 | |
parent | fdbeb96258141d911ca8ba98931b9024038b84e0 (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.c | 88 |
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 | ||
584 | static int tvp5150_write_inittab(struct v4l2_subdev *sd, | 581 | static 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 | ||
594 | static int tvp5150_vdp_init(struct v4l2_subdev *sd, | 591 | static 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, | |||
620 | static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, | 620 | static 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 | */ |
653 | static int tvp5150_set_vbi(struct v4l2_subdev *sd, | 657 | static 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 | ||
699 | static int tvp5150_get_vbi(struct v4l2_subdev *sd, | 702 | static 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; |