aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/dib9000.c
diff options
context:
space:
mode:
authorAlexey Khoroshilov <khoroshilov@ispras.ru>2012-03-06 15:08:29 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-19 13:36:24 -0400
commitf3033aecf2341a4e2669c63ed78a190a1c3e7a3a (patch)
tree922c9e4476283fb1eb346c12bd9b0ee8be556a8a /drivers/media/dvb/frontends/dib9000.c
parent9bb24a7e49c33c16c4d9d7d3496f46626e573d02 (diff)
[media] dib9000: implement error handling for DibAcquireLock
DibAcquireLock() is implemented as mutex_lock_interruptible() but the driver does not handle unsuccessful locking. As a result it may lead to unlock of an unheld mutex. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/frontends/dib9000.c')
-rw-r--r--drivers/media/dvb/frontends/dib9000.c115
1 files changed, 91 insertions, 24 deletions
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
index d96b6a1e65d9..80848b4c15d4 100644
--- a/drivers/media/dvb/frontends/dib9000.c
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -33,7 +33,7 @@ struct i2c_device {
33 33
34/* lock */ 34/* lock */
35#define DIB_LOCK struct mutex 35#define DIB_LOCK struct mutex
36#define DibAcquireLock(lock) do { if (mutex_lock_interruptible(lock) < 0) dprintk("could not get the lock"); } while (0) 36#define DibAcquireLock(lock) mutex_lock_interruptible(lock)
37#define DibReleaseLock(lock) mutex_unlock(lock) 37#define DibReleaseLock(lock) mutex_unlock(lock)
38#define DibInitLock(lock) mutex_init(lock) 38#define DibInitLock(lock) mutex_init(lock)
39#define DibFreeLock(lock) 39#define DibFreeLock(lock)
@@ -446,7 +446,10 @@ static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u1
446 if (!state->platform.risc.fw_is_running) 446 if (!state->platform.risc.fw_is_running)
447 return -EIO; 447 return -EIO;
448 448
449 DibAcquireLock(&state->platform.risc.mem_lock); 449 if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) {
450 dprintk("could not get the lock");
451 return -EINTR;
452 }
450 dib9000_risc_mem_setup(state, cmd | 0x80); 453 dib9000_risc_mem_setup(state, cmd | 0x80);
451 dib9000_risc_mem_read_chunks(state, b, len); 454 dib9000_risc_mem_read_chunks(state, b, len);
452 DibReleaseLock(&state->platform.risc.mem_lock); 455 DibReleaseLock(&state->platform.risc.mem_lock);
@@ -459,7 +462,10 @@ static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8
459 if (!state->platform.risc.fw_is_running) 462 if (!state->platform.risc.fw_is_running)
460 return -EIO; 463 return -EIO;
461 464
462 DibAcquireLock(&state->platform.risc.mem_lock); 465 if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) {
466 dprintk("could not get the lock");
467 return -EINTR;
468 }
463 dib9000_risc_mem_setup(state, cmd); 469 dib9000_risc_mem_setup(state, cmd);
464 dib9000_risc_mem_write_chunks(state, b, m->size); 470 dib9000_risc_mem_write_chunks(state, b, m->size);
465 DibReleaseLock(&state->platform.risc.mem_lock); 471 DibReleaseLock(&state->platform.risc.mem_lock);
@@ -531,7 +537,10 @@ static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data,
531 if (!state->platform.risc.fw_is_running) 537 if (!state->platform.risc.fw_is_running)
532 return -EINVAL; 538 return -EINVAL;
533 539
534 DibAcquireLock(&state->platform.risc.mbx_if_lock); 540 if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) {
541 dprintk("could not get the lock");
542 return -EINTR;
543 }
535 tmp = MAX_MAILBOX_TRY; 544 tmp = MAX_MAILBOX_TRY;
536 do { 545 do {
537 size = dib9000_read_word_attr(state, 1043, attr) & 0xff; 546 size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
@@ -593,7 +602,10 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id,
593 if (!state->platform.risc.fw_is_running) 602 if (!state->platform.risc.fw_is_running)
594 return 0; 603 return 0;
595 604
596 DibAcquireLock(&state->platform.risc.mbx_if_lock); 605 if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) {
606 dprintk("could not get the lock");
607 return 0;
608 }
597 if (risc_id == 1) 609 if (risc_id == 1)
598 mc_base = 16; 610 mc_base = 16;
599 else 611 else
@@ -701,7 +713,10 @@ static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
701 if (!state->platform.risc.fw_is_running) 713 if (!state->platform.risc.fw_is_running)
702 return -1; 714 return -1;
703 715
704 DibAcquireLock(&state->platform.risc.mbx_lock); 716 if (DibAcquireLock(&state->platform.risc.mbx_lock) < 0) {
717 dprintk("could not get the lock");
718 return -1;
719 }
705 720
706 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */ 721 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */
707 ret = dib9000_mbx_fetch_to_cache(state, attr); 722 ret = dib9000_mbx_fetch_to_cache(state, attr);
@@ -1178,7 +1193,10 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe)
1178 struct dibDVBTChannel *ch; 1193 struct dibDVBTChannel *ch;
1179 int ret = 0; 1194 int ret = 0;
1180 1195
1181 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 1196 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
1197 dprintk("could not get the lock");
1198 return -EINTR;
1199 }
1182 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 1200 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
1183 ret = -EIO; 1201 ret = -EIO;
1184 goto error; 1202 goto error;
@@ -1660,7 +1678,10 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2
1660 p[12] = 0; 1678 p[12] = 0;
1661 } 1679 }
1662 1680
1663 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 1681 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
1682 dprintk("could not get the lock");
1683 return 0;
1684 }
1664 1685
1665 dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p); 1686 dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
1666 1687
@@ -1768,7 +1789,10 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1768 return 0; 1789 return 0;
1769 } 1790 }
1770 1791
1771 DibAcquireLock(&state->demod_lock); 1792 if (DibAcquireLock(&state->demod_lock) < 0) {
1793 dprintk("could not get the lock");
1794 return -EINTR;
1795 }
1772 1796
1773 val = dib9000_read_word(state, 294 + 1) & 0xffef; 1797 val = dib9000_read_word(state, 294 + 1) & 0xffef;
1774 val |= (onoff & 0x1) << 4; 1798 val |= (onoff & 0x1) << 4;
@@ -1800,7 +1824,10 @@ int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1800 return 0; 1824 return 0;
1801 } 1825 }
1802 1826
1803 DibAcquireLock(&state->demod_lock); 1827 if (DibAcquireLock(&state->demod_lock) < 0) {
1828 dprintk("could not get the lock");
1829 return -EINTR;
1830 }
1804 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); 1831 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
1805 ret = dib9000_write_word(state, 300 + 1 + id, 1832 ret = dib9000_write_word(state, 300 + 1 + id,
1806 onoff ? (1 << 13) | pid : 0); 1833 onoff ? (1 << 13) | pid : 0);
@@ -1848,7 +1875,10 @@ static int dib9000_sleep(struct dvb_frontend *fe)
1848 u8 index_frontend; 1875 u8 index_frontend;
1849 int ret = 0; 1876 int ret = 0;
1850 1877
1851 DibAcquireLock(&state->demod_lock); 1878 if (DibAcquireLock(&state->demod_lock) < 0) {
1879 dprintk("could not get the lock");
1880 return -EINTR;
1881 }
1852 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 1882 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1853 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]); 1883 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1854 if (ret < 0) 1884 if (ret < 0)
@@ -1874,8 +1904,12 @@ static int dib9000_get_frontend(struct dvb_frontend *fe)
1874 fe_status_t stat; 1904 fe_status_t stat;
1875 int ret = 0; 1905 int ret = 0;
1876 1906
1877 if (state->get_frontend_internal == 0) 1907 if (state->get_frontend_internal == 0) {
1878 DibAcquireLock(&state->demod_lock); 1908 if (DibAcquireLock(&state->demod_lock) < 0) {
1909 dprintk("could not get the lock");
1910 return -EINTR;
1911 }
1912 }
1879 1913
1880 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 1914 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1881 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); 1915 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
@@ -1978,7 +2012,10 @@ static int dib9000_set_frontend(struct dvb_frontend *fe)
1978 } 2012 }
1979 2013
1980 state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */ 2014 state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */
1981 DibAcquireLock(&state->demod_lock); 2015 if (DibAcquireLock(&state->demod_lock) < 0) {
2016 dprintk("could not get the lock");
2017 return 0;
2018 }
1982 2019
1983 fe->dtv_property_cache.delivery_system = SYS_DVBT; 2020 fe->dtv_property_cache.delivery_system = SYS_DVBT;
1984 2021
@@ -2138,7 +2175,10 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2138 u8 index_frontend; 2175 u8 index_frontend;
2139 u16 lock = 0, lock_slave = 0; 2176 u16 lock = 0, lock_slave = 0;
2140 2177
2141 DibAcquireLock(&state->demod_lock); 2178 if (DibAcquireLock(&state->demod_lock) < 0) {
2179 dprintk("could not get the lock");
2180 return -EINTR;
2181 }
2142 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 2182 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2143 lock_slave |= dib9000_read_lock(state->fe[index_frontend]); 2183 lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
2144 2184
@@ -2168,8 +2208,15 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
2168 u16 *c; 2208 u16 *c;
2169 int ret = 0; 2209 int ret = 0;
2170 2210
2171 DibAcquireLock(&state->demod_lock); 2211 if (DibAcquireLock(&state->demod_lock) < 0) {
2172 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2212 dprintk("could not get the lock");
2213 return -EINTR;
2214 }
2215 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
2216 dprintk("could not get the lock");
2217 ret = -EINTR;
2218 goto error;
2219 }
2173 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2220 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2174 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2221 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2175 ret = -EIO; 2222 ret = -EIO;
@@ -2196,7 +2243,10 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2196 u16 val; 2243 u16 val;
2197 int ret = 0; 2244 int ret = 0;
2198 2245
2199 DibAcquireLock(&state->demod_lock); 2246 if (DibAcquireLock(&state->demod_lock) < 0) {
2247 dprintk("could not get the lock");
2248 return -EINTR;
2249 }
2200 *strength = 0; 2250 *strength = 0;
2201 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 2251 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2202 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val); 2252 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
@@ -2206,7 +2256,11 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2206 *strength += val; 2256 *strength += val;
2207 } 2257 }
2208 2258
2209 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2259 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
2260 dprintk("could not get the lock");
2261 ret = -EINTR;
2262 goto error;
2263 }
2210 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2264 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2211 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2265 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2212 ret = -EIO; 2266 ret = -EIO;
@@ -2233,10 +2287,13 @@ static u32 dib9000_get_snr(struct dvb_frontend *fe)
2233 u32 n, s, exp; 2287 u32 n, s, exp;
2234 u16 val; 2288 u16 val;
2235 2289
2236 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2290 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
2291 dprintk("could not get the lock");
2292 return 0;
2293 }
2237 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2294 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2238 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2295 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2239 return -EIO; 2296 return 0;
2240 } 2297 }
2241 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); 2298 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2242 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2299 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
@@ -2269,7 +2326,10 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
2269 u8 index_frontend; 2326 u8 index_frontend;
2270 u32 snr_master; 2327 u32 snr_master;
2271 2328
2272 DibAcquireLock(&state->demod_lock); 2329 if (DibAcquireLock(&state->demod_lock) < 0) {
2330 dprintk("could not get the lock");
2331 return -EINTR;
2332 }
2273 snr_master = dib9000_get_snr(fe); 2333 snr_master = dib9000_get_snr(fe);
2274 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 2334 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2275 snr_master += dib9000_get_snr(state->fe[index_frontend]); 2335 snr_master += dib9000_get_snr(state->fe[index_frontend]);
@@ -2291,8 +2351,15 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2291 u16 *c = (u16 *)state->i2c_read_buffer; 2351 u16 *c = (u16 *)state->i2c_read_buffer;
2292 int ret = 0; 2352 int ret = 0;
2293 2353
2294 DibAcquireLock(&state->demod_lock); 2354 if (DibAcquireLock(&state->demod_lock) < 0) {
2295 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2355 dprintk("could not get the lock");
2356 return -EINTR;
2357 }
2358 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
2359 dprintk("could not get the lock");
2360 ret = -EINTR;
2361 goto error;
2362 }
2296 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2363 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2297 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2364 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2298 ret = -EIO; 2365 ret = -EIO;