Commit ecb77686 authored by Jean-Francois Moine's avatar Jean-Francois Moine Committed by Mauro Carvalho Chehab

V4L/DVB (13567): gspca - sunplus/stk014: Propagate errors to higher level.

Signed-off-by: default avatarJean-Francois Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 8c4ebae4
......@@ -126,12 +126,14 @@ static const struct v4l2_pix_format vga_mode[] = {
};
/* -- read a register -- */
static int reg_r(struct gspca_dev *gspca_dev,
static u8 reg_r(struct gspca_dev *gspca_dev,
__u16 index)
{
struct usb_device *dev = gspca_dev->dev;
int ret;
if (gspca_dev->usb_err < 0)
return 0;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0x00,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
......@@ -141,18 +143,21 @@ static int reg_r(struct gspca_dev *gspca_dev,
500);
if (ret < 0) {
PDEBUG(D_ERR, "reg_r err %d", ret);
return ret;
gspca_dev->usb_err = ret;
return 0;
}
return gspca_dev->usb_buf[0];
}
/* -- write a register -- */
static int reg_w(struct gspca_dev *gspca_dev,
static void reg_w(struct gspca_dev *gspca_dev,
__u16 index, __u16 value)
{
struct usb_device *dev = gspca_dev->dev;
int ret;
if (gspca_dev->usb_err < 0)
return;
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0x01,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
......@@ -161,13 +166,14 @@ static int reg_w(struct gspca_dev *gspca_dev,
NULL,
0,
500);
if (ret < 0)
if (ret < 0) {
PDEBUG(D_ERR, "reg_w err %d", ret);
return ret;
gspca_dev->usb_err = ret;
}
}
/* -- get a bulk value (4 bytes) -- */
static int rcv_val(struct gspca_dev *gspca_dev,
static void rcv_val(struct gspca_dev *gspca_dev,
int ads)
{
struct usb_device *dev = gspca_dev->dev;
......@@ -182,17 +188,22 @@ static int rcv_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x63a, 0);
reg_w(gspca_dev, 0x63b, 0);
reg_w(gspca_dev, 0x630, 5);
if (gspca_dev->usb_err < 0)
return;
ret = usb_bulk_msg(dev,
usb_rcvbulkpipe(dev, 0x05),
gspca_dev->usb_buf,
4, /* length */
&alen,
500); /* timeout in milliseconds */
return ret;
if (ret < 0) {
PDEBUG(D_ERR, "rcv_val err %d", ret);
gspca_dev->usb_err = ret;
}
}
/* -- send a bulk value -- */
static int snd_val(struct gspca_dev *gspca_dev,
static void snd_val(struct gspca_dev *gspca_dev,
int ads,
unsigned int val)
{
......@@ -201,16 +212,9 @@ static int snd_val(struct gspca_dev *gspca_dev,
__u8 seq = 0;
if (ads == 0x003f08) {
ret = reg_r(gspca_dev, 0x0704);
if (ret < 0)
goto ko;
ret = reg_r(gspca_dev, 0x0705);
if (ret < 0)
goto ko;
seq = ret; /* keep the sequence number */
ret = reg_r(gspca_dev, 0x0650);
if (ret < 0)
goto ko;
reg_r(gspca_dev, 0x0704);
seq = reg_r(gspca_dev, 0x0705);
reg_r(gspca_dev, 0x0650);
reg_w(gspca_dev, 0x654, seq);
} else {
reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
......@@ -223,6 +227,8 @@ static int snd_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x65a, 0);
reg_w(gspca_dev, 0x65b, 0);
reg_w(gspca_dev, 0x650, 5);
if (gspca_dev->usb_err < 0)
return;
gspca_dev->usb_buf[0] = val >> 24;
gspca_dev->usb_buf[1] = val >> 16;
gspca_dev->usb_buf[2] = val >> 8;
......@@ -233,24 +239,23 @@ static int snd_val(struct gspca_dev *gspca_dev,
4,
&alen,
500); /* timeout in milliseconds */
if (ret < 0)
goto ko;
if (ads == 0x003f08) {
seq += 4;
seq &= 0x3f;
reg_w(gspca_dev, 0x705, seq);
if (ret < 0) {
PDEBUG(D_ERR, "snd_val err %d", ret);
gspca_dev->usb_err = ret;
} else {
if (ads == 0x003f08) {
seq += 4;
seq &= 0x3f;
reg_w(gspca_dev, 0x705, seq);
}
}
return ret;
ko:
PDEBUG(D_ERR, "snd_val err %d", ret);
return ret;
}
/* set a camera parameter */
static int set_par(struct gspca_dev *gspca_dev,
static void set_par(struct gspca_dev *gspca_dev,
int parval)
{
return snd_val(gspca_dev, 0x003f08, parval);
snd_val(gspca_dev, 0x003f08, parval);
}
static void setbrightness(struct gspca_dev *gspca_dev)
......@@ -311,18 +316,18 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
int ret;
u8 ret;
/* check if the device responds */
usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
ret = reg_r(gspca_dev, 0x0740);
if (ret < 0)
return ret;
if (ret != 0xff) {
PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
return -1;
if (gspca_dev->usb_err >= 0) {
if (ret != 0xff) {
PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
gspca_dev->usb_err = -EIO;
}
}
return 0;
return gspca_dev->usb_err;
}
/* -- start the camera -- */
......@@ -357,15 +362,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
if (ret < 0) {
PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed",
gspca_dev->iface, gspca_dev->alt);
gspca_dev->usb_err = ret;
goto out;
}
ret = reg_r(gspca_dev, 0x0630);
if (ret < 0)
goto out;
reg_r(gspca_dev, 0x0630);
rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
ret = reg_r(gspca_dev, 0x0650);
if (ret < 0)
goto out;
reg_r(gspca_dev, 0x0650);
snd_val(gspca_dev, 0x000020, 0xffffffff);
reg_w(gspca_dev, 0x0620, 0);
reg_w(gspca_dev, 0x0630, 0);
......@@ -384,11 +386,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* start the video flow */
set_par(gspca_dev, 0x01000000);
set_par(gspca_dev, 0x01000000);
PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
return 0;
if (gspca_dev->usb_err >= 0)
PDEBUG(D_STREAM, "camera started alt: 0x%02x",
gspca_dev->alt);
out:
PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
return ret;
return gspca_dev->usb_err;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
......@@ -456,7 +458,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
sd->brightness = val;
if (gspca_dev->streaming)
setbrightness(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
......@@ -474,7 +476,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
sd->contrast = val;
if (gspca_dev->streaming)
setcontrast(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
......@@ -492,7 +494,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
sd->colors = val;
if (gspca_dev->streaming)
setcolors(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
......@@ -510,7 +512,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
sd->lightfreq = val;
if (gspca_dev->streaming)
setfreq(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
......@@ -552,7 +554,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev,
sd->quality = jcomp->quality;
if (gspca_dev->streaming)
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
return 0;
return gspca_dev->usb_err;
}
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment