aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Grenie <olivier.grenie@dibcom.fr>2011-08-01 11:45:58 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-08-06 08:31:36 -0400
commitbff469f4167fdabfe15294f375577d7eadbaa1bb (patch)
tree2f89dde514f48ee94958408fbbe1db9c8d4741cf
parent79fcce3230b140f7675f8529ee53fe2f9644f902 (diff)
[media] dib0700: protect the dib0700 buffer access
This patch protects the common buffer access inside the dib0700 in order to manage concurrent access. This protection is done using mutex. Cc: Mauro Carvalho Chehab <mchehab@redhat.com> Cc: Florian Mickler <florian@mickler.org> Cc: stable@kernel.org Signed-off-by: Javier Marcet <javier@marcet.info> Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr> Signed-off-by: Patrick Boettcher <patrick.boettcher@dibcom.fr> [mchehab@redhat.com: dprint requires 3 arguments. Replaced by dib_info] Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c81
1 files changed, 72 insertions, 9 deletions
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 5eb91b4f8fd0..a224e94325b7 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -30,6 +30,11 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
30 struct dib0700_state *st = d->priv; 30 struct dib0700_state *st = d->priv;
31 int ret; 31 int ret;
32 32
33 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
34 deb_info("could not acquire lock");
35 return 0;
36 }
37
33 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), 38 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
34 REQUEST_GET_VERSION, 39 REQUEST_GET_VERSION,
35 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, 40 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
@@ -46,6 +51,7 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
46 if (fwtype != NULL) 51 if (fwtype != NULL)
47 *fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) | 52 *fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) |
48 (st->buf[14] << 8) | st->buf[15]; 53 (st->buf[14] << 8) | st->buf[15];
54 mutex_unlock(&d->usb_mutex);
49 return ret; 55 return ret;
50} 56}
51 57
@@ -108,7 +114,12 @@ int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen
108int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val) 114int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
109{ 115{
110 struct dib0700_state *st = d->priv; 116 struct dib0700_state *st = d->priv;
111 s16 ret; 117 int ret;
118
119 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
120 deb_info("could not acquire lock");
121 return 0;
122 }
112 123
113 st->buf[0] = REQUEST_SET_GPIO; 124 st->buf[0] = REQUEST_SET_GPIO;
114 st->buf[1] = gpio; 125 st->buf[1] = gpio;
@@ -116,6 +127,7 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
116 127
117 ret = dib0700_ctrl_wr(d, st->buf, 3); 128 ret = dib0700_ctrl_wr(d, st->buf, 3);
118 129
130 mutex_unlock(&d->usb_mutex);
119 return ret; 131 return ret;
120} 132}
121 133
@@ -125,6 +137,11 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
125 int ret; 137 int ret;
126 138
127 if (st->fw_version >= 0x10201) { 139 if (st->fw_version >= 0x10201) {
140 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
141 deb_info("could not acquire lock");
142 return 0;
143 }
144
128 st->buf[0] = REQUEST_SET_USB_XFER_LEN; 145 st->buf[0] = REQUEST_SET_USB_XFER_LEN;
129 st->buf[1] = (nb_ts_packets >> 8) & 0xff; 146 st->buf[1] = (nb_ts_packets >> 8) & 0xff;
130 st->buf[2] = nb_ts_packets & 0xff; 147 st->buf[2] = nb_ts_packets & 0xff;
@@ -132,6 +149,7 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
132 deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets); 149 deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
133 150
134 ret = dib0700_ctrl_wr(d, st->buf, 3); 151 ret = dib0700_ctrl_wr(d, st->buf, 3);
152 mutex_unlock(&d->usb_mutex);
135 } else { 153 } else {
136 deb_info("this firmware does not allow to change the USB xfer len\n"); 154 deb_info("this firmware does not allow to change the USB xfer len\n");
137 ret = -EIO; 155 ret = -EIO;
@@ -208,6 +226,10 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
208 226
209 } else { 227 } else {
210 /* Write request */ 228 /* Write request */
229 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
230 deb_info("could not acquire lock");
231 return 0;
232 }
211 st->buf[0] = REQUEST_NEW_I2C_WRITE; 233 st->buf[0] = REQUEST_NEW_I2C_WRITE;
212 st->buf[1] = msg[i].addr << 1; 234 st->buf[1] = msg[i].addr << 1;
213 st->buf[2] = (en_start << 7) | (en_stop << 6) | 235 st->buf[2] = (en_start << 7) | (en_stop << 6) |
@@ -227,6 +249,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
227 USB_TYPE_VENDOR | USB_DIR_OUT, 249 USB_TYPE_VENDOR | USB_DIR_OUT,
228 0, 0, st->buf, msg[i].len + 4, 250 0, 0, st->buf, msg[i].len + 4,
229 USB_CTRL_GET_TIMEOUT); 251 USB_CTRL_GET_TIMEOUT);
252 mutex_unlock(&d->usb_mutex);
230 if (result < 0) { 253 if (result < 0) {
231 deb_info("i2c write error (status = %d)\n", result); 254 deb_info("i2c write error (status = %d)\n", result);
232 break; 255 break;
@@ -249,6 +272,10 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
249 272
250 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 273 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
251 return -EAGAIN; 274 return -EAGAIN;
275 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
276 deb_info("could not acquire lock");
277 return 0;
278 }
252 279
253 for (i = 0; i < num; i++) { 280 for (i = 0; i < num; i++) {
254 /* fill in the address */ 281 /* fill in the address */
@@ -279,6 +306,7 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
279 break; 306 break;
280 } 307 }
281 } 308 }
309 mutex_unlock(&d->usb_mutex);
282 mutex_unlock(&d->i2c_mutex); 310 mutex_unlock(&d->i2c_mutex);
283 311
284 return i; 312 return i;
@@ -337,7 +365,12 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
337 u16 pll_loopdiv, u16 free_div, u16 dsuScaler) 365 u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
338{ 366{
339 struct dib0700_state *st = d->priv; 367 struct dib0700_state *st = d->priv;
340 s16 ret; 368 int ret;
369
370 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
371 deb_info("could not acquire lock");
372 return 0;
373 }
341 374
342 st->buf[0] = REQUEST_SET_CLOCK; 375 st->buf[0] = REQUEST_SET_CLOCK;
343 st->buf[1] = (en_pll << 7) | (pll_src << 6) | 376 st->buf[1] = (en_pll << 7) | (pll_src << 6) |
@@ -352,6 +385,7 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
352 st->buf[9] = dsuScaler & 0xff; /* LSB */ 385 st->buf[9] = dsuScaler & 0xff; /* LSB */
353 386
354 ret = dib0700_ctrl_wr(d, st->buf, 10); 387 ret = dib0700_ctrl_wr(d, st->buf, 10);
388 mutex_unlock(&d->usb_mutex);
355 389
356 return ret; 390 return ret;
357} 391}
@@ -360,10 +394,16 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
360{ 394{
361 struct dib0700_state *st = d->priv; 395 struct dib0700_state *st = d->priv;
362 u16 divider; 396 u16 divider;
397 int ret;
363 398
364 if (scl_kHz == 0) 399 if (scl_kHz == 0)
365 return -EINVAL; 400 return -EINVAL;
366 401
402 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
403 deb_info("could not acquire lock");
404 return 0;
405 }
406
367 st->buf[0] = REQUEST_SET_I2C_PARAM; 407 st->buf[0] = REQUEST_SET_I2C_PARAM;
368 divider = (u16) (30000 / scl_kHz); 408 divider = (u16) (30000 / scl_kHz);
369 st->buf[1] = 0; 409 st->buf[1] = 0;
@@ -379,7 +419,11 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
379 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", 419 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
380 (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) | 420 (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
381 st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz); 421 st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
382 return dib0700_ctrl_wr(d, st->buf, 8); 422
423 ret = dib0700_ctrl_wr(d, st->buf, 8);
424 mutex_unlock(&d->usb_mutex);
425
426 return ret;
383} 427}
384 428
385 429
@@ -515,6 +559,11 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
515 } 559 }
516 } 560 }
517 561
562 if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
563 deb_info("could not acquire lock");
564 return 0;
565 }
566
518 st->buf[0] = REQUEST_ENABLE_VIDEO; 567 st->buf[0] = REQUEST_ENABLE_VIDEO;
519 /* this bit gives a kind of command, 568 /* this bit gives a kind of command,
520 * rather than enabling something or not */ 569 * rather than enabling something or not */
@@ -548,7 +597,10 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
548 597
549 deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]); 598 deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
550 599
551 return dib0700_ctrl_wr(adap->dev, st->buf, 4); 600 ret = dib0700_ctrl_wr(adap->dev, st->buf, 4);
601 mutex_unlock(&adap->dev->usb_mutex);
602
603 return ret;
552} 604}
553 605
554int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type) 606int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
@@ -557,6 +609,11 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
557 struct dib0700_state *st = d->priv; 609 struct dib0700_state *st = d->priv;
558 int new_proto, ret; 610 int new_proto, ret;
559 611
612 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
613 deb_info("could not acquire lock");
614 return 0;
615 }
616
560 st->buf[0] = REQUEST_SET_RC; 617 st->buf[0] = REQUEST_SET_RC;
561 st->buf[1] = 0; 618 st->buf[1] = 0;
562 st->buf[2] = 0; 619 st->buf[2] = 0;
@@ -567,23 +624,29 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
567 else if (rc_type == RC_TYPE_NEC) 624 else if (rc_type == RC_TYPE_NEC)
568 new_proto = 0; 625 new_proto = 0;
569 else if (rc_type == RC_TYPE_RC6) { 626 else if (rc_type == RC_TYPE_RC6) {
570 if (st->fw_version < 0x10200) 627 if (st->fw_version < 0x10200) {
571 return -EINVAL; 628 ret = -EINVAL;
629 goto out;
630 }
572 631
573 new_proto = 2; 632 new_proto = 2;
574 } else 633 } else {
575 return -EINVAL; 634 ret = -EINVAL;
635 goto out;
636 }
576 637
577 st->buf[1] = new_proto; 638 st->buf[1] = new_proto;
578 639
579 ret = dib0700_ctrl_wr(d, st->buf, 3); 640 ret = dib0700_ctrl_wr(d, st->buf, 3);
580 if (ret < 0) { 641 if (ret < 0) {
581 err("ir protocol setup failed"); 642 err("ir protocol setup failed");
582 return ret; 643 goto out;
583 } 644 }
584 645
585 d->props.rc.core.protocol = rc_type; 646 d->props.rc.core.protocol = rc_type;
586 647
648out:
649 mutex_unlock(&d->usb_mutex);
587 return ret; 650 return ret;
588} 651}
589 652