Skip to content

Commit

Permalink
V4L/DVB (8352): gspca: Buffers for USB exchanges cannot be in the stack.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jean-Francois Moine authored and Mauro Carvalho Chehab committed Jul 20, 2008
1 parent 5b77ae7 commit 739570b
Show file tree
Hide file tree
Showing 22 changed files with 1,700 additions and 1,795 deletions.
385 changes: 176 additions & 209 deletions drivers/media/video/gspca/conex.c

Large diffs are not rendered by default.

443 changes: 222 additions & 221 deletions drivers/media/video/gspca/etoms.c

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions drivers/media/video/gspca/gspca.c
Original file line number Diff line number Diff line change
Expand Up @@ -1347,9 +1347,11 @@ static int frame_wait(struct gspca_dev *gspca_dev,
gspca_dev->fr_i,
gspca_dev->fr_o);

if (gspca_dev->sd_desc->dq_callback)
if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->sd_desc->dq_callback(gspca_dev);

mutex_unlock(&gspca_dev->usb_lock);
}
return j;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/gspca/gspca.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ struct gspca_dev {
struct cam cam; /* device information */
const struct sd_desc *sd_desc; /* subdriver description */

__u8 usb_buf[8]; /* buffer for USB exchanges */
struct urb *urb[MAX_NURBS];

__u8 *frbuf; /* buffer for nframes */
Expand Down
158 changes: 85 additions & 73 deletions drivers/media/video/gspca/mars.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
#include "gspca.h"
#include "jpeg.h"

#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5)
static const char version[] = "2.1.5";
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.7";

MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
Expand Down Expand Up @@ -83,39 +83,53 @@ enum {
REG_HW_MI_63,
REG_HW_MI_64,
REG_HW_MI_F1 = 0xf1,
ATTR_TOTAL_MI_REG = 242
ATTR_TOTAL_MI_REG = 0xf2
};

static int pcam_reg_write(struct usb_device *dev,
__u16 index, __u8 *value, int len)
/* the bytes to write are in gspca_dev->usb_buf */
static int reg_w(struct gspca_dev *gspca_dev,
__u16 index, int len)
{
int rc;

rc = usb_control_msg(dev,
usb_sndbulkpipe(dev, 4),
rc = usb_control_msg(gspca_dev->dev,
usb_sndbulkpipe(gspca_dev->dev, 4),
0x12,
/* ?? 0xc8 = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_??? !? */
0xc8,
0xc8, /* ?? */
0, /* value */
index, value, len, 500);
index, gspca_dev->usb_buf, len, 500);
if (rc < 0)
PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
return rc;
}

static void MISensor_BulkWrite(struct usb_device *dev,
unsigned short *pch,
char Address)
static int reg_w_buf(struct gspca_dev *gspca_dev,
__u16 index, __u8 *buf, int len)
{
__u8 data[6];
int rc;

rc = usb_control_msg(gspca_dev->dev,
usb_sndbulkpipe(gspca_dev->dev, 4),
0x12,
0xc8, /* ?? */
0, /* value */
index, buf, len, 500);
if (rc < 0)
PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
return rc;
}

data[0] = 0x1f;
data[1] = 0; /* control byte */
data[2] = Address;
data[3] = *pch >> 8; /* high byte */
data[4] = *pch; /* low byte */
static void bulk_w(struct gspca_dev *gspca_dev,
__u16 *pch,
__u16 Address)
{
gspca_dev->usb_buf[0] = 0x1f;
gspca_dev->usb_buf[1] = 0; /* control byte */
gspca_dev->usb_buf[2] = Address;
gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */
gspca_dev->usb_buf[4] = *pch; /* low byte */

pcam_reg_write(dev, Address, data, 5);
reg_w(gspca_dev, Address, 5);
}

/* this function is called at probe time */
Expand All @@ -142,33 +156,30 @@ static int sd_open(struct gspca_dev *gspca_dev)

static void sd_start(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
int err_code;
__u8 data[12];
__u16 MI_buf[242];
__u8 *data;
__u16 *MI_buf;
int h_size, v_size;
int intpipe;
/* struct usb_device *dev = pcam->dev; */

memset(data, 0, sizeof data);
memset(MI_buf, 0, sizeof MI_buf);

PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
if (usb_set_interface(dev, gspca_dev->iface, 8) < 0) {
if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8) < 0) {
PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
return;
}

data = gspca_dev->usb_buf;
data[0] = 0x01; /* address */
data[1] = 0x01;

err_code = pcam_reg_write(dev, data[0], data, 2);
err_code = reg_w(gspca_dev, data[0], 2);
if (err_code < 0)
return;

/*
Initialize the MR97113 chip register
*/
data = kmalloc(16, GFP_KERNEL);
data[0] = 0x00; /* address */
data[1] = 0x0c | 0x01; /* reg 0 */
data[2] = 0x01; /* reg 1 */
Expand All @@ -181,34 +192,34 @@ static void sd_start(struct gspca_dev *gspca_dev)
data[6] = 4; /* reg 5, H start */
data[7] = 0xc0; /* reg 6, gamma 1.5 */
data[8] = 3; /* reg 7, V start */
/* if(h_size == 320 ) */
/* if (h_size == 320 ) */
/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
/* else */
data[9] = 0x52; /* reg 8, 24MHz, no scale down */
data[10] = 0x5d; /* reg 9, I2C device address
* [for PAS5101 (0x40)] [for MI (0x5d)] */

err_code = pcam_reg_write(dev, data[0], data, 11);
err_code = reg_w_buf(gspca_dev, data[0], data, 11);
kfree(data);
if (err_code < 0)
return;

data = gspca_dev->usb_buf;
data[0] = 0x23; /* address */
data[1] = 0x09; /* reg 35, append frame header */

err_code = pcam_reg_write(dev, data[0], data, 2);
if (err_code < 0) {
PDEBUG(D_ERR, "Register write failed");
err_code = reg_w(gspca_dev, data[0], 2);
if (err_code < 0)
return;
}

data[0] = 0x3C; /* address */
/* if (pcam->width == 1280) */
data[0] = 0x3c; /* address */
/* if (gspca_dev->width == 1280) */
/* data[1] = 200; * reg 60, pc-cam frame size
* (unit: 4KB) 800KB */
/* else */
data[1] = 50; /* 50 reg 60, pc-cam frame size
* (unit: 4KB) 200KB */
err_code = pcam_reg_write(dev, data[0], data, 2);
err_code = reg_w(gspca_dev, data[0], 2);
if (err_code < 0)
return;

Expand Down Expand Up @@ -250,19 +261,20 @@ static void sd_start(struct gspca_dev *gspca_dev)
/* auto dark-gain */
data[0] = 0x5e; /* address */

err_code = pcam_reg_write(dev, data[0], data, 6);
err_code = reg_w(gspca_dev, data[0], 6);
if (err_code < 0)
return;

data[0] = 0x67;
data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */
err_code = pcam_reg_write(dev, data[0], data, 2);
err_code = reg_w(gspca_dev, data[0], 2);
if (err_code < 0)
return;

/*
* initialize the value of MI sensor...
*/
MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL);
MI_buf[REG_HW_MI_1] = 0x000a;
MI_buf[REG_HW_MI_2] = 0x000c;
MI_buf[REG_HW_MI_3] = 0x0405;
Expand Down Expand Up @@ -304,48 +316,48 @@ static void sd_start(struct gspca_dev *gspca_dev)
}
MI_buf[0x20] = 0x1104;

