diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-10-24 03:19:29 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-29 14:53:29 -0500 |
commit | ba13cca706ab9eacb5bf5ed73c67d9af74ea45b1 (patch) | |
tree | 25ed2deecfc78c6ebb55a1b68c449bf0e7ec1934 /drivers/media/video/gspca/tv8532.c | |
parent | ff374747ce5357eedf034b44ec3111cec28d50d5 (diff) |
V4L/DVB (9546): gspca: Bad scanning of ISOC packets in tv8532.
- The scan function must know about empty packets.
- Packets starting with 0x80 must not be counted.
- Wrong size of the translated frame.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/tv8532.c')
-rw-r--r-- | drivers/media/video/gspca/tv8532.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index 968a5911704f..f6a4733d0262 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c | |||
@@ -30,15 +30,14 @@ MODULE_LICENSE("GPL"); | |||
30 | struct sd { | 30 | struct sd { |
31 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 31 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
32 | 32 | ||
33 | int buflen; /* current length of tmpbuf */ | 33 | __u32 buflen; /* current length of tmpbuf */ |
34 | __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */ | 34 | __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */ |
35 | __u8 tmpbuf2[352 * 288]; /* no protection... */ | 35 | __u8 tmpbuf2[352 * 288]; /* no protection... */ |
36 | 36 | ||
37 | unsigned short brightness; | 37 | __u16 brightness; |
38 | unsigned short contrast; | 38 | __u16 contrast; |
39 | 39 | ||
40 | char packet; | 40 | __u8 packet; |
41 | char synchro; | ||
42 | }; | 41 | }; |
43 | 42 | ||
44 | /* V4L2 controls supported by the driver */ | 43 | /* V4L2 controls supported by the driver */ |
@@ -443,6 +442,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
443 | /************************************************/ | 442 | /************************************************/ |
444 | tv_8532_PollReg(gspca_dev); | 443 | tv_8532_PollReg(gspca_dev); |
445 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ | 444 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ |
445 | |||
446 | gspca_dev->empty_packet = 0; /* check the empty packets */ | ||
447 | |||
446 | return 0; | 448 | return 0; |
447 | } | 449 | } |
448 | 450 | ||
@@ -455,7 +457,7 @@ static void tv8532_preprocess(struct gspca_dev *gspca_dev) | |||
455 | { | 457 | { |
456 | struct sd *sd = (struct sd *) gspca_dev; | 458 | struct sd *sd = (struct sd *) gspca_dev; |
457 | /* we should received a whole frame with header and EOL marker | 459 | /* we should received a whole frame with header and EOL marker |
458 | * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2 | 460 | * in sd->tmpbuf and return a GBRG pattern in sd->tmpbuf2 |
459 | * sequence 2bytes header the Alternate pixels bayer GB 4 bytes | 461 | * sequence 2bytes header the Alternate pixels bayer GB 4 bytes |
460 | * Alternate pixels bayer RG 4 bytes EOL */ | 462 | * Alternate pixels bayer RG 4 bytes EOL */ |
461 | int width = gspca_dev->width; | 463 | int width = gspca_dev->width; |
@@ -509,23 +511,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
509 | 511 | ||
510 | /* header 0x80 0x80 0x80 0x80 0x80 */ | 512 | /* header 0x80 0x80 0x80 0x80 0x80 */ |
511 | /* packet 00 63 127 145 00 */ | 513 | /* packet 00 63 127 145 00 */ |
512 | /* sof 0 1 1 0 0 */ | 514 | /* empty 1 0 0 1 1 */ |
513 | 515 | ||
514 | /* update sequence */ | 516 | /* update sequence */ |
515 | if (sd->packet == 63 || sd->packet == 127) | 517 | if (sd->packet == 63 || sd->packet == 127) |
516 | sd->synchro = 1; | 518 | gspca_dev->empty_packet = 0; |
517 | 519 | ||
518 | /* is there a frame start ? */ | 520 | /* is there a frame start ? */ |
521 | /* (each packet is 2 lines plus 10 bytes) */ | ||
519 | if (sd->packet >= (gspca_dev->height >> 1) - 1) { | 522 | if (sd->packet >= (gspca_dev->height >> 1) - 1) { |
520 | PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro, | 523 | PDEBUG(D_PACK, "empty %d packet %d", |
521 | sd->packet); | 524 | gspca_dev->empty_packet, sd->packet); |
522 | if (!sd->synchro) { /* start of frame */ | 525 | if (gspca_dev->empty_packet) { /* start of frame */ |
523 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | 526 | if (gspca_dev->last_packet_type == FIRST_PACKET) { |
524 | tv8532_preprocess(gspca_dev); | 527 | tv8532_preprocess(gspca_dev); |
525 | frame = gspca_frame_add(gspca_dev, | 528 | frame = gspca_frame_add(gspca_dev, |
526 | LAST_PACKET, | 529 | LAST_PACKET, |
527 | frame, sd->tmpbuf2, | 530 | frame, sd->tmpbuf2, |
528 | gspca_dev->width * | 531 | gspca_dev->height * |
529 | gspca_dev->width); | 532 | gspca_dev->width); |
530 | } | 533 | } |
531 | gspca_frame_add(gspca_dev, FIRST_PACKET, | 534 | gspca_frame_add(gspca_dev, FIRST_PACKET, |
@@ -544,18 +547,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
544 | return; | 547 | return; |
545 | } | 548 | } |
546 | 549 | ||
547 | if (!sd->synchro) { | 550 | if (gspca_dev->empty_packet) { |
548 | /* Drop packet frame corrupt */ | 551 | /* Drop packet frame corrupt */ |
549 | PDEBUG(D_PACK, "DROP SOF %d packet %d", | 552 | PDEBUG(D_PACK, "DROP empty %d packet %d", |
550 | sd->synchro, sd->packet); | 553 | gspca_dev->empty_packet, sd->packet); |
551 | sd->packet = 0; | 554 | sd->packet = 0; |
552 | gspca_dev->last_packet_type = DISCARD_PACKET; | 555 | gspca_dev->last_packet_type = DISCARD_PACKET; |
553 | return; | ||
554 | } | 556 | } |
555 | sd->synchro = 1; | ||
556 | sd->packet++; | ||
557 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
558 | sd->buflen += len; | ||
559 | } | 557 | } |
560 | 558 | ||
561 | static void setcontrast(struct gspca_dev *gspca_dev) | 559 | static void setcontrast(struct gspca_dev *gspca_dev) |