diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2013-11-22 02:55:43 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-03-31 12:58:12 -0400 |
commit | 60b35930067dfc0ef4d82b2653a9221b247ce5f1 (patch) | |
tree | 141ede33506d420531a2fb3b9f4602937095de16 | |
parent | a1c10a94ff3c76b83a9e2899659ff27877fce23f (diff) |
media: cxusb: unlock on error in cxusb_i2c_xfer()
commit 1cdbcc5db4e6d51ce9bb1313195167cada9aa6e9 upstream.
We recently introduced some new error paths which are missing their
unlocks.
Fixes: 64f7ef8afbf8 ('[media] cxusb: Don't use dynamic static allocation')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/media/usb/dvb-usb/cxusb.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 20e345d9fe8f..a1c641e18362 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c | |||
@@ -149,6 +149,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
149 | int num) | 149 | int num) |
150 | { | 150 | { |
151 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 151 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
152 | int ret; | ||
152 | int i; | 153 | int i; |
153 | 154 | ||
154 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 155 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
@@ -173,7 +174,8 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
173 | if (1 + msg[i].len > sizeof(ibuf)) { | 174 | if (1 + msg[i].len > sizeof(ibuf)) { |
174 | warn("i2c rd: len=%d is too big!\n", | 175 | warn("i2c rd: len=%d is too big!\n", |
175 | msg[i].len); | 176 | msg[i].len); |
176 | return -EOPNOTSUPP; | 177 | ret = -EOPNOTSUPP; |
178 | goto unlock; | ||
177 | } | 179 | } |
178 | obuf[0] = 0; | 180 | obuf[0] = 0; |
179 | obuf[1] = msg[i].len; | 181 | obuf[1] = msg[i].len; |
@@ -193,12 +195,14 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
193 | if (3 + msg[i].len > sizeof(obuf)) { | 195 | if (3 + msg[i].len > sizeof(obuf)) { |
194 | warn("i2c wr: len=%d is too big!\n", | 196 | warn("i2c wr: len=%d is too big!\n", |
195 | msg[i].len); | 197 | msg[i].len); |
196 | return -EOPNOTSUPP; | 198 | ret = -EOPNOTSUPP; |
199 | goto unlock; | ||
197 | } | 200 | } |
198 | if (1 + msg[i + 1].len > sizeof(ibuf)) { | 201 | if (1 + msg[i + 1].len > sizeof(ibuf)) { |
199 | warn("i2c rd: len=%d is too big!\n", | 202 | warn("i2c rd: len=%d is too big!\n", |
200 | msg[i + 1].len); | 203 | msg[i + 1].len); |
201 | return -EOPNOTSUPP; | 204 | ret = -EOPNOTSUPP; |
205 | goto unlock; | ||
202 | } | 206 | } |
203 | obuf[0] = msg[i].len; | 207 | obuf[0] = msg[i].len; |
204 | obuf[1] = msg[i+1].len; | 208 | obuf[1] = msg[i+1].len; |
@@ -223,7 +227,8 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
223 | if (2 + msg[i].len > sizeof(obuf)) { | 227 | if (2 + msg[i].len > sizeof(obuf)) { |
224 | warn("i2c wr: len=%d is too big!\n", | 228 | warn("i2c wr: len=%d is too big!\n", |
225 | msg[i].len); | 229 | msg[i].len); |
226 | return -EOPNOTSUPP; | 230 | ret = -EOPNOTSUPP; |
231 | goto unlock; | ||
227 | } | 232 | } |
228 | obuf[0] = msg[i].addr; | 233 | obuf[0] = msg[i].addr; |
229 | obuf[1] = msg[i].len; | 234 | obuf[1] = msg[i].len; |
@@ -237,8 +242,14 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
237 | } | 242 | } |
238 | } | 243 | } |
239 | 244 | ||
245 | if (i == num) | ||
246 | ret = num; | ||
247 | else | ||
248 | ret = -EREMOTEIO; | ||
249 | |||
250 | unlock: | ||
240 | mutex_unlock(&d->i2c_mutex); | 251 | mutex_unlock(&d->i2c_mutex); |
241 | return i == num ? num : -EREMOTEIO; | 252 | return ret; |
242 | } | 253 | } |
243 | 254 | ||
244 | static u32 cxusb_i2c_func(struct i2c_adapter *adapter) | 255 | static u32 cxusb_i2c_func(struct i2c_adapter *adapter) |