MISensor_BulkWrite(dev, MI_buf + 1, 1);
MISensor_BulkWrite(dev, MI_buf + 2, 2);
MISensor_BulkWrite(dev, MI_buf + 3, 3);
MISensor_BulkWrite(dev, MI_buf + 4, 4);
MISensor_BulkWrite(dev, MI_buf + 5, 5);
MISensor_BulkWrite(dev, MI_buf + 6, 6);
MISensor_BulkWrite(dev, MI_buf + 7, 7);
MISensor_BulkWrite(dev, MI_buf + 9, 9);
MISensor_BulkWrite(dev, MI_buf + 0x0b, 0x0b);
MISensor_BulkWrite(dev, MI_buf + 0x0c, 0x0c);
MISensor_BulkWrite(dev, MI_buf + 0x0d, 0x0d);
MISensor_BulkWrite(dev, MI_buf + 0x1e, 0x1e);
MISensor_BulkWrite(dev, MI_buf + 0x20, 0x20);
MISensor_BulkWrite(dev, MI_buf + 0x2b, 0x2b);
MISensor_BulkWrite(dev, MI_buf + 0x2c, 0x2c);
MISensor_BulkWrite(dev, MI_buf + 0x2d, 0x2d);
MISensor_BulkWrite(dev, MI_buf + 0x2e, 0x2e);
MISensor_BulkWrite(dev, MI_buf + 0x35, 0x35);
MISensor_BulkWrite(dev, MI_buf + 0x5f, 0x5f);
MISensor_BulkWrite(dev, MI_buf + 0x60, 0x60);
MISensor_BulkWrite(dev, MI_buf + 0x61, 0x61);
MISensor_BulkWrite(dev, MI_buf + 0x62, 0x62);
MISensor_BulkWrite(dev, MI_buf + 0x63, 0x63);
MISensor_BulkWrite(dev, MI_buf + 0x64, 0x64);
MISensor_BulkWrite(dev, MI_buf + 0xf1, 0xf1);

