Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / drivers / media / dvb / dvb-usb / dw2102.c
index 52f03f9..e0b3d37 100644 (file)
@@ -234,6 +234,20 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
 
        switch (num) {
        case 2:
+               if (msg[0].len != 1) {
+                       warn("i2c rd: len=%d is not 1!\n",
+                            msg[0].len);
+                       num = -EOPNOTSUPP;
+                       break;
+               }
+
+               if (2 + msg[1].len > sizeof(buf6)) {
+                       warn("i2c rd: len=%d is too big!\n",
+                            msg[1].len);
+                       num = -EOPNOTSUPP;
+                       break;
+               }
+
                /* read si2109 register by number */
                buf6[0] = msg[0].addr << 1;
                buf6[1] = msg[0].len;
@@ -249,6 +263,13 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
        case 1:
                switch (msg[0].addr) {
                case 0x68:
+                       if (2 + msg[0].len > sizeof(buf6)) {
+                               warn("i2c wr: len=%d is too big!\n",
+                                    msg[0].len);
+                               num = -EOPNOTSUPP;
+                               break;
+                       }
+
                        /* write to si2109 register */
                        buf6[0] = msg[0].addr << 1;
                        buf6[1] = msg[0].len;
@@ -292,10 +313,18 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
                /* first write first register number */
                u8 ibuf[MAX_XFER_SIZE], obuf[3];
 
+               if (2 + msg[0].len != sizeof(obuf)) {
+                       warn("i2c rd: len=%d is not 1!\n",
+                            msg[0].len);
+                       ret = -EOPNOTSUPP;
+                       goto unlock;
+               }
+
                if (2 + msg[1].len > sizeof(ibuf)) {
                        warn("i2c rd: len=%d is too big!\n",
                             msg[1].len);
-                       return -EOPNOTSUPP;
+                       ret = -EOPNOTSUPP;
+                       goto unlock;
                }
 
                obuf[0] = msg[0].addr << 1;
@@ -319,7 +348,8 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
                        if (2 + msg[0].len > sizeof(obuf)) {
                                warn("i2c wr: len=%d is too big!\n",
                                     msg[1].len);
-                               return -EOPNOTSUPP;
+                               ret = -EOPNOTSUPP;
+                               goto unlock;
                        }
 
                        obuf[0] = msg[0].addr << 1;
@@ -336,7 +366,8 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
                        if (2 + msg[0].len > sizeof(obuf)) {
                                warn("i2c wr: len=%d is too big!\n",
                                     msg[1].len);
-                               return -EOPNOTSUPP;
+                               ret = -EOPNOTSUPP;
+                               goto unlock;
                        }
 
                        obuf[0] = msg[0].addr << 1;
@@ -365,9 +396,11 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
 
                break;
        }
+       ret = num;
 
+unlock:
        mutex_unlock(&d->i2c_mutex);
-       return num;
+       return ret;
 }
 
 static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
@@ -410,7 +443,8 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
                                if (2 + msg[j].len > sizeof(ibuf)) {
                                        warn("i2c rd: len=%d is too big!\n",
                                             msg[j].len);
-                                       return -EOPNOTSUPP;
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
                                }
 
                                ret = dw210x_op_rw(d->udev, 0xc3,
@@ -446,7 +480,8 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
                                if (2 + msg[j].len > sizeof(obuf)) {
                                        warn("i2c wr: len=%d is too big!\n",
                                             msg[j].len);
-                                       return -EOPNOTSUPP;
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
                                }
 
                                obuf[0] = msg[j].addr << 1;
@@ -461,9 +496,11 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
                }
 
        }
+       ret = num;
 
+unlock:
        mutex_unlock(&d->i2c_mutex);
-       return num;
+       return ret;
 }
 
 static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -483,10 +520,17 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                /* first write first register number */
                u8 ibuf[MAX_XFER_SIZE], obuf[3];
 
+               if (2 + msg[0].len != sizeof(obuf)) {
+                       warn("i2c rd: len=%d is not 1!\n",
+                            msg[0].len);
+                       ret = -EOPNOTSUPP;
+                       goto unlock;
+               }
                if (2 + msg[1].len > sizeof(ibuf)) {
                        warn("i2c rd: len=%d is too big!\n",
                             msg[1].len);
-                       return -EOPNOTSUPP;
+                       ret = -EOPNOTSUPP;
+                       goto unlock;
                }
                obuf[0] = msg[0].addr << 1;
                obuf[1] = msg[0].len;
@@ -510,7 +554,8 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                        if (2 + msg[0].len > sizeof(obuf)) {
                                warn("i2c wr: len=%d is too big!\n",
                                     msg[0].len);
-                               return -EOPNOTSUPP;
+                               ret = -EOPNOTSUPP;
+                               goto unlock;
                        }
                        obuf[0] = msg[0].addr << 1;
                        obuf[1] = msg[0].len;
@@ -536,9 +581,11 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                                msg[i].flags == 0 ? ">>>" : "<<<");
                debug_dump(msg[i].buf, msg[i].len, deb_xfer);
        }
+       ret = num;
 
+unlock:
        mutex_unlock(&d->i2c_mutex);
-       return num;
+       return ret;
 }
 
 static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -599,7 +646,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                                if (msg[j].len > sizeof(ibuf)) {
                                        warn("i2c rd: len=%d is too big!\n",
                                             msg[j].len);
-                                       return -EOPNOTSUPP;
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
                                }
 
                                ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
@@ -633,7 +681,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                                if (2 + msg[j].len > sizeof(obuf)) {
                                        warn("i2c wr: len=%d is too big!\n",
                                             msg[j].len);
-                                       return -EOPNOTSUPP;
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
                                }
 
                                obuf[0] = msg[j + 1].len;
@@ -652,7 +701,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                                if (2 + msg[j].len > sizeof(obuf)) {
                                        warn("i2c wr: len=%d is too big!\n",
                                             msg[j].len);
-                                       return -EOPNOTSUPP;
+                                       ret = -EOPNOTSUPP;
+                                       goto unlock;
                                }
                                obuf[0] = msg[j].len + 1;
                                obuf[1] = (msg[j].addr << 1);
@@ -666,9 +716,11 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                }
                }
        }
+       ret = num;
 
+unlock:
        mutex_unlock(&d->i2c_mutex);
-       return num;
+       return ret;
 }
 
 static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -700,6 +752,13 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                        msg[0].buf[0] = ibuf[1];
                        break;
                default:
+                       if (3 + msg[0].len > sizeof(obuf)) {
+                               warn("i2c wr: len=%d is too big!\n",
+                                    msg[0].len);
+                               num = -EOPNOTSUPP;
+                               break;
+                       }
+
                        /* always i2c write*/
                        obuf[0] = 0x08;
                        obuf[1] = msg[0].addr;
@@ -715,6 +774,19 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                break;
        case 2:
                /* always i2c read */
+               if (4 + msg[0].len > sizeof(obuf)) {
+                       warn("i2c rd: len=%d is too big!\n",
+                            msg[0].len);
+                       num = -EOPNOTSUPP;
+                       break;
+               }
+               if (1 + msg[1].len > sizeof(obuf)) {
+                       warn("i2c rd: len=%d is too big!\n",
+                            msg[1].len);
+                       num = -EOPNOTSUPP;
+                       break;
+               }
+
                obuf[0] = 0x09;
                obuf[1] = msg[0].len;
                obuf[2] = msg[1].len;