0x00
 };
 
-static void reg_w_buf(struct gspca_dev *gspca_dev,
+static int reg_w_buf(struct gspca_dev *gspca_dev,
                  __u8 index,
                  const char *buffer, int len)
 {
                PDEBUG(D_ERR, "reg_w_buf(): "
                "Failed to write registers to index 0x%x, error %i",
                index, ret);
+       return ret;
 }
 
 
-static void reg_w(struct gspca_dev *gspca_dev,
+static int reg_w(struct gspca_dev *gspca_dev,
                  __u8 index,
                  __u8 value)
 {
                PDEBUG(D_ERR, "reg_w(): "
                "Failed to write register to index 0x%x, value 0x%x, error %i",
                index, value, ret);
+       return ret;
 }
 
-static void reg_w_seq(struct gspca_dev *gspca_dev,
+static int reg_w_seq(struct gspca_dev *gspca_dev,
                const __u8 *seq, int len)
 {
+       int ret = 0;
        while (--len >= 0) {
-               reg_w(gspca_dev, seq[0], seq[1]);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, seq[0], seq[1]);
                seq += 2;
        }
+       return ret;
 }
 
 /* load the beginning of a page */
-static void reg_w_page(struct gspca_dev *gspca_dev,
+static int reg_w_page(struct gspca_dev *gspca_dev,
                        const __u8 *page, int len)
 {
        int index;
-       int ret;
+       int ret = 0;
 
        for (index = 0; index < len; index++) {
                if (page[index] == SKIP)                /* skip this index */
                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                                0, index, gspca_dev->usb_buf, 1,
                                500);
-               if (ret < 0)
+               if (ret < 0) {
                        PDEBUG(D_ERR, "reg_w_page(): "
                        "Failed to write register to index 0x%x, "
                        "value 0x%x, error %i",
                        index, page[index], ret);
+                       break;
+               }
        }
+       return ret;
 }
 
 /* output a variable sequence */
-static void reg_w_var(struct gspca_dev *gspca_dev,
+static int reg_w_var(struct gspca_dev *gspca_dev,
                        const __u8 *seq,
                        const __u8 *page3, unsigned int page3_len,
                        const __u8 *page4, unsigned int page4_len)
 {
        int index, len;
+       int ret = 0;
 
        for (;;) {
                index = *seq++;
                len = *seq++;
                switch (len) {
                case END_OF_SEQUENCE:
-                       return;
+                       return ret;
                case LOAD_PAGE4:
-                       reg_w_page(gspca_dev, page4, page4_len);
+                       ret = reg_w_page(gspca_dev, page4, page4_len);
                        break;
                case LOAD_PAGE3:
-                       reg_w_page(gspca_dev, page3, page3_len);
+                       ret = reg_w_page(gspca_dev, page3, page3_len);
                        break;
                default:
                        if (len > USB_BUF_SZ) {
                                PDEBUG(D_ERR|D_STREAM,
                                        "Incorrect variable sequence");
-                               return;
+                               return -EINVAL;
                        }
                        while (len > 0) {
                                if (len < 8) {
-                                       reg_w_buf(gspca_dev, index, seq, len);
+                                       ret = reg_w_buf(gspca_dev,
+                                               index, seq, len);
+                                       if (ret < 0)
+                                               return ret;
                                        seq += len;
                                        break;
                                }
-                               reg_w_buf(gspca_dev, index, seq, 8);
+                               ret = reg_w_buf(gspca_dev, index, seq, 8);
                                seq += 8;
                                index += 8;
                                len -= 8;
                        }
                }
+               if (ret < 0)
+                       return ret;
        }
        /* not reached */
 }
 }
 
 /* This function is used by pac7302 only */
-static void setbrightcont(struct gspca_dev *gspca_dev)
+static int setbrightcont(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
        int i, v;
+       int ret;
        static const __u8 max[10] =
                {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
                 0xd4, 0xec};
                {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
                 0x11, 0x0b};
 
-       reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
+       ret = reg_w(gspca_dev, 0xff, 0x00);     /* page 0 */
        for (i = 0; i < 10; i++) {
                v = max[i];
                v += (sd->brightness - BRIGHTNESS_MAX)
                        v = 0;
                else if (v > 0xff)
                        v = 0xff;
-               reg_w(gspca_dev, 0xa2 + i, v);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0xa2 + i, v);
        }
-       reg_w(gspca_dev, 0xdc, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0xdc, 0x01);
+       return ret;
 }
 
 /* This function is used by pac7302 only */
-static void setcolors(struct gspca_dev *gspca_dev)
+static int setcolors(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
        int i, v;
+       int ret;
        static const int a[9] =
                {217, -212, 0, -101, 170, -67, -38, -315, 355};
        static const int b[9] =
                {19, 106, 0, 19, 106, 1, 19, 106, 1};
 
-       reg_w(gspca_dev, 0xff, 0x03);   /* page 3 */
-       reg_w(gspca_dev, 0x11, 0x01);
-       reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
+       ret = reg_w(gspca_dev, 0xff, 0x03);     /* page 3 */
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x11, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0xff, 0x00);     /* page 0 */
        for (i = 0; i < 9; i++) {
                v = a[i] * sd->colors / COLOR_MAX + b[i];
-               reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
-               reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
        }
-       reg_w(gspca_dev, 0xdc, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0xdc, 0x01);
        PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
+       return ret;
 }
 
