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