updated on Fri Jan 13 04:01:25 UTC 2012
[aur-mirror.git] / linux-vserver / dib0700-fix.patch
blobcd7bc9cb3afc87aea52e3c3caae6d3d850b406ec
1 commit 198c545cd7306dc90aaae1d61e64175e70a70dc8
2 Author: Patrick Boettcher <Patrick.Boettcher@dibcom.fr>
3 Date: Wed Aug 3 17:08:21 2011 +0200
5 [media] DiBcom: protect the I2C bufer access
7 This patch protect the I2C buffer access in order to manage concurrent
8 access. This protection is done using mutex.
9 Furthermore, for the dib9000, if a pid filtering command is
10 received during the tuning, this pid filtering command is delayed to
11 avoid any concurrent access issue.
13 Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
14 Cc: Florian Mickler <florian@mickler.org>
15 Cc: stable@kernel.org
17 Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr>
18 Signed-off-by: Patrick Boettcher <Patrick.Boettcher@dibcom.fr>
20 diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
21 index 1d47d4d..dc1cb17 100644
22 --- a/drivers/media/dvb/frontends/dib0070.c
23 +++ b/drivers/media/dvb/frontends/dib0070.c
24 @@ -27,6 +27,7 @@
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
27 #include <linux/i2c.h>
28 +#include <linux/mutex.h>
30 #include "dvb_frontend.h"
32 @@ -78,10 +79,18 @@ struct dib0070_state {
33 struct i2c_msg msg[2];
34 u8 i2c_write_buffer[3];
35 u8 i2c_read_buffer[2];
36 + struct mutex i2c_buffer_lock;
39 -static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
40 +static u16 dib0070_read_reg(struct dib0070_state *state, u8 reg)
42 + u16 ret;
44 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
45 + dprintk("could not acquire lock");
46 + return 0;
47 + }
49 state->i2c_write_buffer[0] = reg;
51 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
52 @@ -96,13 +105,23 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
54 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
55 printk(KERN_WARNING "DiB0070 I2C read failed\n");
56 - return 0;
57 - }
58 - return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
59 + ret = 0;
60 + } else
61 + ret = (state->i2c_read_buffer[0] << 8)
62 + | state->i2c_read_buffer[1];
64 + mutex_unlock(&state->i2c_buffer_lock);
65 + return ret;
68 static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
70 + int ret;
72 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
73 + dprintk("could not acquire lock");
74 + return -EINVAL;
75 + }
76 state->i2c_write_buffer[0] = reg;
77 state->i2c_write_buffer[1] = val >> 8;
78 state->i2c_write_buffer[2] = val & 0xff;
79 @@ -115,9 +134,12 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
81 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
82 printk(KERN_WARNING "DiB0070 I2C write failed\n");
83 - return -EREMOTEIO;
84 - }
85 - return 0;
86 + ret = -EREMOTEIO;
87 + } else
88 + ret = 0;
90 + mutex_unlock(&state->i2c_buffer_lock);
91 + return ret;
94 #define HARD_RESET(state) do { \
95 @@ -734,6 +756,7 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
96 state->cfg = cfg;
97 state->i2c = i2c;
98 state->fe = fe;
99 + mutex_init(&state->i2c_buffer_lock);
100 fe->tuner_priv = state;
102 if (dib0070_reset(fe) != 0)
103 diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
104 index c9c935a..b174d1c 100644
105 --- a/drivers/media/dvb/frontends/dib0090.c
106 +++ b/drivers/media/dvb/frontends/dib0090.c
107 @@ -27,6 +27,7 @@
108 #include <linux/kernel.h>
109 #include <linux/slab.h>
110 #include <linux/i2c.h>
111 +#include <linux/mutex.h>
113 #include "dvb_frontend.h"
115 @@ -196,6 +197,7 @@ struct dib0090_state {
116 struct i2c_msg msg[2];
117 u8 i2c_write_buffer[3];
118 u8 i2c_read_buffer[2];
119 + struct mutex i2c_buffer_lock;
122 struct dib0090_fw_state {
123 @@ -208,10 +210,18 @@ struct dib0090_fw_state {
124 struct i2c_msg msg;
125 u8 i2c_write_buffer[2];
126 u8 i2c_read_buffer[2];
127 + struct mutex i2c_buffer_lock;
130 static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
132 + u16 ret;
134 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
135 + dprintk("could not acquire lock");
136 + return 0;
139 state->i2c_write_buffer[0] = reg;
141 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
142 @@ -226,14 +236,24 @@ static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
144 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
145 printk(KERN_WARNING "DiB0090 I2C read failed\n");
146 - return 0;
148 + ret = 0;
149 + } else
150 + ret = (state->i2c_read_buffer[0] << 8)
151 + | state->i2c_read_buffer[1];
153 - return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
154 + mutex_unlock(&state->i2c_buffer_lock);
155 + return ret;
158 static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
160 + int ret;
162 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
163 + dprintk("could not acquire lock");
164 + return -EINVAL;
167 state->i2c_write_buffer[0] = reg & 0xff;
168 state->i2c_write_buffer[1] = val >> 8;
169 state->i2c_write_buffer[2] = val & 0xff;
170 @@ -246,13 +266,23 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
172 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
173 printk(KERN_WARNING "DiB0090 I2C write failed\n");
174 - return -EREMOTEIO;
176 - return 0;
177 + ret = -EREMOTEIO;
178 + } else
179 + ret = 0;
181 + mutex_unlock(&state->i2c_buffer_lock);
182 + return ret;
185 static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
187 + u16 ret;
189 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
190 + dprintk("could not acquire lock");
191 + return 0;
194 state->i2c_write_buffer[0] = reg;
196 memset(&state->msg, 0, sizeof(struct i2c_msg));
197 @@ -262,13 +292,24 @@ static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
198 state->msg.len = 2;
199 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
200 printk(KERN_WARNING "DiB0090 I2C read failed\n");
201 - return 0;
203 - return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
204 + ret = 0;
205 + } else
206 + ret = (state->i2c_read_buffer[0] << 8)
207 + | state->i2c_read_buffer[1];
209 + mutex_unlock(&state->i2c_buffer_lock);
210 + return ret;
213 static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
215 + int ret;
217 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
218 + dprintk("could not acquire lock");
219 + return -EINVAL;
222 state->i2c_write_buffer[0] = val >> 8;
223 state->i2c_write_buffer[1] = val & 0xff;
225 @@ -279,9 +320,12 @@ static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
226 state->msg.len = 2;
227 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
228 printk(KERN_WARNING "DiB0090 I2C write failed\n");
229 - return -EREMOTEIO;
231 - return 0;
232 + ret = -EREMOTEIO;
233 + } else
234 + ret = 0;
236 + mutex_unlock(&state->i2c_buffer_lock);
237 + return ret;
240 #define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0)
241 @@ -2440,6 +2484,7 @@ struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapte
242 st->config = config;
243 st->i2c = i2c;
244 st->fe = fe;
245 + mutex_init(&st->i2c_buffer_lock);
246 fe->tuner_priv = st;
248 if (config->wbd == NULL)
249 @@ -2471,6 +2516,7 @@ struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_ada
250 st->config = config;
251 st->i2c = i2c;
252 st->fe = fe;
253 + mutex_init(&st->i2c_buffer_lock);
254 fe->tuner_priv = st;
256 if (dib0090_fw_reset_digital(fe, st->config) != 0)
257 diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
258 index 79cb1c2..dbb76d7 100644
259 --- a/drivers/media/dvb/frontends/dib7000m.c
260 +++ b/drivers/media/dvb/frontends/dib7000m.c
261 @@ -11,6 +11,7 @@
262 #include <linux/kernel.h>
263 #include <linux/slab.h>
264 #include <linux/i2c.h>
265 +#include <linux/mutex.h>
267 #include "dvb_frontend.h"
269 @@ -55,6 +56,7 @@ struct dib7000m_state {
270 struct i2c_msg msg[2];
271 u8 i2c_write_buffer[4];
272 u8 i2c_read_buffer[2];
273 + struct mutex i2c_buffer_lock;
276 enum dib7000m_power_mode {
277 @@ -69,6 +71,13 @@ enum dib7000m_power_mode {
279 static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
281 + u16 ret;
283 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
284 + dprintk("could not acquire lock");
285 + return 0;
288 state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
289 state->i2c_write_buffer[1] = reg & 0xff;
291 @@ -85,11 +94,21 @@ static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
292 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
293 dprintk("i2c read error on %d",reg);
295 - return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
296 + ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
297 + mutex_unlock(&state->i2c_buffer_lock);
299 + return ret;
302 static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
304 + int ret;
306 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
307 + dprintk("could not acquire lock");
308 + return -EINVAL;
311 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
312 state->i2c_write_buffer[1] = reg & 0xff;
313 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
314 @@ -101,7 +120,10 @@ static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
315 state->msg[0].buf = state->i2c_write_buffer;
316 state->msg[0].len = 4;
318 - return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
319 + ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
320 + -EREMOTEIO : 0);
321 + mutex_unlock(&state->i2c_buffer_lock);
322 + return ret;
324 static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
326 @@ -1385,6 +1407,7 @@ struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
327 demod = &st->demod;
328 demod->demodulator_priv = st;
329 memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
330 + mutex_init(&st->i2c_buffer_lock);
332 st->timf_default = cfg->bw->timf;
334 diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
335 index 0c9f40c..292bc19 100644
336 --- a/drivers/media/dvb/frontends/dib7000p.c
337 +++ b/drivers/media/dvb/frontends/dib7000p.c
338 @@ -10,6 +10,7 @@
339 #include <linux/kernel.h>
340 #include <linux/slab.h>
341 #include <linux/i2c.h>
342 +#include <linux/mutex.h>
344 #include "dvb_math.h"
345 #include "dvb_frontend.h"
346 @@ -68,6 +69,7 @@ struct dib7000p_state {
347 struct i2c_msg msg[2];
348 u8 i2c_write_buffer[4];
349 u8 i2c_read_buffer[2];
350 + struct mutex i2c_buffer_lock;
353 enum dib7000p_power_mode {
354 @@ -81,6 +83,13 @@ static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
356 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
358 + u16 ret;
360 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
361 + dprintk("could not acquire lock");
362 + return 0;
365 state->i2c_write_buffer[0] = reg >> 8;
366 state->i2c_write_buffer[1] = reg & 0xff;
368 @@ -97,11 +106,20 @@ static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
369 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
370 dprintk("i2c read error on %d", reg);
372 - return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
373 + ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
374 + mutex_unlock(&state->i2c_buffer_lock);
375 + return ret;
378 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
380 + int ret;
382 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
383 + dprintk("could not acquire lock");
384 + return -EINVAL;
387 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
388 state->i2c_write_buffer[1] = reg & 0xff;
389 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
390 @@ -113,7 +131,10 @@ static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
391 state->msg[0].buf = state->i2c_write_buffer;
392 state->msg[0].len = 4;
394 - return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
395 + ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
396 + -EREMOTEIO : 0);
397 + mutex_unlock(&state->i2c_buffer_lock);
398 + return ret;
401 static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
402 @@ -1646,6 +1667,7 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
403 return -ENOMEM;
405 dpst->i2c_adap = i2c;
406 + mutex_init(&dpst->i2c_buffer_lock);
408 for (k = no_of_demods - 1; k >= 0; k--) {
409 dpst->cfg = cfg[k];
410 @@ -2324,6 +2346,7 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
411 demod = &st->demod;
412 demod->demodulator_priv = st;
413 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
414 + mutex_init(&st->i2c_buffer_lock);
416 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
418 @@ -2333,8 +2356,9 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
419 st->version = dib7000p_read_word(st, 897);
421 /* FIXME: make sure the dev.parent field is initialized, or else
422 - request_firmware() will hit an OOPS (this should be moved somewhere
423 - more common) */
424 + request_firmware() will hit an OOPS (this should be moved somewhere
425 + more common) */
426 + st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
428 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
430 diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
431 index 7d2ea11..fe284d5 100644
432 --- a/drivers/media/dvb/frontends/dib8000.c
433 +++ b/drivers/media/dvb/frontends/dib8000.c
434 @@ -10,6 +10,8 @@
435 #include <linux/kernel.h>
436 #include <linux/slab.h>
437 #include <linux/i2c.h>
438 +#include <linux/mutex.h>
440 #include "dvb_math.h"
442 #include "dvb_frontend.h"
443 @@ -37,6 +39,7 @@ struct i2c_device {
444 u8 addr;
445 u8 *i2c_write_buffer;
446 u8 *i2c_read_buffer;
447 + struct mutex *i2c_buffer_lock;
450 struct dib8000_state {
451 @@ -77,6 +80,7 @@ struct dib8000_state {
452 struct i2c_msg msg[2];
453 u8 i2c_write_buffer[4];
454 u8 i2c_read_buffer[2];
455 + struct mutex i2c_buffer_lock;
458 enum dib8000_power_mode {
459 @@ -86,24 +90,39 @@ enum dib8000_power_mode {
461 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
463 + u16 ret;
464 struct i2c_msg msg[2] = {
465 - {.addr = i2c->addr >> 1, .flags = 0,
466 - .buf = i2c->i2c_write_buffer, .len = 2},
467 - {.addr = i2c->addr >> 1, .flags = I2C_M_RD,
468 - .buf = i2c->i2c_read_buffer, .len = 2},
469 + {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
470 + {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
473 + if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
474 + dprintk("could not acquire lock");
475 + return 0;
478 + msg[0].buf = i2c->i2c_write_buffer;
479 msg[0].buf[0] = reg >> 8;
480 msg[0].buf[1] = reg & 0xff;
481 + msg[1].buf = i2c->i2c_read_buffer;
483 if (i2c_transfer(i2c->adap, msg, 2) != 2)
484 dprintk("i2c read error on %d", reg);
486 - return (msg[1].buf[0] << 8) | msg[1].buf[1];
487 + ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
488 + mutex_unlock(i2c->i2c_buffer_lock);
489 + return ret;
492 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
494 + u16 ret;
496 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
497 + dprintk("could not acquire lock");
498 + return 0;
501 state->i2c_write_buffer[0] = reg >> 8;
502 state->i2c_write_buffer[1] = reg & 0xff;
504 @@ -120,7 +139,10 @@ static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
505 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
506 dprintk("i2c read error on %d", reg);
508 - return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
509 + ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
510 + mutex_unlock(&state->i2c_buffer_lock);
512 + return ret;
515 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
516 @@ -135,22 +157,35 @@ static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
518 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
520 - struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0,
521 - .buf = i2c->i2c_write_buffer, .len = 4};
522 + struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
523 int ret = 0;
525 + if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
526 + dprintk("could not acquire lock");
527 + return -EINVAL;
530 + msg.buf = i2c->i2c_write_buffer;
531 msg.buf[0] = (reg >> 8) & 0xff;
532 msg.buf[1] = reg & 0xff;
533 msg.buf[2] = (val >> 8) & 0xff;
534 msg.buf[3] = val & 0xff;
536 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
537 + mutex_unlock(i2c->i2c_buffer_lock);
539 return ret;
542 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
544 + int ret;
546 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
547 + dprintk("could not acquire lock");
548 + return -EINVAL;
551 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
552 state->i2c_write_buffer[1] = reg & 0xff;
553 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
554 @@ -162,7 +197,11 @@ static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
555 state->msg[0].buf = state->i2c_write_buffer;
556 state->msg[0].len = 4;
558 - return i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
559 + ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
560 + -EREMOTEIO : 0);
561 + mutex_unlock(&state->i2c_buffer_lock);
563 + return ret;
566 static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
567 @@ -2434,8 +2473,15 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau
568 if (!client.i2c_read_buffer) {
569 dprintk("%s: not enough memory", __func__);
570 ret = -ENOMEM;
571 - goto error_memory;
572 + goto error_memory_read;
574 + client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
575 + if (!client.i2c_buffer_lock) {
576 + dprintk("%s: not enough memory", __func__);
577 + ret = -ENOMEM;
578 + goto error_memory_lock;
580 + mutex_init(client.i2c_buffer_lock);
582 for (k = no_of_demods - 1; k >= 0; k--) {
583 /* designated i2c address */
584 @@ -2476,8 +2522,10 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau
587 error:
588 + kfree(client.i2c_buffer_lock);
589 +error_memory_lock:
590 kfree(client.i2c_read_buffer);
591 -error_memory:
592 +error_memory_read:
593 kfree(client.i2c_write_buffer);
595 return ret;
596 @@ -2581,6 +2629,8 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s
597 state->i2c.addr = i2c_addr;
598 state->i2c.i2c_write_buffer = state->i2c_write_buffer;
599 state->i2c.i2c_read_buffer = state->i2c_read_buffer;
600 + mutex_init(&state->i2c_buffer_lock);
601 + state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
602 state->gpio_val = cfg->gpio_val;
603 state->gpio_dir = cfg->gpio_dir;
605 diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
606 index a085588..b931074 100644
607 --- a/drivers/media/dvb/frontends/dib9000.c
608 +++ b/drivers/media/dvb/frontends/dib9000.c
609 @@ -38,6 +38,15 @@ struct i2c_device {
610 #define DibInitLock(lock) mutex_init(lock)
611 #define DibFreeLock(lock)
613 +struct dib9000_pid_ctrl {
614 +#define DIB9000_PID_FILTER_CTRL 0
615 +#define DIB9000_PID_FILTER 1
616 + u8 cmd;
617 + u8 id;
618 + u16 pid;
619 + u8 onoff;
622 struct dib9000_state {
623 struct i2c_device i2c;
625 @@ -99,6 +108,10 @@ struct dib9000_state {
626 struct i2c_msg msg[2];
627 u8 i2c_write_buffer[255];
628 u8 i2c_read_buffer[255];
629 + DIB_LOCK demod_lock;
630 + u8 get_frontend_internal;
631 + struct dib9000_pid_ctrl pid_ctrl[10];
632 + s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */
635 static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
636 @@ -1743,19 +1756,56 @@ EXPORT_SYMBOL(dib9000_set_gpio);
637 int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
639 struct dib9000_state *state = fe->demodulator_priv;
640 - u16 val = dib9000_read_word(state, 294 + 1) & 0xffef;
641 + u16 val;
642 + int ret;
644 + if ((state->pid_ctrl_index != -2) && (state->pid_ctrl_index < 9)) {
645 + /* postpone the pid filtering cmd */
646 + dprintk("pid filter cmd postpone");
647 + state->pid_ctrl_index++;
648 + state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER_CTRL;
649 + state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
650 + return 0;
653 + DibAcquireLock(&state->demod_lock);
655 + val = dib9000_read_word(state, 294 + 1) & 0xffef;
656 val |= (onoff & 0x1) << 4;
658 dprintk("PID filter enabled %d", onoff);
659 - return dib9000_write_word(state, 294 + 1, val);
660 + ret = dib9000_write_word(state, 294 + 1, val);
661 + DibReleaseLock(&state->demod_lock);
662 + return ret;
665 EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl);
667 int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
669 struct dib9000_state *state = fe->demodulator_priv;
670 + int ret;
672 + if (state->pid_ctrl_index != -2) {
673 + /* postpone the pid filtering cmd */
674 + dprintk("pid filter postpone");
675 + if (state->pid_ctrl_index < 9) {
676 + state->pid_ctrl_index++;
677 + state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER;
678 + state->pid_ctrl[state->pid_ctrl_index].id = id;
679 + state->pid_ctrl[state->pid_ctrl_index].pid = pid;
680 + state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
681 + } else
682 + dprintk("can not add any more pid ctrl cmd");
683 + return 0;
686 + DibAcquireLock(&state->demod_lock);
687 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
688 - return dib9000_write_word(state, 300 + 1 + id, onoff ? (1 << 13) | pid : 0);
689 + ret = dib9000_write_word(state, 300 + 1 + id,
690 + onoff ? (1 << 13) | pid : 0);
691 + DibReleaseLock(&state->demod_lock);
692 + return ret;
694 EXPORT_SYMBOL(dib9000_fw_pid_filter);
696 @@ -1778,6 +1828,7 @@ static void dib9000_release(struct dvb_frontend *demod)
697 DibFreeLock(&state->platform.risc.mbx_lock);
698 DibFreeLock(&state->platform.risc.mem_lock);
699 DibFreeLock(&state->platform.risc.mem_mbx_lock);
700 + DibFreeLock(&state->demod_lock);
701 dibx000_exit_i2c_master(&st->i2c_master);
703 i2c_del_adapter(&st->tuner_adap);
704 @@ -1795,14 +1846,19 @@ static int dib9000_sleep(struct dvb_frontend *fe)
706 struct dib9000_state *state = fe->demodulator_priv;
707 u8 index_frontend;
708 - int ret;
709 + int ret = 0;
711 + DibAcquireLock(&state->demod_lock);
712 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
713 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
714 if (ret < 0)
715 - return ret;
716 + goto error;
718 - return dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
719 + ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
721 +error:
722 + DibReleaseLock(&state->demod_lock);
723 + return ret;
726 static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
727 @@ -1816,7 +1872,10 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
728 struct dib9000_state *state = fe->demodulator_priv;
729 u8 index_frontend, sub_index_frontend;
730 fe_status_t stat;
731 - int ret;
732 + int ret = 0;
734 + if (state->get_frontend_internal == 0)
735 + DibAcquireLock(&state->demod_lock);
737 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
738 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
739 @@ -1846,14 +1905,15 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
740 state->fe[index_frontend]->dtv_property_cache.rolloff;
743 - return 0;
744 + ret = 0;
745 + goto return_value;
749 /* get the channel from master chip */
750 ret = dib9000_fw_get_channel(fe, fep);
751 if (ret != 0)
752 - return ret;
753 + goto return_value;
755 /* synchronize the cache with the other frontends */
756 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
757 @@ -1866,8 +1926,12 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
758 state->fe[index_frontend]->dtv_property_cache.code_rate_LP = fe->dtv_property_cache.code_rate_LP;
759 state->fe[index_frontend]->dtv_property_cache.rolloff = fe->dtv_property_cache.rolloff;
761 + ret = 0;
763 - return 0;
764 +return_value:
765 + if (state->get_frontend_internal == 0)
766 + DibReleaseLock(&state->demod_lock);
767 + return ret;
770 static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
771 @@ -1912,6 +1976,10 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
772 dprintk("dib9000: must specify bandwidth ");
773 return 0;
776 + state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */
777 + DibAcquireLock(&state->demod_lock);
779 fe->dtv_property_cache.delivery_system = SYS_DVBT;
781 /* set the master status */
782 @@ -1974,13 +2042,18 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
783 /* check the tune result */
784 if (exit_condition == 1) { /* tune failed */
785 dprintk("tune failed");
786 + DibReleaseLock(&state->demod_lock);
787 + /* tune failed; put all the pid filtering cmd to junk */
788 + state->pid_ctrl_index = -1;
789 return 0;
792 dprintk("tune success on frontend%i", index_frontend_success);
794 /* synchronize all the channel cache */
795 + state->get_frontend_internal = 1;
796 dib9000_get_frontend(state->fe[0], fep);
797 + state->get_frontend_internal = 0;
799 /* retune the other frontends with the found channel */
800 channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
801 @@ -2025,6 +2098,28 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
802 /* turn off the diversity for the last frontend */
803 dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);
805 + DibReleaseLock(&state->demod_lock);
806 + if (state->pid_ctrl_index >= 0) {
807 + u8 index_pid_filter_cmd;
808 + u8 pid_ctrl_index = state->pid_ctrl_index;
810 + state->pid_ctrl_index = -2;
811 + for (index_pid_filter_cmd = 0;
812 + index_pid_filter_cmd <= pid_ctrl_index;
813 + index_pid_filter_cmd++) {
814 + if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER_CTRL)
815 + dib9000_fw_pid_filter_ctrl(state->fe[0],
816 + state->pid_ctrl[index_pid_filter_cmd].onoff);
817 + else if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER)
818 + dib9000_fw_pid_filter(state->fe[0],
819 + state->pid_ctrl[index_pid_filter_cmd].id,
820 + state->pid_ctrl[index_pid_filter_cmd].pid,
821 + state->pid_ctrl[index_pid_filter_cmd].onoff);
824 + /* do not postpone any more the pid filtering */
825 + state->pid_ctrl_index = -2;
827 return 0;
830 @@ -2041,6 +2136,7 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
831 u8 index_frontend;
832 u16 lock = 0, lock_slave = 0;
834 + DibAcquireLock(&state->demod_lock);
835 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
836 lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
838 @@ -2059,6 +2155,8 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
839 if ((lock & 0x0008) || (lock_slave & 0x0008))
840 *stat |= FE_HAS_LOCK;
842 + DibReleaseLock(&state->demod_lock);
844 return 0;
847 @@ -2066,10 +2164,14 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
849 struct dib9000_state *state = fe->demodulator_priv;
850 u16 *c;
851 + int ret = 0;
853 + DibAcquireLock(&state->demod_lock);
854 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
855 - if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
856 - return -EIO;
857 + if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
858 + ret = -EIO;
859 + goto error;
861 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
862 state->i2c_read_buffer, 16 * 2);
863 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
864 @@ -2077,7 +2179,10 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
865 c = (u16 *)state->i2c_read_buffer;
867 *ber = c[10] << 16 | c[11];
868 - return 0;
870 +error:
871 + DibReleaseLock(&state->demod_lock);
872 + return ret;
875 static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
876 @@ -2086,7 +2191,9 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
877 u8 index_frontend;
878 u16 *c = (u16 *)state->i2c_read_buffer;
879 u16 val;
880 + int ret = 0;
882 + DibAcquireLock(&state->demod_lock);
883 *strength = 0;
884 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
885 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
886 @@ -2097,8 +2204,10 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
889 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
890 - if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
891 - return -EIO;
892 + if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
893 + ret = -EIO;
894 + goto error;
896 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
897 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
899 @@ -2107,7 +2216,10 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
900 *strength = 65535;
901 else
902 *strength += val;
903 - return 0;
905 +error:
906 + DibReleaseLock(&state->demod_lock);
907 + return ret;
910 static u32 dib9000_get_snr(struct dvb_frontend *fe)
911 @@ -2151,6 +2263,7 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
912 u8 index_frontend;
913 u32 snr_master;
915 + DibAcquireLock(&state->demod_lock);
916 snr_master = dib9000_get_snr(fe);
917 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
918 snr_master += dib9000_get_snr(state->fe[index_frontend]);
919 @@ -2161,6 +2274,8 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
920 } else
921 *snr = 0;
923 + DibReleaseLock(&state->demod_lock);
925 return 0;
928 @@ -2168,15 +2283,22 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
930 struct dib9000_state *state = fe->demodulator_priv;
931 u16 *c = (u16 *)state->i2c_read_buffer;
932 + int ret = 0;
934 + DibAcquireLock(&state->demod_lock);
935 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
936 - if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
937 - return -EIO;
938 + if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
939 + ret = -EIO;
940 + goto error;
942 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
943 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
945 *unc = c[12];
946 - return 0;
948 +error:
949 + DibReleaseLock(&state->demod_lock);
950 + return ret;
953 int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
954 @@ -2322,6 +2444,10 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c
955 DibInitLock(&st->platform.risc.mbx_lock);
956 DibInitLock(&st->platform.risc.mem_lock);
957 DibInitLock(&st->platform.risc.mem_mbx_lock);
958 + DibInitLock(&st->demod_lock);
959 + st->get_frontend_internal = 0;
961 + st->pid_ctrl_index = -2;
963 st->fe[0] = fe;
964 fe->demodulator_priv = st;
965 diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
966 index dc5d17a..774d507 100644
967 --- a/drivers/media/dvb/frontends/dibx000_common.c
968 +++ b/drivers/media/dvb/frontends/dibx000_common.c
969 @@ -1,4 +1,5 @@
970 #include <linux/i2c.h>
971 +#include <linux/mutex.h>
973 #include "dibx000_common.h"
975 @@ -10,6 +11,13 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
977 static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
979 + int ret;
981 + if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
982 + dprintk("could not acquire lock");
983 + return -EINVAL;
986 mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
987 mst->i2c_write_buffer[1] = reg & 0xff;
988 mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
989 @@ -21,11 +29,21 @@ static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
990 mst->msg[0].buf = mst->i2c_write_buffer;
991 mst->msg[0].len = 4;
993 - return i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
994 + ret = i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
995 + mutex_unlock(&mst->i2c_buffer_lock);
997 + return ret;
1000 static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
1002 + u16 ret;
1004 + if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
1005 + dprintk("could not acquire lock");
1006 + return 0;
1009 mst->i2c_write_buffer[0] = reg >> 8;
1010 mst->i2c_write_buffer[1] = reg & 0xff;
1012 @@ -42,7 +60,10 @@ static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
1013 if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
1014 dprintk("i2c read error on %d", reg);
1016 - return (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
1017 + ret = (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
1018 + mutex_unlock(&mst->i2c_buffer_lock);
1020 + return ret;
1023 static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
1024 @@ -257,6 +278,7 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
1025 struct i2c_msg msg[], int num)
1027 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
1028 + int ret;
1030 if (num > 32) {
1031 dprintk("%s: too much I2C message to be transmitted (%i).\
1032 @@ -264,10 +286,15 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
1033 return -ENOMEM;
1036 - memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
1038 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
1040 + if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
1041 + dprintk("could not acquire lock");
1042 + return -EINVAL;
1045 + memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
1047 /* open the gate */
1048 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
1049 mst->msg[0].addr = mst->i2c_addr;
1050 @@ -282,7 +309,11 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
1051 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
1052 mst->msg[num + 1].len = 4;
1054 - return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
1055 + ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
1056 + num : -EIO);
1058 + mutex_unlock(&mst->i2c_buffer_lock);
1059 + return ret;
1062 static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
1063 @@ -294,6 +325,7 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
1064 struct i2c_msg msg[], int num)
1066 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
1067 + int ret;
1069 if (num > 32) {
1070 dprintk("%s: too much I2C message to be transmitted (%i).\
1071 @@ -301,10 +333,14 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
1072 return -ENOMEM;
1075 - memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
1077 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
1079 + if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
1080 + dprintk("could not acquire lock");
1081 + return -EINVAL;
1083 + memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
1085 /* open the gate */
1086 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
1087 mst->msg[0].addr = mst->i2c_addr;
1088 @@ -319,7 +355,10 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
1089 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
1090 mst->msg[num + 1].len = 4;
1092 - return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
1093 + ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
1094 + num : -EIO);
1095 + mutex_unlock(&mst->i2c_buffer_lock);
1096 + return ret;
1099 static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
1100 @@ -390,8 +429,18 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
1101 int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
1102 struct i2c_adapter *i2c_adap, u8 i2c_addr)
1104 - u8 tx[4];
1105 - struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };
1106 + int ret;
1108 + mutex_init(&mst->i2c_buffer_lock);
1109 + if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
1110 + dprintk("could not acquire lock");
1111 + return -EINVAL;
1113 + memset(mst->msg, 0, sizeof(struct i2c_msg));
1114 + mst->msg[0].addr = i2c_addr >> 1;
1115 + mst->msg[0].flags = 0;
1116 + mst->msg[0].buf = mst->i2c_write_buffer;
1117 + mst->msg[0].len = 4;
1119 mst->device_rev = device_rev;
1120 mst->i2c_adap = i2c_adap;
1121 @@ -431,9 +480,12 @@ int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
1122 "DiBX000: could not initialize the master i2c_adapter\n");
1124 /* initialize the i2c-master by closing the gate */
1125 - dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
1126 + dibx000_i2c_gate_ctrl(mst, mst->i2c_write_buffer, 0, 0);
1128 + ret = (i2c_transfer(i2c_adap, mst->msg, 1) == 1);
1129 + mutex_unlock(&mst->i2c_buffer_lock);
1131 - return i2c_transfer(i2c_adap, &m, 1) == 1;
1132 + return ret;
1135 EXPORT_SYMBOL(dibx000_init_i2c_master);
1136 diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
1137 index f031165..5e01147 100644
1138 --- a/drivers/media/dvb/frontends/dibx000_common.h
1139 +++ b/drivers/media/dvb/frontends/dibx000_common.h
1140 @@ -33,6 +33,7 @@ struct dibx000_i2c_master {
1141 struct i2c_msg msg[34];
1142 u8 i2c_write_buffer[8];
1143 u8 i2c_read_buffer[2];
1144 + struct mutex i2c_buffer_lock;
1147 extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
1148 commit 45cbff13693d645fa5dcbba964e802e1746b2e57
1149 Author: Olivier Grenie <olivier.grenie@dibcom.fr>
1150 Date: Mon Aug 1 17:45:58 2011 +0200
1152 [media] dib0700: protect the dib0700 buffer access
1154 This patch protects the common buffer access inside the dib0700 in order
1155 to manage concurrent access. This protection is done using mutex.
1157 Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
1158 Cc: Florian Mickler <florian@mickler.org>
1159 Cc: stable@kernel.org
1161 Signed-off-by: Javier Marcet <javier@marcet.info>
1162 Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr>
1163 Signed-off-by: Patrick Boettcher <patrick.boettcher@dibcom.fr>
1165 diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
1166 index 5eb91b4..291b645 100644
1167 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c
1168 +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
1169 @@ -30,6 +30,11 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
1170 struct dib0700_state *st = d->priv;
1171 int ret;
1173 + if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1174 + dprintk("could not acquire lock");
1175 + return 0;
1178 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
1179 REQUEST_GET_VERSION,
1180 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
1181 @@ -46,6 +51,7 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
1182 if (fwtype != NULL)
1183 *fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) |
1184 (st->buf[14] << 8) | st->buf[15];
1185 + mutex_unlock(&d->usb_mutex);
1186 return ret;
1189 @@ -108,7 +114,12 @@ int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen
1190 int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
1192 struct dib0700_state *st = d->priv;
1193 - s16 ret;
1194 + int ret;
1196 + if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1197 + dprintk("could not acquire lock");
1198 + return 0;
1201 st->buf[0] = REQUEST_SET_GPIO;
1202 st->buf[1] = gpio;
1203 @@ -116,6 +127,7 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
1205 ret = dib0700_ctrl_wr(d, st->buf, 3);
1207 + mutex_unlock(&d->usb_mutex);
1208 return ret;
1211 @@ -125,6 +137,11 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
1212 int ret;
1214 if (st->fw_version >= 0x10201) {
1215 + if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1216 + dprintk("could not acquire lock");
1217 + return 0;
1220 st->buf[0] = REQUEST_SET_USB_XFER_LEN;
1221 st->buf[1] = (nb_ts_packets >> 8) & 0xff;
1222 st->buf[2] = nb_ts_packets & 0xff;
1223 @@ -132,6 +149,7 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
1224 deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
1226 ret = dib0700_ctrl_wr(d, st->buf, 3);
1227 + mutex_unlock(&d->usb_mutex);
1228 } else {
1229 deb_info("this firmware does not allow to change the USB xfer len\n");
1230 ret = -EIO;
1231 @@ -208,6 +226,10 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
1233 } else {
1234 /* Write request */
1235 + if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1236 + dprintk("could not acquire lock");
1237 + return 0;
1239 st->buf[0] = REQUEST_NEW_I2C_WRITE;
1240 st->buf[1] = msg[i].addr << 1;
1241 st->buf[2] = (en_start << 7) | (en_stop << 6) |
1242 @@ -227,6 +249,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
1243 USB_TYPE_VENDOR | USB_DIR_OUT,
1244 0, 0, st->buf, msg[i].len + 4,
1245 USB_CTRL_GET_TIMEOUT);
1246 + mutex_unlock(&d->usb_mutex);
1247 if (result < 0) {
1248 deb_info("i2c write error (status = %d)\n", result);
1249 break;
1250 @@ -249,6 +272,10 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
1252 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
1253 return -EAGAIN;
1254 + if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1255 + dprintk("could not acquire lock");
1256 + return 0;
1259 for (i = 0; i < num; i++) {
1260 /* fill in the address */
1261 @@ -279,6 +306,7 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
1262 break;
1265 + mutex_unlock(&d->usb_mutex);
1266 mutex_unlock(&d->i2c_mutex);
1268 return i;
1269 @@ -337,7 +365,12 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
1270 u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
1272 struct dib0700_state *st = d->priv;
1273 - s16 ret;
1274 + int ret;
1276 + if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1277 + dprintk("could not acquire lock");
1278 + return 0;
1281 st->buf[0] = REQUEST_SET_CLOCK;
1282 st->buf[1] = (en_pll << 7) | (pll_src << 6) |
1283 @@ -352,6 +385,7 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
1284 st->buf[9] = dsuScaler & 0xff; /* LSB */
1286 ret = dib0700_ctrl_wr(d, st->buf, 10);
1287 + mutex_unlock(&d->usb_mutex);
1289 return ret;
1291 @@ -360,10 +394,16 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
1293 struct dib0700_state *st = d->priv;
1294 u16 divider;
1295 + int ret;
1297 if (scl_kHz == 0)
1298 return -EINVAL;
1300 + if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1301 + dprintk("could not acquire lock");
1302 + return 0;
1305 st->buf[0] = REQUEST_SET_I2C_PARAM;
1306 divider = (u16) (30000 / scl_kHz);
1307 st->buf[1] = 0;
1308 @@ -379,7 +419,11 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
1309 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
1310 (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
1311 st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
1312 - return dib0700_ctrl_wr(d, st->buf, 8);
1314 + ret = dib0700_ctrl_wr(d, st->buf, 8);
1315 + mutex_unlock(&d->usb_mutex);
1317 + return ret;
1321 @@ -515,6 +559,11 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
1325 + if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
1326 + dprintk("could not acquire lock");
1327 + return 0;
1330 st->buf[0] = REQUEST_ENABLE_VIDEO;
1331 /* this bit gives a kind of command,
1332 * rather than enabling something or not */
1333 @@ -548,7 +597,10 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
1335 deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
1337 - return dib0700_ctrl_wr(adap->dev, st->buf, 4);
1338 + ret = dib0700_ctrl_wr(adap->dev, st->buf, 4);
1339 + mutex_unlock(&adap->dev->usb_mutex);
1341 + return ret;
1344 int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
1345 @@ -557,6 +609,11 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
1346 struct dib0700_state *st = d->priv;
1347 int new_proto, ret;
1349 + if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1350 + dprintk("could not acquire lock");
1351 + return 0;
1354 st->buf[0] = REQUEST_SET_RC;
1355 st->buf[1] = 0;
1356 st->buf[2] = 0;
1357 @@ -567,23 +624,29 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
1358 else if (rc_type == RC_TYPE_NEC)
1359 new_proto = 0;
1360 else if (rc_type == RC_TYPE_RC6) {
1361 - if (st->fw_version < 0x10200)
1362 - return -EINVAL;
1363 + if (st->fw_version < 0x10200) {
1364 + ret = -EINVAL;
1365 + goto out;
1368 new_proto = 2;
1369 - } else
1370 - return -EINVAL;
1371 + } else {
1372 + ret = -EINVAL;
1373 + goto out;
1376 st->buf[1] = new_proto;
1378 ret = dib0700_ctrl_wr(d, st->buf, 3);
1379 if (ret < 0) {
1380 err("ir protocol setup failed");
1381 - return ret;
1382 + goto out;
1385 d->props.rc.core.protocol = rc_type;
1387 +out:
1388 + mutex_unlock(&d->usb_mutex);
1389 return ret;
1392 commit aeb2d456b746164a4bd19e53de0a6678ca63fcad
1393 Author: Olivier Grenie <olivier.grenie@dibcom.fr>
1394 Date: Thu Aug 4 18:10:03 2011 +0200
1396 [media] dib0700: correct error message
1398 The goal of this patch is to correct a previous patch. In case of error,
1399 the err() function should be used instead of dprintk() function.
1401 Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr>
1403 diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
1404 index 291b645..b693ed1 100644
1405 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c
1406 +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
1407 @@ -31,7 +31,7 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
1408 int ret;
1410 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1411 - dprintk("could not acquire lock");
1412 + err("could not acquire lock");
1413 return 0;
1416 @@ -117,7 +117,7 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
1417 int ret;
1419 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1420 - dprintk("could not acquire lock");
1421 + err("could not acquire lock");
1422 return 0;
1425 @@ -138,7 +138,7 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
1427 if (st->fw_version >= 0x10201) {
1428 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1429 - dprintk("could not acquire lock");
1430 + err("could not acquire lock");
1431 return 0;
1434 @@ -227,7 +227,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
1435 } else {
1436 /* Write request */
1437 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1438 - dprintk("could not acquire lock");
1439 + err("could not acquire lock");
1440 return 0;
1442 st->buf[0] = REQUEST_NEW_I2C_WRITE;
1443 @@ -273,7 +273,7 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
1444 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
1445 return -EAGAIN;
1446 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1447 - dprintk("could not acquire lock");
1448 + err("could not acquire lock");
1449 return 0;
1452 @@ -368,7 +368,7 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
1453 int ret;
1455 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1456 - dprintk("could not acquire lock");
1457 + err("could not acquire lock");
1458 return 0;
1461 @@ -400,7 +400,7 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
1462 return -EINVAL;
1464 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1465 - dprintk("could not acquire lock");
1466 + err("could not acquire lock");
1467 return 0;
1470 @@ -560,7 +560,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
1473 if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
1474 - dprintk("could not acquire lock");
1475 + err("could not acquire lock");
1476 return 0;
1479 @@ -610,7 +610,7 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
1480 int new_proto, ret;
1482 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
1483 - dprintk("could not acquire lock");
1484 + err("could not acquire lock");
1485 return 0;