-static void setgain(struct gspca_dev *gspca_dev)
+static int setgain(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
+       int ret;
 
-       reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
-       reg_w(gspca_dev, 0x10, sd->gain >> 3);
+       ret = reg_w(gspca_dev, 0xff, 0x03);             /* page 3 */
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x10, sd->gain >> 3);
 
        /* load registers to sensor (Bit 0, auto clear) */
-       reg_w(gspca_dev, 0x11, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x11, 0x01);
+       return ret;
 }
 
-static void setexposure(struct gspca_dev *gspca_dev)
+static int setexposure(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
+       int ret;
        __u8 reg;
 
        /* register 2 of frame 3/4 contains the clock divider configuring the
           the nearest multiple of 3, except when between 6 and 12? */
        if (reg < 6 || reg > 12)
                reg = ((reg + 1) / 3) * 3;
-       reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
-       reg_w(gspca_dev, 0x02, reg);
+       ret = reg_w(gspca_dev, 0xff, 0x03);             /* page 3 */
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x02, reg);
 
        /* load registers to sensor (Bit 0, auto clear) */
-       reg_w(gspca_dev, 0x11, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x11, 0x01);
+       return ret;
 }
 
-static void sethvflip(struct gspca_dev *gspca_dev)
+static int sethvflip(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
+       int ret;
        __u8 data;
 
-       reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
+       ret = reg_w(gspca_dev, 0xff, 0x03);             /* page 3 */
        data = (sd->hflip ? 0x08 : 0x00) | (sd->vflip ? 0x04 : 0x00);
-       reg_w(gspca_dev, 0x21, data);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x21, data);
        /* load registers to sensor (Bit 0, auto clear) */
-       reg_w(gspca_dev, 0x11, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x11, 0x01);
+       return ret;
 }
 
 /* this function is called at probe and resume time for pac7302 */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-       reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
-
-       return 0;
+       return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
+       int ret = 0;
 
        sd->sof_read = 0;
 
-       reg_w_var(gspca_dev, start_7302,
+       ret = reg_w_var(gspca_dev, start_7302,
                page3_7302, sizeof(page3_7302),
                NULL, 0);
-       setbrightcont(gspca_dev);
-       setcolors(gspca_dev);
-       setgain(gspca_dev);
-       setexposure(gspca_dev);
-       sethvflip(gspca_dev);
+       if (0 <= ret)
+               ret = setbrightcont(gspca_dev);
+       if (0 <= ret)
+               ret = setcolors(gspca_dev);
+       if (0 <= ret)
+               setgain(gspca_dev);
+       if (0 <= ret)
+               setexposure(gspca_dev);
+       if (0 <= ret)
+               sethvflip(gspca_dev);
 
        /* only resolution 640x480 is supported for pac7302 */
 
        atomic_set(&sd->avg_lum, -1);
 
        /* start stream */
-       reg_w(gspca_dev, 0xff, 0x01);
-       reg_w(gspca_dev, 0x78, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0xff, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x78, 0x01);
 
-       return 0;
+       return ret;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
+       int ret;
+
        /* stop stream */
-       reg_w(gspca_dev, 0xff, 0x01);
-       reg_w(gspca_dev, 0x78, 0x00);
+       ret = reg_w(gspca_dev, 0xff, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x78, 0x00);
 }
 
 /* called on streamoff with alt 0 and on disconnect for pac7302 */
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
+       int ret;
+
        if (!gspca_dev->present)
                return;
-       reg_w(gspca_dev, 0xff, 0x01);
-       reg_w(gspca_dev, 0x78, 0x40);
+       ret = reg_w(gspca_dev, 0xff, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x78, 0x40);
 }
 
 /* Include pac common sof detection functions */
 
        0x23, 0x28, 0x04, 0x11, 0x00, 0x00
 };
 