intpipe = usb_sndintpipe(dev, 0);
err_code = usb_clear_halt(dev, intpipe);
bulk_w(gspca_dev, MI_buf + 1, 1);
bulk_w(gspca_dev, MI_buf + 2, 2);
bulk_w(gspca_dev, MI_buf + 3, 3);
bulk_w(gspca_dev, MI_buf + 4, 4);
bulk_w(gspca_dev, MI_buf + 5, 5);
bulk_w(gspca_dev, MI_buf + 6, 6);
bulk_w(gspca_dev, MI_buf + 7, 7);
bulk_w(gspca_dev, MI_buf + 9, 9);
bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b);
bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c);
bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d);
bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e);
bulk_w(gspca_dev, MI_buf + 0x20, 0x20);
bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b);
bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c);
bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d);
bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e);
bulk_w(gspca_dev, MI_buf + 0x35, 0x35);
bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f);
bulk_w(gspca_dev, MI_buf + 0x60, 0x60);
bulk_w(gspca_dev, MI_buf + 0x61, 0x61);
bulk_w(gspca_dev, MI_buf + 0x62, 0x62);
bulk_w(gspca_dev, MI_buf + 0x63, 0x63);
bulk_w(gspca_dev, MI_buf + 0x64, 0x64);
bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1);
kfree(MI_buf);

intpipe = usb_sndintpipe(gspca_dev->dev, 0);
err_code = usb_clear_halt(gspca_dev->dev, intpipe);

data[0] = 0x00;
data[1] = 0x4d; /* ISOC transfering enable... */
pcam_reg_write(dev, data[0], data, 2);
reg_w(gspca_dev, data[0], 2);
}

static void sd_stopN(struct gspca_dev *gspca_dev)
{
int result;
__u8 data[2];

data[0] = 1;
data[1] = 0;
result = pcam_reg_write(gspca_dev->dev, data[0], data, 2);
gspca_dev->usb_buf[0] = 1;
gspca_dev->usb_buf[1] = 0;
result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2);
if (result < 0)
PDEBUG(D_ERR, "Camera Stop failed");
}
Expand Down
19 changes: 8 additions & 11 deletions drivers/media/video/gspca/ov519.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@

#include "gspca.h"

#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5)
static const char version[] = "2.1.5";
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
static const char version[] = "2.1.7";

MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("OV519 USB Camera Driver");
Expand Down Expand Up @@ -282,15 +282,14 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
static int reg_w(struct sd *sd, __u16 index, __u8 value)
{
int ret;
__u8 data;

data = value;
sd->gspca_dev.usb_buf[0] = value;
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
1, /* REQ_IO (ov518/519) */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index,
&data, 1, 500);
sd->gspca_dev.usb_buf, 1, 500);
if (ret < 0)
PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value);
return ret;
Expand All @@ -301,16 +300,15 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
static int reg_r(struct sd *sd, __u16 index)
{
int ret;
__u8 data;

ret = usb_control_msg(sd->gspca_dev.dev,
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1, /* REQ_IO */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index, &data, 1, 500);
0, index, sd->gspca_dev.usb_buf, 1, 500);

if (ret >= 0)
ret = data;
ret = sd->gspca_dev.usb_buf[0];
else
PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
return ret;
Expand All @@ -321,16 +319,15 @@ static int reg_r8(struct sd *sd,
__u16 index)
{
int ret;
__u8 buf[8];

ret = usb_control_msg(sd->gspca_dev.dev,
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1, /* REQ_IO */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index, &buf[0], 8, 500);
0, index, sd->gspca_dev.usb_buf, 8, 500);

if (ret >= 0)
ret = buf[0];
ret = sd->gspca_dev.usb_buf[0];
else
PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
return ret;
Expand Down
Loading

0 comments on commit 739570b

Please sign in to comment.