aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/spca561.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/spca561.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/spca561.c')
-rw-r--r--drivers/media/video/gspca/spca561.c115
1 files changed, 61 insertions, 54 deletions
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index f0770ee595d8..b659bd0f788d 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -24,8 +24,8 @@
24 24
25#include "gspca.h" 25#include "gspca.h"
26 26
27#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) 27#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
28static const char version[] = "2.1.5"; 28static const char version[] = "2.1.7";
29 29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); 31MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
@@ -177,27 +177,28 @@ static void write_vector(struct gspca_dev *gspca_dev,
177 } 177 }
178} 178}
179 179
180static void reg_r(struct usb_device *dev, 180/* read 'len' bytes to gspca_dev->usb_buf */
181 __u16 index, __u8 *buffer, __u16 length) 181static void reg_r(struct gspca_dev *gspca_dev,
182 __u16 index, __u16 length)
182{ 183{
183 usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 184 usb_control_msg(gspca_dev->dev,
185 usb_rcvctrlpipe(gspca_dev->dev, 0),
184 0, /* request */ 186 0, /* request */
185 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 187 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
186 0, /* value */ 188 0, /* value */
187 index, buffer, length, 500); 189 index, gspca_dev->usb_buf, length, 500);
188} 190}
189 191
190static void reg_w_buf(struct usb_device *dev, 192static void reg_w_buf(struct gspca_dev *gspca_dev,
191 __u16 index, const __u8 *buffer, __u16 len) 193 __u16 index, const __u8 *buffer, __u16 len)
192{ 194{
193 __u8 tmpbuf[8]; 195 memcpy(gspca_dev->usb_buf, buffer, len);
194 196 usb_control_msg(gspca_dev->dev,
195 memcpy(tmpbuf, buffer, len); 197 usb_sndctrlpipe(gspca_dev->dev, 0),
196 usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
197 0, /* request */ 198 0, /* request */
198 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 199 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
199 0, /* value */ 200 0, /* value */
200 index, tmpbuf, len, 500); 201 index, gspca_dev->usb_buf, len, 500);
201} 202}
202 203
203static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode) 204static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode)
@@ -211,7 +212,6 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
211 int retry = 60; 212 int retry = 60;
212 __u8 DataLow; 213 __u8 DataLow;
213 __u8 DataHight; 214 __u8 DataHight;
214 __u8 Data;
215 215
216 DataLow = valeur; 216 DataLow = valeur;
217 DataHight = valeur >> 8; 217 DataHight = valeur >> 8;
@@ -219,8 +219,8 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
219 reg_w_val(gspca_dev->dev, DataLow, 0x8805); 219 reg_w_val(gspca_dev->dev, DataLow, 0x8805);
220 reg_w_val(gspca_dev->dev, DataHight, 0x8800); 220 reg_w_val(gspca_dev->dev, DataHight, 0x8800);
221 while (retry--) { 221 while (retry--) {
222 reg_r(gspca_dev->dev, 0x8803, &Data, 1); 222 reg_r(gspca_dev, 0x8803, 1);
223 if (!Data) 223 if (!gspca_dev->usb_buf[0])
224 break; 224 break;
225 } 225 }
226} 226}
@@ -230,20 +230,21 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
230 int retry = 60; 230 int retry = 60;
231 __u8 value; 231 __u8 value;
232 __u8 vallsb; 232 __u8 vallsb;
233 __u8 Data;
234 233
235 reg_w_val(gspca_dev->dev, 0x92, 0x8804); 234 reg_w_val(gspca_dev->dev, 0x92, 0x8804);
236 reg_w_val(gspca_dev->dev, reg, 0x8801); 235 reg_w_val(gspca_dev->dev, reg, 0x8801);
237 reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802); 236 reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802);
238 while (retry--) { 237 while (retry--) {
239 reg_r(gspca_dev->dev, 0x8803, &Data, 1); 238 reg_r(gspca_dev, 0x8803, 1);
240 if (!Data) 239 if (!gspca_dev->usb_buf)
241 break; 240 break;
242 } 241 }
243 if (retry == 0) 242 if (retry == 0)
244 return -1; 243 return -1;
245 reg_r(gspca_dev->dev, 0x8800, &value, 1); 244 reg_r(gspca_dev, 0x8800, 1);
246 reg_r(gspca_dev->dev, 0x8805, &vallsb, 1); 245 value = gspca_dev->usb_buf[0];
246 reg_r(gspca_dev, 0x8805, 1);
247 vallsb = gspca_dev->usb_buf[0];
247 return ((int) value << 8) | vallsb; 248 return ((int) value << 8) | vallsb;
248} 249}
249 250
@@ -541,7 +542,7 @@ static void sensor_mapwrite(struct gspca_dev *gspca_dev,
541 while (sensormap[i][0]) { 542 while (sensormap[i][0]) {
542 usbval[0] = sensormap[i][1]; 543 usbval[0] = sensormap[i][1];
543 usbval[1] = sensormap[i][1] >> 8; 544 usbval[1] = sensormap[i][1] >> 8;
544 reg_w_buf(gspca_dev->dev, sensormap[i][0], usbval, 2); 545 reg_w_buf(gspca_dev, sensormap[i][0], usbval, 2);
545 i++; 546 i++;
546 } 547 }
547} 548}
@@ -559,7 +560,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
559 const struct usb_device_id *id) 560 const struct usb_device_id *id)
560{ 561{
561 struct sd *sd = (struct sd *) gspca_dev; 562 struct sd *sd = (struct sd *) gspca_dev;
562 struct usb_device *dev = gspca_dev->dev;
563 struct cam *cam; 563 struct cam *cam;
564 __u16 vendor, product; 564 __u16 vendor, product;
565 __u8 data1, data2; 565 __u8 data1, data2;
@@ -568,11 +568,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
568 * prove that we can communicate with the device. This works, which 568 * prove that we can communicate with the device. This works, which
569 * confirms at we are communicating properly and that the device 569 * confirms at we are communicating properly and that the device
570 * is a 561. */ 570 * is a 561. */
571 reg_r(dev, 0x8104, &data1, 1); 571 reg_r(gspca_dev, 0x8104, 1);
572 reg_r(dev, 0x8105, &data2, 1); 572 data1 = gspca_dev->usb_buf[0];
573 reg_r(gspca_dev, 0x8105, 1);
574 data2 = gspca_dev->usb_buf[0];
573 vendor = (data2 << 8) | data1; 575 vendor = (data2 << 8) | data1;
574 reg_r(dev, 0x8106, &data1, 1); 576 reg_r(gspca_dev, 0x8106, 1);
575 reg_r(dev, 0x8107, &data2, 1); 577 data1 = gspca_dev->usb_buf[0];
578 reg_r(gspca_dev, 0x8107, 1);
579 data2 = gspca_dev->usb_buf[0];
576 product = (data2 << 8) | data1; 580 product = (data2 << 8) | data1;
577 if (vendor != id->idVendor || product != id->idProduct) { 581 if (vendor != id->idVendor || product != id->idProduct) {
578 PDEBUG(D_PROBE, "Bad vendor / product from device"); 582 PDEBUG(D_PROBE, "Bad vendor / product from device");
@@ -656,8 +660,8 @@ static void setcontrast(struct gspca_dev *gspca_dev)
656 Reg8391[0] = expotimes & 0xff; /* exposure */ 660 Reg8391[0] = expotimes & 0xff; /* exposure */
657 Reg8391[1] = 0x18 | (expotimes >> 8); 661 Reg8391[1] = 0x18 | (expotimes >> 8);
658 Reg8391[2] = sd->brightness; /* gain */ 662 Reg8391[2] = sd->brightness; /* gain */
659 reg_w_buf(dev, 0x8391, Reg8391, 8); 663 reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
660 reg_w_buf(dev, 0x8390, Reg8391, 8); 664 reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
661 break; 665 break;
662 } 666 }
663 } 667 }
@@ -714,10 +718,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
714 * is sufficient to push raw frames at ~20fps */ 718 * is sufficient to push raw frames at ~20fps */
715 reg_w_val(dev, 0x8500, mode); 719 reg_w_val(dev, 0x8500, mode);
716 } /* -- qq@kuku.eu.org */ 720 } /* -- qq@kuku.eu.org */
717 reg_w_buf(dev, 0x8307, Reg8307, 2); 721 reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
718 reg_w_val(dev, 0x8700, Clck); /* 0x8f 0x85 0x27 clock */ 722 reg_w_val(gspca_dev->dev, 0x8700, Clck);
719 reg_w_val(dev, 0x8112, 0x1e | 0x20); 723 /* 0x8f 0x85 0x27 clock */
720 reg_w_val(dev, 0x850b, 0x03); 724 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
725 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
721 setcontrast(gspca_dev); 726 setcontrast(gspca_dev);
722 break; 727 break;
723 } 728 }
@@ -752,10 +757,14 @@ static void setautogain(struct gspca_dev *gspca_dev)
752 757
753 switch (sd->chip_revision) { 758 switch (sd->chip_revision) {
754 case Rev072A: 759 case Rev072A:
755 reg_r(gspca_dev->dev, 0x8621, &Gr, 1); 760 reg_r(gspca_dev, 0x8621, 1);
756 reg_r(gspca_dev->dev, 0x8622, &R, 1); 761 Gr = gspca_dev->usb_buf[0];
757 reg_r(gspca_dev->dev, 0x8623, &B, 1); 762 reg_r(gspca_dev, 0x8622, 1);
758 reg_r(gspca_dev->dev, 0x8624, &Gb, 1); 763 R = gspca_dev->usb_buf[0];
764 reg_r(gspca_dev, 0x8623, 1);
765 B = gspca_dev->usb_buf[0];
766 reg_r(gspca_dev, 0x8624, 1);
767 Gb = gspca_dev->usb_buf[0];
759 y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8; 768 y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
760 /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */ 769 /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
761 /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */ 770 /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
@@ -867,20 +876,19 @@ static void setbrightness(struct gspca_dev *gspca_dev)
867static void getbrightness(struct gspca_dev *gspca_dev) 876static void getbrightness(struct gspca_dev *gspca_dev)
868{ 877{
869 struct sd *sd = (struct sd *) gspca_dev; 878 struct sd *sd = (struct sd *) gspca_dev;
870 __u8 value;
871 __u16 tot; 879 __u16 tot;
872 880
873 switch (sd->chip_revision) { 881 switch (sd->chip_revision) {
874 case Rev072A: 882 case Rev072A:
875 tot = 0; 883 tot = 0;
876 reg_r(gspca_dev->dev, 0x8611, &value, 1); 884 reg_r(gspca_dev, 0x8611, 1);
877 tot += value; 885 tot += gspca_dev->usb_buf[0];
878 reg_r(gspca_dev->dev, 0x8612, &value, 1); 886 reg_r(gspca_dev, 0x8612, 1);
879 tot += value; 887 tot += gspca_dev->usb_buf[0];
880 reg_r(gspca_dev->dev, 0x8613, &value, 1); 888 reg_r(gspca_dev, 0x8613, 1);
881 tot += value; 889 tot += gspca_dev->usb_buf[0];
882 reg_r(gspca_dev->dev, 0x8614, &value, 1); 890 reg_r(gspca_dev, 0x8614, 1);
883 tot += value; 891 tot += gspca_dev->usb_buf[0];
884 sd->brightness = tot >> 2; 892 sd->brightness = tot >> 2;
885 break; 893 break;
886 default: 894 default:
@@ -893,20 +901,19 @@ static void getbrightness(struct gspca_dev *gspca_dev)
893static void getcontrast(struct gspca_dev *gspca_dev) 901static void getcontrast(struct gspca_dev *gspca_dev)
894{ 902{
895 struct sd *sd = (struct sd *) gspca_dev; 903 struct sd *sd = (struct sd *) gspca_dev;
896 __u8 value;
897 __u16 tot; 904 __u16 tot;
898 905
899 switch (sd->chip_revision) { 906 switch (sd->chip_revision) {
900 case Rev072A: 907 case Rev072A:
901 tot = 0; 908 tot = 0;
902 reg_r(gspca_dev->dev, 0x8651, &value, 1); 909 reg_r(gspca_dev, 0x8651, 1);
903 tot += value; 910 tot += gspca_dev->usb_buf[0];
904 reg_r(gspca_dev->dev, 0x8652, &value, 1); 911 reg_r(gspca_dev, 0x8652, 1);
905 tot += value; 912 tot += gspca_dev->usb_buf[0];
906 reg_r(gspca_dev->dev, 0x8653, &value, 1); 913 reg_r(gspca_dev, 0x8653, 1);
907 tot += value; 914 tot += gspca_dev->usb_buf[0];
908 reg_r(gspca_dev->dev, 0x8654, &value, 1); 915 reg_r(gspca_dev, 0x8654, 1);
909 tot += value; 916 tot += gspca_dev->usb_buf[0];
910 sd->contrast = tot << 6; 917 sd->contrast = tot << 6;
911 break; 918 break;
912 default: 919 default: