diff options
Diffstat (limited to 'drivers/media/usb/dvb-usb/cxusb.c')
| -rw-r--r-- | drivers/media/usb/dvb-usb/cxusb.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 3940bb0f9ef6..20e345d9fe8f 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c | |||
| @@ -43,6 +43,9 @@ | |||
| 43 | #include "lgs8gxx.h" | 43 | #include "lgs8gxx.h" |
| 44 | #include "atbm8830.h" | 44 | #include "atbm8830.h" |
| 45 | 45 | ||
| 46 | /* Max transfer size done by I2C transfer functions */ | ||
| 47 | #define MAX_XFER_SIZE 64 | ||
| 48 | |||
| 46 | /* debug */ | 49 | /* debug */ |
| 47 | static int dvb_usb_cxusb_debug; | 50 | static int dvb_usb_cxusb_debug; |
| 48 | module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); | 51 | module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); |
| @@ -57,7 +60,14 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d, | |||
| 57 | u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) | 60 | u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) |
| 58 | { | 61 | { |
| 59 | int wo = (rbuf == NULL || rlen == 0); /* write-only */ | 62 | int wo = (rbuf == NULL || rlen == 0); /* write-only */ |
| 60 | u8 sndbuf[1+wlen]; | 63 | u8 sndbuf[MAX_XFER_SIZE]; |
| 64 | |||
| 65 | if (1 + wlen > sizeof(sndbuf)) { | ||
| 66 | warn("i2c wr: len=%d is too big!\n", | ||
| 67 | wlen); | ||
| 68 | return -EOPNOTSUPP; | ||
| 69 | } | ||
| 70 | |||
| 61 | memset(sndbuf, 0, 1+wlen); | 71 | memset(sndbuf, 0, 1+wlen); |
| 62 | 72 | ||
| 63 | sndbuf[0] = cmd; | 73 | sndbuf[0] = cmd; |
| @@ -158,7 +168,13 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
| 158 | 168 | ||
| 159 | if (msg[i].flags & I2C_M_RD) { | 169 | if (msg[i].flags & I2C_M_RD) { |
| 160 | /* read only */ | 170 | /* read only */ |
| 161 | u8 obuf[3], ibuf[1+msg[i].len]; | 171 | u8 obuf[3], ibuf[MAX_XFER_SIZE]; |
| 172 | |||
| 173 | if (1 + msg[i].len > sizeof(ibuf)) { | ||
| 174 | warn("i2c rd: len=%d is too big!\n", | ||
| 175 | msg[i].len); | ||
| 176 | return -EOPNOTSUPP; | ||
| 177 | } | ||
| 162 | obuf[0] = 0; | 178 | obuf[0] = 0; |
| 163 | obuf[1] = msg[i].len; | 179 | obuf[1] = msg[i].len; |
| 164 | obuf[2] = msg[i].addr; | 180 | obuf[2] = msg[i].addr; |
| @@ -172,7 +188,18 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
| 172 | } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) && | 188 | } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) && |
| 173 | msg[i].addr == msg[i+1].addr) { | 189 | msg[i].addr == msg[i+1].addr) { |
| 174 | /* write to then read from same address */ | 190 | /* write to then read from same address */ |
| 175 | u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len]; | 191 | u8 obuf[MAX_XFER_SIZE], ibuf[MAX_XFER_SIZE]; |
| 192 | |||
| 193 | if (3 + msg[i].len > sizeof(obuf)) { | ||
| 194 | warn("i2c wr: len=%d is too big!\n", | ||
| 195 | msg[i].len); | ||
| 196 | return -EOPNOTSUPP; | ||
| 197 | } | ||
| 198 | if (1 + msg[i + 1].len > sizeof(ibuf)) { | ||
| 199 | warn("i2c rd: len=%d is too big!\n", | ||
| 200 | msg[i + 1].len); | ||
| 201 | return -EOPNOTSUPP; | ||
| 202 | } | ||
| 176 | obuf[0] = msg[i].len; | 203 | obuf[0] = msg[i].len; |
| 177 | obuf[1] = msg[i+1].len; | 204 | obuf[1] = msg[i+1].len; |
| 178 | obuf[2] = msg[i].addr; | 205 | obuf[2] = msg[i].addr; |
| @@ -191,7 +218,13 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
| 191 | i++; | 218 | i++; |
| 192 | } else { | 219 | } else { |
| 193 | /* write only */ | 220 | /* write only */ |
| 194 | u8 obuf[2+msg[i].len], ibuf; | 221 | u8 obuf[MAX_XFER_SIZE], ibuf; |
| 222 | |||
| 223 | if (2 + msg[i].len > sizeof(obuf)) { | ||
| 224 | warn("i2c wr: len=%d is too big!\n", | ||
| 225 | msg[i].len); | ||
| 226 | return -EOPNOTSUPP; | ||
| 227 | } | ||
| 195 | obuf[0] = msg[i].addr; | 228 | obuf[0] = msg[i].addr; |
| 196 | obuf[1] = msg[i].len; | 229 | obuf[1] = msg[i].len; |
| 197 | memcpy(&obuf[2], msg[i].buf, msg[i].len); | 230 | memcpy(&obuf[2], msg[i].buf, msg[i].len); |
