aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sonixb.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-07-14 08:38:29 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:26:14 -0400
commit739570bb218bb4607df1f197282561e97a98e54a (patch)
tree25555dfe5ac873bc96866c486d6f6c1dcabf24f4 /drivers/media/video/gspca/sonixb.c
parent5b77ae7776183d733ec86727bcc34c52a336afd6 (diff)
V4L/DVB (8352): gspca: Buffers for USB exchanges cannot be in the stack.
gspca: Protect dq_callback() against simultaneous USB exchanges. Temporary buffer for USB exchanges added in the device struct. (all) Use a temporary buffer for all USB exchanges. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/gspca/sonixb.c')
-rw-r--r--drivers/media/video/gspca/sonixb.c155
1 files changed, 85 insertions, 70 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 5d2313198807..ce8b28f504d3 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -384,64 +384,82 @@ static const __u8 tas5130_sensor_init[][8] = {
384 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, 384 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
385}; 385};
386 386
387static void reg_r(struct usb_device *dev, 387/* get one byte in gspca_dev->usb_buf */
388 __u16 value, __u8 *buffer) 388static void reg_r(struct gspca_dev *gspca_dev,
389 __u16 value)
389{ 390{
390 usb_control_msg(dev, 391 usb_control_msg(gspca_dev->dev,
391 usb_rcvctrlpipe(dev, 0), 392 usb_rcvctrlpipe(gspca_dev->dev, 0),
392 0, /* request */ 393 0, /* request */
393 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 394 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
394 value, 395 value,
395 0, /* index */ 396 0, /* index */
396 buffer, 1, 397 gspca_dev->usb_buf, 1,
397 500); 398 500);
398} 399}
399 400
400static void reg_w(struct usb_device *dev, 401static void reg_w(struct gspca_dev *gspca_dev,
401 __u16 value, 402 __u16 value,
402 const __u8 *buffer, 403 const __u8 *buffer,
403 int len) 404 int len)
404{ 405{
405 __u8 tmpbuf[48];
406
407#ifdef CONFIG_VIDEO_ADV_DEBUG 406#ifdef CONFIG_VIDEO_ADV_DEBUG
408 if (len > sizeof tmpbuf) { 407 if (len > sizeof gspca_dev->usb_buf) {
409 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); 408 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
410 return; 409 return;
411 } 410 }
412#endif 411#endif
412 memcpy(gspca_dev->usb_buf, buffer, len);
413 usb_control_msg(gspca_dev->dev,
414 usb_sndctrlpipe(gspca_dev->dev, 0),
415 0x08, /* request */
416 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
417 value,
418 0, /* index */
419 gspca_dev->usb_buf, len,
420 500);
421}
422
423static void reg_w_big(struct gspca_dev *gspca_dev,
424 __u16 value,
425 const __u8 *buffer,
426 int len)
427{
428 __u8 *tmpbuf;
429
430 tmpbuf = kmalloc(len, GFP_KERNEL);
413 memcpy(tmpbuf, buffer, len); 431 memcpy(tmpbuf, buffer, len);
414 usb_control_msg(dev, 432 usb_control_msg(gspca_dev->dev,
415 usb_sndctrlpipe(dev, 0), 433 usb_sndctrlpipe(gspca_dev->dev, 0),
416 0x08, /* request */ 434 0x08, /* request */
417 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 435 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
418 value, 436 value,
419 0, /* index */ 437 0, /* index */
420 tmpbuf, len, 438 tmpbuf, len,
421 500); 439 500);
440 kfree(tmpbuf);
422} 441}
423 442
424static int i2c_w(struct usb_device *dev, const __u8 *buffer) 443static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
425{ 444{
426 int retry = 60; 445 int retry = 60;
427 __u8 ByteReceive;
428 446
429 /* is i2c ready */ 447 /* is i2c ready */
430 reg_w(dev, 0x08, buffer, 8); 448 reg_w(gspca_dev, 0x08, buffer, 8);
431 while (retry--) { 449 while (retry--) {
432 msleep(10); 450 msleep(10);
433 reg_r(dev, 0x08, &ByteReceive); 451 reg_r(gspca_dev, 0x08);
434 if (ByteReceive == 4) 452 if (gspca_dev->usb_buf[0] == 4)
435 return 0; 453 return 0;
436 } 454 }
437 return -1; 455 return -1;
438} 456}
439 457
440static void i2c_w_vector(struct usb_device *dev, 458static void i2c_w_vector(struct gspca_dev *gspca_dev,
441 const __u8 buffer[][8], int len) 459 const __u8 buffer[][8], int len)
442{ 460{
443 for (;;) { 461 for (;;) {
444 reg_w(dev, 0x08, *buffer, 8); 462 reg_w(gspca_dev, 0x08, *buffer, 8);
445 len -= 8; 463 len -= 8;
446 if (len <= 0) 464 if (len <= 0)
447 break; 465 break;
@@ -460,7 +478,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
460 {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15}; 478 {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15};
461 479
462 i2cOV6650[3] = sd->brightness; 480 i2cOV6650[3] = sd->brightness;
463 if (i2c_w(gspca_dev->dev, i2cOV6650) < 0) 481 if (i2c_w(gspca_dev, i2cOV6650) < 0)
464 goto err; 482 goto err;
465 break; 483 break;
466 } 484 }
@@ -470,7 +488,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
470 488
471 /* change reg 0x06 */ 489 /* change reg 0x06 */
472 i2cOV[3] = sd->brightness; 490 i2cOV[3] = sd->brightness;
473 if (i2c_w(gspca_dev->dev, i2cOV) < 0) 491 if (i2c_w(gspca_dev, i2cOV) < 0)
474 goto err; 492 goto err;
475 break; 493 break;
476 } 494 }
@@ -480,11 +498,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
480 498
481 i2c1[3] = sd->brightness >> 3; 499 i2c1[3] = sd->brightness >> 3;
482 i2c1[2] = 0x0e; 500 i2c1[2] = 0x0e;
483 if (i2c_w(gspca_dev->dev, i2c1) < 0) 501 if (i2c_w(gspca_dev, i2c1) < 0)
484 goto err; 502 goto err;
485 i2c1[3] = 0x01; 503 i2c1[3] = 0x01;
486 i2c1[2] = 0x13; 504 i2c1[2] = 0x13;
487 if (i2c_w(gspca_dev->dev, i2c1) < 0) 505 if (i2c_w(gspca_dev, i2c1) < 0)
488 goto err; 506 goto err;
489 break; 507 break;
490 } 508 }
@@ -500,18 +518,18 @@ static void setbrightness(struct gspca_dev *gspca_dev)
500 518
501 /* change reg 0x10 */ 519 /* change reg 0x10 */
502 i2cpexpo[4] = 0xff - sd->brightness; 520 i2cpexpo[4] = 0xff - sd->brightness;
503/* if(i2c_w(gspca_dev->dev,i2cpexpo1) < 0) 521/* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
504 goto err; */ 522 goto err; */
505/* if(i2c_w(gspca_dev->dev,i2cpdoit) < 0) 523/* if(i2c_w(gspca_dev,i2cpdoit) < 0)
506 goto err; */ 524 goto err; */
507 if (i2c_w(gspca_dev->dev, i2cpexpo) < 0) 525 if (i2c_w(gspca_dev, i2cpexpo) < 0)
508 goto err; 526 goto err;
509 if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) 527 if (i2c_w(gspca_dev, i2cpdoit) < 0)
510 goto err; 528 goto err;
511 i2cp202[3] = sd->brightness >> 3; 529 i2cp202[3] = sd->brightness >> 3;
512 if (i2c_w(gspca_dev->dev, i2cp202) < 0) 530 if (i2c_w(gspca_dev, i2cp202) < 0)
513 goto err; 531 goto err;
514 if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) 532 if (i2c_w(gspca_dev, i2cpdoit) < 0)
515 goto err; 533 goto err;
516 break; 534 break;
517 } 535 }
@@ -522,7 +540,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
522 value = 0xff - sd->brightness; 540 value = 0xff - sd->brightness;
523 i2c[4] = value; 541 i2c[4] = value;
524 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]); 542 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
525 if (i2c_w(gspca_dev->dev, i2c) < 0) 543 if (i2c_w(gspca_dev, i2c) < 0)
526 goto err; 544 goto err;
527 break; 545 break;
528 } 546 }
@@ -551,14 +569,14 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
551 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; 569 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
552 570
553 i2c[4] = 255 - gain; 571 i2c[4] = 255 - gain;
554 if (i2c_w(gspca_dev->dev, i2c) < 0) 572 if (i2c_w(gspca_dev, i2c) < 0)
555 goto err; 573 goto err;
556 break; 574 break;
557 } 575 }
558 case SENSOR_OV6650: { 576 case SENSOR_OV6650: {
559 __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 577 __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
560 i2c[3] = gain; 578 i2c[3] = gain;
561 if (i2c_w(gspca_dev->dev, i2c) < 0) 579 if (i2c_w(gspca_dev, i2c) < 0)
562 goto err; 580 goto err;
563 break; 581 break;
564 } 582 }
@@ -578,10 +596,10 @@ static void setgain(struct gspca_dev *gspca_dev)
578 596
579 /* red and blue gain */ 597 /* red and blue gain */
580 rgb_value = gain << 4 | gain; 598 rgb_value = gain << 4 | gain;
581 reg_w(gspca_dev->dev, 0x10, &rgb_value, 1); 599 reg_w(gspca_dev, 0x10, &rgb_value, 1);
582 /* green gain */ 600 /* green gain */
583 rgb_value = gain; 601 rgb_value = gain;
584 reg_w(gspca_dev->dev, 0x11, &rgb_value, 1); 602 reg_w(gspca_dev, 0x11, &rgb_value, 1);
585 603
586 if (sd->sensor_has_gain) 604 if (sd->sensor_has_gain)
587 setsensorgain(gspca_dev); 605 setsensorgain(gspca_dev);
@@ -604,7 +622,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
604 if (reg > 15) 622 if (reg > 15)
605 reg = 15; 623 reg = 15;
606 reg = (reg << 4) | 0x0b; 624 reg = (reg << 4) | 0x0b;
607 reg_w(gspca_dev->dev, 0x19, &reg, 1); 625 reg_w(gspca_dev, 0x19, &reg, 1);
608 break; 626 break;
609 } 627 }
610 case SENSOR_OV6650: { 628 case SENSOR_OV6650: {
@@ -613,7 +631,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
613 if (i2c[3] > 15) 631 if (i2c[3] > 15)
614 i2c[3] = 15; 632 i2c[3] = 15;
615 i2c[3] |= 0xc0; 633 i2c[3] |= 0xc0;
616 if (i2c_w(gspca_dev->dev, i2c) < 0) 634 if (i2c_w(gspca_dev, i2c) < 0)
617 PDEBUG(D_ERR, "i2c error exposure"); 635 PDEBUG(D_ERR, "i2c error exposure");
618 break; 636 break;
619 } 637 }
@@ -721,22 +739,20 @@ static int sd_config(struct gspca_dev *gspca_dev,
721 sd->exposure = EXPOSURE_DEF; 739 sd->exposure = EXPOSURE_DEF;
722 sd->autogain = AUTOGAIN_DEF; 740 sd->autogain = AUTOGAIN_DEF;
723 if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ 741 if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */
724 reg_w(gspca_dev->dev, 0x01, probe_ov7630, sizeof probe_ov7630); 742 reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
725 return 0; 743 return 0;
726} 744}
727 745
728/* this function is called at open time */ 746/* this function is called at open time */
729static int sd_open(struct gspca_dev *gspca_dev) 747static int sd_open(struct gspca_dev *gspca_dev)
730{ 748{
731 __u8 ByteReceive; 749 reg_r(gspca_dev, 0x00);
732 750 if (gspca_dev->usb_buf[0] != 0x10)
733 reg_r(gspca_dev->dev, 0x00, &ByteReceive);
734 if (ByteReceive != 0x10)
735 return -ENODEV; 751 return -ENODEV;
736 return 0; 752 return 0;
737} 753}
738 754
739static void pas106_i2cinit(struct usb_device *dev) 755static void pas106_i2cinit(struct gspca_dev *gspca_dev)
740{ 756{
741 int i; 757 int i;
742 const __u8 *data; 758 const __u8 *data;
@@ -747,7 +763,7 @@ static void pas106_i2cinit(struct usb_device *dev)
747 while (--i >= 0) { 763 while (--i >= 0) {
748 memcpy(&i2c1[2], data, 2); 764 memcpy(&i2c1[2], data, 2);
749 /* copy 2 bytes from the template */ 765 /* copy 2 bytes from the template */
750 if (i2c_w(dev, i2c1) < 0) 766 if (i2c_w(gspca_dev, i2c1) < 0)
751 PDEBUG(D_ERR, "i2c error pas106"); 767 PDEBUG(D_ERR, "i2c error pas106");
752 data += 2; 768 data += 2;
753 } 769 }
@@ -757,7 +773,6 @@ static void pas106_i2cinit(struct usb_device *dev)
757static void sd_start(struct gspca_dev *gspca_dev) 773static void sd_start(struct gspca_dev *gspca_dev)
758{ 774{
759 struct sd *sd = (struct sd *) gspca_dev; 775 struct sd *sd = (struct sd *) gspca_dev;
760 struct usb_device *dev = gspca_dev->dev;
761 int mode, l; 776 int mode, l;
762 const __u8 *sn9c10x; 777 const __u8 *sn9c10x;
763 __u8 reg01, reg17; 778 __u8 reg01, reg17;
@@ -835,75 +850,75 @@ static void sd_start(struct gspca_dev *gspca_dev)
835 } 850 }
836 851
837 /* reg 0x01 bit 2 video transfert on */ 852 /* reg 0x01 bit 2 video transfert on */
838 reg_w(dev, 0x01, &reg01, 1); 853 reg_w(gspca_dev, 0x01, &reg01, 1);
839 /* reg 0x17 SensorClk enable inv Clk 0x60 */ 854 /* reg 0x17 SensorClk enable inv Clk 0x60 */
840 reg_w(dev, 0x17, &reg17, 1); 855 reg_w(gspca_dev, 0x17, &reg17, 1);
841/*fixme: for ov7630 102 856/*fixme: for ov7630 102
842 reg_w(dev, 0x01, {0x06, sn9c10x[1]}, 2); */ 857 reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
843 /* Set the registers from the template */ 858 /* Set the registers from the template */
844 reg_w(dev, 0x01, sn9c10x, l); 859 reg_w_big(gspca_dev, 0x01, sn9c10x, l);
845 switch (sd->sensor) { 860 switch (sd->sensor) {
846 case SENSOR_HV7131R: 861 case SENSOR_HV7131R:
847 i2c_w_vector(dev, hv7131_sensor_init, 862 i2c_w_vector(gspca_dev, hv7131_sensor_init,
848 sizeof hv7131_sensor_init); 863 sizeof hv7131_sensor_init);
849 break; 864 break;
850 case SENSOR_OV6650: 865 case SENSOR_OV6650:
851 i2c_w_vector(dev, ov6650_sensor_init, 866 i2c_w_vector(gspca_dev, ov6650_sensor_init,
852 sizeof ov6650_sensor_init); 867 sizeof ov6650_sensor_init);
853 break; 868 break;
854 case SENSOR_OV7630: 869 case SENSOR_OV7630:
855 i2c_w_vector(dev, ov7630_sensor_init_com, 870 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
856 sizeof ov7630_sensor_init_com); 871 sizeof ov7630_sensor_init_com);
857 msleep(200); 872 msleep(200);
858 i2c_w_vector(dev, ov7630_sensor_init, 873 i2c_w_vector(gspca_dev, ov7630_sensor_init,
859 sizeof ov7630_sensor_init); 874 sizeof ov7630_sensor_init);
860 break; 875 break;
861 case SENSOR_OV7630_3: 876 case SENSOR_OV7630_3:
862 i2c_w_vector(dev, ov7630_sensor_init_com, 877 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
863 sizeof ov7630_sensor_init_com); 878 sizeof ov7630_sensor_init_com);
864 msleep(200); 879 msleep(200);
865 i2c_w_vector(dev, ov7630_sensor_init_3, 880 i2c_w_vector(gspca_dev, ov7630_sensor_init_3,
866 sizeof ov7630_sensor_init_3); 881 sizeof ov7630_sensor_init_3);
867 break; 882 break;
868 case SENSOR_PAS106: 883 case SENSOR_PAS106:
869 pas106_i2cinit(dev); 884 pas106_i2cinit(gspca_dev);
870 break; 885 break;
871 case SENSOR_PAS202: 886 case SENSOR_PAS202:
872 i2c_w_vector(dev, pas202_sensor_init, 887 i2c_w_vector(gspca_dev, pas202_sensor_init,
873 sizeof pas202_sensor_init); 888 sizeof pas202_sensor_init);
874 break; 889 break;
875 case SENSOR_TAS5110: 890 case SENSOR_TAS5110:
876 i2c_w_vector(dev, tas5110_sensor_init, 891 i2c_w_vector(gspca_dev, tas5110_sensor_init,
877 sizeof tas5110_sensor_init); 892 sizeof tas5110_sensor_init);
878 break; 893 break;
879 default: 894 default:
880/* case SENSOR_TAS5130CXX: */ 895/* case SENSOR_TAS5130CXX: */
881 i2c_w_vector(dev, tas5130_sensor_init, 896 i2c_w_vector(gspca_dev, tas5130_sensor_init,
882 sizeof tas5130_sensor_init); 897 sizeof tas5130_sensor_init);
883 break; 898 break;
884 } 899 }
885 /* H_size V_size 0x28, 0x1e maybe 640x480 */ 900 /* H_size V_size 0x28, 0x1e maybe 640x480 */
886 reg_w(dev, 0x15, reg15, 2); 901 reg_w(gspca_dev, 0x15, reg15, 2);
887 /* compression register */ 902 /* compression register */
888 reg_w(dev, 0x18, &reg17_19[1], 1); 903 reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
889 if (sd->sensor != SENSOR_OV7630_3) { 904 if (sd->sensor != SENSOR_OV7630_3) {
890 /* H_start */ 905 /* H_start */
891 reg_w(dev, 0x12, &sn9c10x[0x12 - 1], 1); 906 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
892 /* V_START */ 907 /* V_START */
893 reg_w(dev, 0x13, &sn9c10x[0x13 - 1], 1); 908 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
894 } 909 }
895 /* reset 0x17 SensorClk enable inv Clk 0x60 */ 910 /* reset 0x17 SensorClk enable inv Clk 0x60 */
896 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ 911 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
897 reg_w(dev, 0x17, &reg17_19[0], 1); 912 reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
898 /*MCKSIZE ->3 */ /*fixme: not ov7630*/ 913 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
899 if (sd->sensor != SENSOR_OV7630_3) 914 if (sd->sensor != SENSOR_OV7630_3)
900 reg_w(dev, 0x19, &reg17_19[2], 1); 915 reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
901 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ 916 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
902 reg_w(dev, 0x1c, &sn9c10x[0x1c - 1], 4); 917 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
903 /* Enable video transfert */ 918 /* Enable video transfert */
904 reg_w(dev, 0x01, &sn9c10x[0], 1); 919 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
905 /* Compression */ 920 /* Compression */
906 reg_w(dev, 0x18, &reg17_19[1], 2); 921 reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
907 msleep(20); 922 msleep(20);
908 923
909 setgain(gspca_dev); 924 setgain(gspca_dev);
@@ -919,7 +934,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
919 __u8 ByteSend; 934 __u8 ByteSend;
920 935
921 ByteSend = 0x09; /* 0X00 */ 936 ByteSend = 0x09; /* 0X00 */
922 reg_w(gspca_dev->dev, 0x01, &ByteSend, 1); 937 reg_w(gspca_dev, 0x01, &ByteSend, 1);
923} 938}
924 939
925static void sd_stop0(struct gspca_dev *gspca_dev) 940static void sd_stop0(struct gspca_dev *gspca_dev)