-static void reg_w_buf(struct gspca_dev *gspca_dev,
+static int reg_w_buf(struct gspca_dev *gspca_dev,
                  __u8 index,
                  const char *buffer, int len)
 {
                PDEBUG(D_ERR, "reg_w_buf(): "
                "Failed to write registers to index 0x%x, error %i",
                index, ret);
+       return ret;
 }
 
 
-static void reg_w(struct gspca_dev *gspca_dev,
+static int reg_w(struct gspca_dev *gspca_dev,
                  __u8 index,
                  __u8 value)
 {
                PDEBUG(D_ERR, "reg_w(): "
                "Failed to write register to index 0x%x, value 0x%x, error %i",
                index, value, ret);
+       return ret;
 }
 
-static void reg_w_seq(struct gspca_dev *gspca_dev,
+static int reg_w_seq(struct gspca_dev *gspca_dev,
                const __u8 *seq, int len)
 {
+       int ret = 0;
        while (--len >= 0) {
-               reg_w(gspca_dev, seq[0], seq[1]);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, seq[0], seq[1]);
                seq += 2;
        }
+       return ret;
 }
 
 /* load the beginning of a page */
-static void reg_w_page(struct gspca_dev *gspca_dev,
+static int reg_w_page(struct gspca_dev *gspca_dev,
                        const __u8 *page, int len)
 {
        int index;
-       int ret;
+       int ret = 0;
 
        for (index = 0; index < len; index++) {
                if (page[index] == SKIP)                /* skip this index */
                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                                0, index, gspca_dev->usb_buf, 1,
                                500);
-               if (ret < 0)
+               if (ret < 0) {
                        PDEBUG(D_ERR, "reg_w_page(): "
                        "Failed to write register to index 0x%x, "
                        "value 0x%x, error %i",
                        index, page[index], ret);
+                       break;
+               }
        }
+       return ret;
 }
 
 /* output a variable sequence */
-static void reg_w_var(struct gspca_dev *gspca_dev,
+static int reg_w_var(struct gspca_dev *gspca_dev,
                        const __u8 *seq,
                        const __u8 *page3, unsigned int page3_len,
                        const __u8 *page4, unsigned int page4_len)
 {
        int index, len;
+       int ret = 0;
 
        for (;;) {
                index = *seq++;
                len = *seq++;
                switch (len) {
                case END_OF_SEQUENCE:
-                       return;
+                       return ret;
                case LOAD_PAGE4:
-                       reg_w_page(gspca_dev, page4, page4_len);
+                       ret = reg_w_page(gspca_dev, page4, page4_len);
                        break;
                case LOAD_PAGE3:
-                       reg_w_page(gspca_dev, page3, page3_len);
+                       ret = reg_w_page(gspca_dev, page3, page3_len);
                        break;
                default:
                        if (len > USB_BUF_SZ) {
                                PDEBUG(D_ERR|D_STREAM,
                                        "Incorrect variable sequence");
-                               return;
+                               return -EINVAL;
                        }
                        while (len > 0) {
                                if (len < 8) {
-                                       reg_w_buf(gspca_dev, index, seq, len);
+                                       ret = reg_w_buf(gspca_dev,
+                                               index, seq, len);
+                                       if (ret < 0)
+                                               return ret;
                                        seq += len;
                                        break;
                                }
-                               reg_w_buf(gspca_dev, index, seq, 8);
+                               ret = reg_w_buf(gspca_dev, index, seq, 8);
                                seq += 8;
                                index += 8;
                                len -= 8;
                        }
                }
+               if (ret < 0)
+                       return ret;
        }
        /* not reached */
 }
 }
 
 /* This function is used by pac7311 only */
-static void setcontrast(struct gspca_dev *gspca_dev)
+static int setcontrast(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
+       int ret;
 
-       reg_w(gspca_dev, 0xff, 0x04);
-       reg_w(gspca_dev, 0x10, sd->contrast >> 4);
+       ret = reg_w(gspca_dev, 0xff, 0x04);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
        /* load registers to sensor (Bit 0, auto clear) */
-       reg_w(gspca_dev, 0x11, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x11, 0x01);
+       return ret;
 }
 
-static void setgain(struct gspca_dev *gspca_dev)
+static int setgain(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
        int gain = GAIN_MAX - sd->gain;
+       int ret;
 
        if (gain < 1)
                gain = 1;
        else if (gain > 245)
                gain = 245;
-       reg_w(gspca_dev, 0xff, 0x04);           /* page 4 */
-       reg_w(gspca_dev, 0x0e, 0x00);
-       reg_w(gspca_dev, 0x0f, gain);
+       ret = reg_w(gspca_dev, 0xff, 0x04);             /* page 4 */
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x0e, 0x00);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x0f, gain);
 
        /* load registers to sensor (Bit 0, auto clear) */
-       reg_w(gspca_dev, 0x11, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x11, 0x01);
+       return ret;
 }
 
