gspca_sonixj: handle return values from USB subsystem
RFC PATCH 1/1 gspca_sonixj: handle return values from USB subsystem
From: Márton Németh <[email protected]>
The usb_control_msg() may return error at any time so it is necessary to handle it. The error handling mechanism is taken from the pac7302.
The resulting driver was tested with hama AC-150 webcam (USB ID 0c45:6142).
---
drivers/media/video/gspca/sonixj.c +86 -23
@@ -1359,29 +1359,45 @@ static const u8 (*sensor_init[])[8] = {static void reg_r (struct gspca_dev *gspca_dev,u16 value,int len) { +int ret; +#ifdef GSPCA_DEBUG if (len >USB_BUF_SZ ) {err ("reg_r: buffer overflow" );return ; }#endif -usb_control_msg (gspca_dev->dev, +if (gspca_dev->usb_err <0 ) +return ; + ret =usb_control_msg (gspca_dev->dev,usb_rcvctrlpipe (gspca_dev->dev,0 ),0 ,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_INTERFACE , value,0 , gspca_dev->usb_buf, len,500 ); -PDEBUG (D_USBI ,"reg_r [%02x] -> %02x" , value, gspca_dev->usb_buf[0 ]); +if (ret <0 ) { +PDEBUG (D_ERR ,"reg_r(): " +"Failed to read %i registers from to 0x%x, error %i" , + len, value, ret); + gspca_dev->usb_err = ret; + }else { +PDEBUG (D_USBI ,"reg_r [%02x] -> %02x" , + value, gspca_dev->usb_buf[0 ]); + } }static void reg_w1 (struct gspca_dev *gspca_dev,u16 value,u8 data) { +int ret; + +if (gspca_dev->usb_err <0 ) +return ;PDEBUG (D_USBO ,"reg_w1 [%04x] = %02x" , value, data); gspca_dev->usb_buf[0 ] = data; - usb_control_msg(gspca_dev->dev, + ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0x08, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
@@ -1389,12 +1405,22 @@ static void reg_w1(struct gspca_dev *gsp0 , gspca_dev->usb_buf,1 , 500); +if (ret <0 ) { +PDEBUG (D_ERR ,"reg_w1(): " +"Failed to write register to 0x%x, error %i" , + value, ret); + gspca_dev->usb_err = ret; + } }static void reg_w (struct gspca_dev *gspca_dev,u16 value,const u8 *buffer,int len) { +int ret; + +if (gspca_dev->usb_err <0 ) +return ;PDEBUG (D_USBO ,"reg_w [%04x] = %02x %02x .." , value, buffer[0 ], buffer[1 ]);#ifdef GSPCA_DEBUG
@@ -1404,20 +1430,29 @@ static void reg_w(struct gspca_dev *gspc }#endif memcpy (gspca_dev->usb_buf, buffer, len); -usb_control_msg (gspca_dev->dev, + ret =usb_control_msg (gspca_dev->dev,usb_sndctrlpipe (gspca_dev->dev,0 ),0x08 ,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_INTERFACE , value,0 , gspca_dev->usb_buf, len,500 ); +if (ret <0 ) { +PDEBUG (D_ERR ,"reg_w(): " +"Failed to write %i registers to 0x%x, error %i" , + len, value, ret); + gspca_dev->usb_err = ret; + } }/* I2C write 1 byte */ static void i2c_w1 (struct gspca_dev *gspca_dev,u8 reg,u8 val) {struct sd *sd = (struct sd *) gspca_dev; +int ret; +if (gspca_dev->usb_err <0 ) +return ;PDEBUG (D_USBO ,"i2c_w1 [%02x] = %02x" , reg, val);switch (sd->sensor) {case SENSOR_ADCM1700 :
@@ -1436,7 +1471,7 @@ static void i2c_w1(struct gspca_dev *gsp gspca_dev->usb_buf[5 ] =0 ; gspca_dev->usb_buf[6 ] =0 ; gspca_dev->usb_buf[7 ] =0x10 ; - usb_control_msg(gspca_dev->dev, + ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0x08, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
@@ -1444,22 +1479,37 @@ static void i2c_w1(struct gspca_dev *gsp0 , gspca_dev->usb_buf,8 , 500); +if (ret <0 ) { +PDEBUG (D_ERR ,"i2c_w1(): Failed to write " +"I2C register 0x%x, value 0x%X, error %i" , + reg, val, ret); + gspca_dev->usb_err = ret; + } }/* I2C write 8 bytes */ static void i2c_w8 (struct gspca_dev *gspca_dev,const u8 *buffer) { +int ret; + +if (gspca_dev->usb_err <0 ) +return ;PDEBUG (D_USBO ,"i2c_w8 [%02x] = %02x .." , buffer[2 ], buffer[3 ]);memcpy (gspca_dev->usb_buf, buffer,8 ); -usb_control_msg (gspca_dev->dev, + ret =usb_control_msg (gspca_dev->dev,usb_sndctrlpipe (gspca_dev->dev,0 ),0x08 ,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_INTERFACE ,0x08 ,0 ,/* value, index */ gspca_dev->usb_buf,8 ,500 ); +if (ret <0 ) { +PDEBUG (D_ERR ,"i2c_w8(): Failed to write " +"I2C registers, error %i" , ret); + gspca_dev->usb_err = ret; + }msleep (2 ); }
@@ -1915,7 +1965,7 @@ static int sd_init(struct gspca_dev *gsp gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; -return 0 ; +return gspca_dev->usb_err; } static u32 setexposure(struct gspca_dev *gspca_dev,
@@ -2289,6 +2339,7 @@ static void setjpegqual(struct gspca_dev {struct sd *sd = (struct sd *) gspca_dev;int i, sc; +int ret;if (sd->jpegqual <50 ) sc =5000 / sd->jpegqual;
@@ -2300,23 +2351,35 @@ static void setjpegqual(struct gspca_devfor (i =0 ; i <64 ; i++) gspca_dev->usb_buf[i] = (jpeg_head[JPEG_QT0_OFFSET + i] * sc +50 ) /100 ; -usb_control_msg (gspca_dev->dev, + ret =usb_control_msg (gspca_dev->dev,usb_sndctrlpipe (gspca_dev->dev,0 ),0x08 ,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_INTERFACE ,0x0100 ,0 , gspca_dev->usb_buf,64 ,500 ); +if (ret <0 ) { +PDEBUG (D_ERR ,"setjpegqual(): Failed to set JPEG quality, " +"error %i" , ret); + gspca_dev->usb_err = ret; +return ; + }for (i =0 ; i <64 ; i++) gspca_dev->usb_buf[i] = (jpeg_head[JPEG_QT1_OFFSET + i] * sc +50 ) /100 ; -usb_control_msg (gspca_dev->dev, + ret =usb_control_msg (gspca_dev->dev,usb_sndctrlpipe (gspca_dev->dev,0 ),0x08 ,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_INTERFACE ,0x0140 ,0 , gspca_dev->usb_buf,64 ,500 ); +if (ret <0 ) { +PDEBUG (D_ERR ,"setjpegqual(): Failed to set JPEG quality, " +"error %i" , ret); + gspca_dev->usb_err = ret; +return ; + } sd->reg18 ^=0x40 ;reg_w1 (gspca_dev,0x18 , sd->reg18);
@@ -2591,7 +2654,7 @@ static int sd_start(struct gspca_dev *gssetcolors (gspca_dev);setautogain (gspca_dev);setfreq (gspca_dev); -return 0 ; +return gspca_dev->usb_err; }static void sd_stopN (struct gspca_dev *gspca_dev)
@@ -2754,7 +2817,7 @@ static int sd_setbrightness(struct gspca 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)
@@ -2772,7 +2835,7 @@ static int sd_setcontrast(struct gspca_d 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)
@@ -2790,7 +2853,7 @@ static int sd_setcolors(struct gspca_dev 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)
@@ -2808,7 +2871,7 @@ static int sd_setblue_balance(struct gsp sd->blue = val;if (gspca_dev->streaming)setredblue (gspca_dev); -return 0 ; +return gspca_dev->usb_err; }static int sd_getblue_balance (struct gspca_dev *gspca_dev,__s32 *val)
@@ -2826,7 +2889,7 @@ static int sd_setred_balance(struct gspc sd->red = val;if (gspca_dev->streaming)setredblue (gspca_dev); -return 0 ; +return gspca_dev->usb_err; }static int sd_getred_balance (struct gspca_dev *gspca_dev,__s32 *val)
@@ -2844,7 +2907,7 @@ static int sd_setgamma(struct gspca_dev sd->gamma = val;if (gspca_dev->streaming)setgamma (gspca_dev); -return 0 ; +return gspca_dev->usb_err; }static int sd_getgamma (struct gspca_dev *gspca_dev,__s32 *val)
@@ -2862,7 +2925,7 @@ static int sd_setautogain(struct gspca_d sd->autogain = val;if (gspca_dev->streaming)setautogain (gspca_dev); -return 0 ; +return gspca_dev->usb_err; }static int sd_getautogain (struct gspca_dev *gspca_dev,__s32 *val)
@@ -2880,7 +2943,7 @@ static int sd_setsharpness(struct gspca_ sd->sharpness = val;if (gspca_dev->streaming)setsharpness (sd); -return 0 ; +return gspca_dev->usb_err; }static int sd_getsharpness (struct gspca_dev *gspca_dev,__s32 *val)
@@ -2898,7 +2961,7 @@ static int sd_setvflip(struct gspca_dev sd->vflip = val;if (gspca_dev->streaming)sethvflip (sd); -return 0 ; +return gspca_dev->usb_err; }static int sd_getvflip (struct gspca_dev *gspca_dev,__s32 *val)
@@ -2916,7 +2979,7 @@ static int sd_sethflip(struct gspca_dev sd->hflip = val;if (gspca_dev->streaming)sethvflip (sd); -return 0 ; +return gspca_dev->usb_err; }static int sd_gethflip (struct gspca_dev *gspca_dev,__s32 *val)
@@ -2934,7 +2997,7 @@ static int sd_setinfrared(struct gspca_d sd->infrared = val;if (gspca_dev->streaming)setinfrared (sd); -return 0 ; +return gspca_dev->usb_err; }static int sd_getinfrared (struct gspca_dev *gspca_dev,__s32 *val)
@@ -2952,7 +3015,7 @@ static int sd_setfreq(struct gspca_dev * sd->freq = 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)
@@ -2976,7 +3039,7 @@ static int sd_set_jcomp(struct 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,
Quoted 5 lines · On Sun, 17 Oct 2010 16:45:03 +0200 Németh Márton <[email protected]> wrote:
The
usb_control_msg()may return error at any time so it is necessary to handle it. The error handling mechanism is taken from the pac7302.The resulting driver was tested with hama AC-150 webcam (USB ID 0c45:6142).
Hi Németh,
This mechanism has already been done by commit 60f44336 in media_tree.git branch staging/v2.6.37.
Cheers.
Signature · 2 lines
Ken ar c'hentañ | ** Breizh ha Linux atav! ** Jef | http://moinejf.free.fr/
Hi,
Jean-Francois Moine írta:
Quoted 6 lines
Quoted 3 lines · On Sun, 17 Oct 2010 16:45:03 +0200 Németh Márton <[email protected]> wrote:
The
usb_control_msg()may return error at any time so it is necessary to handle it. The error handling mechanism is taken from the pac7302.
Quoted 7 lines
Quoted 2 lines
The resulting driver was tested with hama AC-150 webcam (USB ID 0c45:6142).
Hi Németh,
This mechanism has already been done by commit
60f44336in media_tree.git branch staging/v2.6.37.
I must looking at totally wrong place for my base of changes. Now I see the branch staging/v2.6.37, thanks for the hint.
Márton Németh