diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-07-14 08:38:29 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:26:14 -0400 |
commit | 739570bb218bb4607df1f197282561e97a98e54a (patch) | |
tree | 25555dfe5ac873bc96866c486d6f6c1dcabf24f4 /drivers/media/video/gspca/vc032x.c | |
parent | 5b77ae7776183d733ec86727bcc34c52a336afd6 (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/vc032x.c')
-rw-r--r-- | drivers/media/video/gspca/vc032x.c | 81 |
1 files changed, 40 insertions, 41 deletions
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 668e024aaa8f..dd7c1389f38d 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -1227,17 +1227,18 @@ static const struct sensor_info sensor_info_data[] = { | |||
1227 | {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, | 1227 | {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, |
1228 | }; | 1228 | }; |
1229 | 1229 | ||
1230 | static void reg_r(struct usb_device *dev, | 1230 | /* read 'len' bytes in gspca_dev->usb_buf */ |
1231 | __u16 req, | 1231 | static void reg_r(struct gspca_dev *gspca_dev, |
1232 | __u16 index, | 1232 | __u16 req, |
1233 | __u8 *buffer, __u16 length) | 1233 | __u16 index, |
1234 | __u16 len) | ||
1234 | { | 1235 | { |
1235 | usb_control_msg(dev, | 1236 | usb_control_msg(gspca_dev->dev, |
1236 | usb_rcvctrlpipe(dev, 0), | 1237 | usb_rcvctrlpipe(gspca_dev->dev, 0), |
1237 | req, | 1238 | req, |
1238 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 1239 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
1239 | 1, /* value */ | 1240 | 1, /* value */ |
1240 | index, buffer, length, | 1241 | index, gspca_dev->usb_buf, len, |
1241 | 500); | 1242 | 500); |
1242 | } | 1243 | } |
1243 | 1244 | ||
@@ -1254,55 +1255,55 @@ static void reg_w(struct usb_device *dev, | |||
1254 | 500); | 1255 | 500); |
1255 | } | 1256 | } |
1256 | 1257 | ||
1257 | static void vc032x_read_sensor_register(struct usb_device *dev, | 1258 | static void read_sensor_register(struct gspca_dev *gspca_dev, |
1258 | __u16 address, __u16 *value) | 1259 | __u16 address, __u16 *value) |
1259 | { | 1260 | { |
1261 | struct usb_device *dev = gspca_dev->dev; | ||
1260 | __u8 ldata, mdata, hdata; | 1262 | __u8 ldata, mdata, hdata; |
1261 | __u8 tmpvalue = 0; | ||
1262 | int retry = 50; | 1263 | int retry = 50; |
1263 | ldata = 0; | 1264 | |
1264 | mdata = 0; | ||
1265 | hdata = 0; | ||
1266 | *value = 0; | 1265 | *value = 0; |
1267 | 1266 | ||
1268 | reg_r(dev, 0xa1, 0xb33f, &tmpvalue, 1); | 1267 | reg_r(gspca_dev, 0xa1, 0xb33f, 1); |
1269 | /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */ | 1268 | /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */ |
1270 | if (!(tmpvalue & 0x02)) { | 1269 | if (!(gspca_dev->usb_buf[0] & 0x02)) { |
1271 | PDEBUG(D_ERR, "I2c Bus Busy Wait %d", tmpvalue & 0x02); | 1270 | PDEBUG(D_ERR, "I2c Bus Busy Wait %d", |
1271 | gspca_dev->usb_buf[0] & 0x02); | ||
1272 | return; | 1272 | return; |
1273 | } | 1273 | } |
1274 | reg_w(dev, 0xa0, address, 0xb33a); | 1274 | reg_w(dev, 0xa0, address, 0xb33a); |
1275 | reg_w(dev, 0xa0, 0x02, 0xb339); | 1275 | reg_w(dev, 0xa0, 0x02, 0xb339); |
1276 | 1276 | ||
1277 | tmpvalue = 0; | 1277 | reg_r(gspca_dev, 0xa1, 0xb33b, 1); |
1278 | reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1); | 1278 | while (retry-- && gspca_dev->usb_buf[0]) { |
1279 | while (retry-- && tmpvalue) { | 1279 | reg_r(gspca_dev, 0xa1, 0xb33b, 1); |
1280 | reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1); | ||
1281 | /* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */ | 1280 | /* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */ |
1282 | msleep(1); | 1281 | msleep(1); |
1283 | } | 1282 | } |
1284 | reg_r(dev, 0xa1, 0xb33e, &hdata, 1); | 1283 | reg_r(gspca_dev, 0xa1, 0xb33e, 1); |
1285 | reg_r(dev, 0xa1, 0xb33d, &mdata, 1); | 1284 | hdata = gspca_dev->usb_buf[0]; |
1286 | reg_r(dev, 0xa1, 0xb33c, &ldata, 1); | 1285 | reg_r(gspca_dev, 0xa1, 0xb33d, 1); |
1286 | mdata = gspca_dev->usb_buf[0]; | ||
1287 | reg_r(gspca_dev, 0xa1, 0xb33c, 1); | ||
1288 | ldata = gspca_dev->usb_buf[0]; | ||
1287 | PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)", | 1289 | PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)", |
1288 | hdata, mdata, ldata); | 1290 | hdata, mdata, ldata); |
1289 | tmpvalue = 0; | 1291 | reg_r(gspca_dev, 0xa1, 0xb334, 1); |
1290 | reg_r(dev, 0xa1, 0xb334, &tmpvalue, 1); | 1292 | if (gspca_dev->usb_buf[0] == 0x02) |
1291 | if (tmpvalue == 0x02) | ||
1292 | *value = (ldata << 8) + mdata; | 1293 | *value = (ldata << 8) + mdata; |
1293 | else | 1294 | else |
1294 | *value = ldata; | 1295 | *value = ldata; |
1295 | } | 1296 | } |
1297 | |||
1296 | static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) | 1298 | static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) |
1297 | { | 1299 | { |
1298 | struct usb_device *dev = gspca_dev->dev; | 1300 | struct usb_device *dev = gspca_dev->dev; |
1299 | int i; | 1301 | int i; |
1300 | __u8 data; | ||
1301 | __u16 value; | 1302 | __u16 value; |
1302 | const struct sensor_info *ptsensor_info; | 1303 | const struct sensor_info *ptsensor_info; |
1303 | 1304 | ||
1304 | reg_r(dev, 0xa1, 0xbfcf, &data, 1); | 1305 | reg_r(gspca_dev, 0xa1, 0xbfcf, 1); |
1305 | PDEBUG(D_PROBE, "check sensor header %d", data); | 1306 | PDEBUG(D_PROBE, "check sensor header %d", gspca_dev->usb_buf[0]); |
1306 | for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { | 1307 | for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { |
1307 | ptsensor_info = &sensor_info_data[i]; | 1308 | ptsensor_info = &sensor_info_data[i]; |
1308 | reg_w(dev, 0xa0, 0x02, 0xb334); | 1309 | reg_w(dev, 0xa0, 0x02, 0xb334); |
@@ -1315,7 +1316,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) | |||
1315 | "check sensor VC032X -> %d Add -> ox%02X!", | 1316 | "check sensor VC032X -> %d Add -> ox%02X!", |
1316 | i, ptsensor_info->I2cAdd); */ | 1317 | i, ptsensor_info->I2cAdd); */ |
1317 | reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); | 1318 | reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); |
1318 | vc032x_read_sensor_register(dev, ptsensor_info->IdAdd, &value); | 1319 | read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value); |
1319 | if (value == ptsensor_info->VpId) { | 1320 | if (value == ptsensor_info->VpId) { |
1320 | /* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!", | 1321 | /* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!", |
1321 | ptsensor_info->VpId); */ | 1322 | ptsensor_info->VpId); */ |
@@ -1325,14 +1326,14 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) | |||
1325 | return -1; | 1326 | return -1; |
1326 | } | 1327 | } |
1327 | 1328 | ||
1328 | static __u8 i2c_write(struct usb_device *dev, | 1329 | static __u8 i2c_write(struct gspca_dev *gspca_dev, |
1329 | __u8 reg, const __u8 *val, __u8 size) | 1330 | __u8 reg, const __u8 *val, __u8 size) |
1330 | { | 1331 | { |
1331 | __u8 retbyte; | 1332 | struct usb_device *dev = gspca_dev->dev; |
1332 | 1333 | ||
1333 | if (size > 3 || size < 1) | 1334 | if (size > 3 || size < 1) |
1334 | return -EINVAL; | 1335 | return -EINVAL; |
1335 | reg_r(dev, 0xa1, 0xb33f, &retbyte, 1); | 1336 | reg_r(gspca_dev, 0xa1, 0xb33f, 1); |
1336 | reg_w(dev, 0xa0, size, 0xb334); | 1337 | reg_w(dev, 0xa0, size, 0xb334); |
1337 | reg_w(dev, 0xa0, reg, 0xb33a); | 1338 | reg_w(dev, 0xa0, reg, 0xb33a); |
1338 | switch (size) { | 1339 | switch (size) { |
@@ -1353,8 +1354,8 @@ static __u8 i2c_write(struct usb_device *dev, | |||
1353 | return -EINVAL; | 1354 | return -EINVAL; |
1354 | } | 1355 | } |
1355 | reg_w(dev, 0xa0, 0x01, 0xb339); | 1356 | reg_w(dev, 0xa0, 0x01, 0xb339); |
1356 | reg_r(dev, 0xa1, 0xb33b, &retbyte, 1); | 1357 | reg_r(gspca_dev, 0xa1, 0xb33b, 1); |
1357 | return retbyte == 0; | 1358 | return gspca_dev->usb_buf[0] == 0; |
1358 | } | 1359 | } |
1359 | 1360 | ||
1360 | static void put_tab_to_reg(struct gspca_dev *gspca_dev, | 1361 | static void put_tab_to_reg(struct gspca_dev *gspca_dev, |
@@ -1382,10 +1383,10 @@ static void usb_exchange(struct gspca_dev *gspca_dev, | |||
1382 | ((data[i][0])<<8) | data[i][1]); | 1383 | ((data[i][0])<<8) | data[i][1]); |
1383 | break; | 1384 | break; |
1384 | case 0xaa: /* i2c op */ | 1385 | case 0xaa: /* i2c op */ |
1385 | i2c_write(dev, data[i][1], &data[i][2], 1); | 1386 | i2c_write(gspca_dev, data[i][1], &data[i][2], 1); |
1386 | break; | 1387 | break; |
1387 | case 0xbb: /* i2c op */ | 1388 | case 0xbb: /* i2c op */ |
1388 | i2c_write(dev, data[i][0], &data[i][1], 2); | 1389 | i2c_write(gspca_dev, data[i][0], &data[i][1], 2); |
1389 | break; | 1390 | break; |
1390 | case 0xdd: | 1391 | case 0xdd: |
1391 | msleep(data[i][2] + 10); | 1392 | msleep(data[i][2] + 10); |
@@ -1417,7 +1418,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1417 | struct sd *sd = (struct sd *) gspca_dev; | 1418 | struct sd *sd = (struct sd *) gspca_dev; |
1418 | struct usb_device *dev = gspca_dev->dev; | 1419 | struct usb_device *dev = gspca_dev->dev; |
1419 | struct cam *cam; | 1420 | struct cam *cam; |
1420 | __u8 tmp2[4]; | ||
1421 | int sensor; | 1421 | int sensor; |
1422 | __u16 product; | 1422 | __u16 product; |
1423 | 1423 | ||
@@ -1488,10 +1488,10 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1488 | sd->lightfreq = FREQ_DEF; | 1488 | sd->lightfreq = FREQ_DEF; |
1489 | 1489 | ||
1490 | if (sd->bridge == BRIDGE_VC0321) { | 1490 | if (sd->bridge == BRIDGE_VC0321) { |
1491 | reg_r(dev, 0x8a, 0, tmp2, 3); | 1491 | reg_r(gspca_dev, 0x8a, 0, 3); |
1492 | reg_w(dev, 0x87, 0x00, 0x0f0f); | 1492 | reg_w(dev, 0x87, 0x00, 0x0f0f); |
1493 | 1493 | ||
1494 | reg_r(dev, 0x8b, 0, tmp2, 3); | 1494 | reg_r(gspca_dev, 0x8b, 0, 3); |
1495 | reg_w(dev, 0x88, 0x00, 0x0202); | 1495 | reg_w(dev, 0x88, 0x00, 0x0202); |
1496 | } | 1496 | } |
1497 | return 0; | 1497 | return 0; |
@@ -1525,7 +1525,6 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
1525 | static void sd_start(struct gspca_dev *gspca_dev) | 1525 | static void sd_start(struct gspca_dev *gspca_dev) |
1526 | { | 1526 | { |
1527 | struct sd *sd = (struct sd *) gspca_dev; | 1527 | struct sd *sd = (struct sd *) gspca_dev; |
1528 | /* __u8 tmp2; */ | ||
1529 | const __u8 *GammaT = NULL; | 1528 | const __u8 *GammaT = NULL; |
1530 | const __u8 *MatrixT = NULL; | 1529 | const __u8 *MatrixT = NULL; |
1531 | int mode; | 1530 | int mode; |
@@ -1627,7 +1626,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1627 | reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824); | 1626 | reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824); |
1628 | */ | 1627 | */ |
1629 | /* Only works for HV7131R ?? | 1628 | /* Only works for HV7131R ?? |
1630 | reg_r (gspca_dev->dev, 0xa1, 0xb881, &tmp2, 1); | 1629 | reg_r (gspca_dev, 0xa1, 0xb881, 1); |
1631 | reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881); | 1630 | reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881); |
1632 | reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801); | 1631 | reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801); |
1633 | */ | 1632 | */ |