-static void setexposure(struct gspca_dev *gspca_dev)
+static int setexposure(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
+       int ret;
        __u8 reg;
 
        /* register 2 of frame 3/4 contains the clock divider configuring the
        else if (reg > 63)
                reg = 63;
 
-       reg_w(gspca_dev, 0xff, 0x04);           /* page 4 */
-       reg_w(gspca_dev, 0x02, reg);
+       ret = reg_w(gspca_dev, 0xff, 0x04);             /* page 4 */
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x02, reg);
        /* Page 1 register 8 must always be 0x08 except when not in
           640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
-       reg_w(gspca_dev, 0xff, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0xff, 0x01);
        if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
-                       reg <= 3)
-               reg_w(gspca_dev, 0x08, 0x09);
-       else
-               reg_w(gspca_dev, 0x08, 0x08);
+                       reg <= 3) {
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x08, 0x09);
+       } else {
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x08, 0x08);
+       }
 
        /* load registers to sensor (Bit 0, auto clear) */
-       reg_w(gspca_dev, 0x11, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x11, 0x01);
+       return ret;
 }
 
-static void sethvflip(struct gspca_dev *gspca_dev)
+static int sethvflip(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
+       int ret;
        __u8 data;
 
-       reg_w(gspca_dev, 0xff, 0x04);           /* page 4 */
+       ret = reg_w(gspca_dev, 0xff, 0x04);             /* page 4 */
        data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
-       reg_w(gspca_dev, 0x21, data);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x21, data);
        /* load registers to sensor (Bit 0, auto clear) */
-       reg_w(gspca_dev, 0x11, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x11, 0x01);
+       return ret;
 }
 
 /* this function is called at probe and resume time for pac7311 */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-       reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
-
-       return 0;
+       return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
+       int ret;
 
        sd->sof_read = 0;
 
-       reg_w_var(gspca_dev, start_7311,
+       ret = reg_w_var(gspca_dev, start_7311,
                NULL, 0,
                page4_7311, sizeof(page4_7311));
-       setcontrast(gspca_dev);
-       setgain(gspca_dev);
-       setexposure(gspca_dev);
-       sethvflip(gspca_dev);
+       if (0 <= ret)
+               ret = setcontrast(gspca_dev);
+       if (0 <= ret)
+               ret = setgain(gspca_dev);
+       if (0 <= ret)
+               ret = setexposure(gspca_dev);
+       if (0 <= ret)
+               ret = sethvflip(gspca_dev);
 
        /* set correct resolution */
        switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
        case 2:                                 /* 160x120 pac7311 */
-               reg_w(gspca_dev, 0xff, 0x01);
-               reg_w(gspca_dev, 0x17, 0x20);
-               reg_w(gspca_dev, 0x87, 0x10);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0xff, 0x01);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x17, 0x20);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x87, 0x10);
                break;
        case 1:                                 /* 320x240 pac7311 */
-               reg_w(gspca_dev, 0xff, 0x01);
-               reg_w(gspca_dev, 0x17, 0x30);
-               reg_w(gspca_dev, 0x87, 0x11);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0xff, 0x01);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x17, 0x30);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x87, 0x11);
                break;
        case 0:                                 /* 640x480 */
-               reg_w(gspca_dev, 0xff, 0x01);
-               reg_w(gspca_dev, 0x17, 0x00);
-               reg_w(gspca_dev, 0x87, 0x12);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0xff, 0x01);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x17, 0x00);
+               if (0 <= ret)
+                       ret = reg_w(gspca_dev, 0x87, 0x12);
                break;
        }
 
        atomic_set(&sd->avg_lum, -1);
 
        /* start stream */
-       reg_w(gspca_dev, 0xff, 0x01);
-       reg_w(gspca_dev, 0x78, 0x05);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0xff, 0x01);
+       if (0 <= ret)
+               ret = reg_w(gspca_dev, 0x78, 0x05);
 
-       return 0;
+       return ret;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)