Commit d52786dd authored by Daniel Scheller's avatar Daniel Scheller Committed by Mauro Carvalho Chehab

media: ddbridge: make (ddb)readl in while-loops fail-safe

Reported by smatch:

  drivers/media/pci/ddbridge/ddbridge-core.c:1246 input_tasklet() warn: this loop depends on readl() succeeding
  drivers/media/pci/ddbridge/ddbridge-core.c:1768 flashio() warn: this loop depends on readl() succeeding
  drivers/media/pci/ddbridge/ddbridge-core.c:1788 flashio() warn: this loop depends on readl() succeeding

Fix this by introducing safe_ddbreadl() which will wrap ddbreadl and checks
for all bits set in the return which indicates failure, and return 0 in
that case. Usable as drop-in-replacement in all affected while loops w/o
having to change the logic.
Signed-off-by: default avatarDaniel Scheller <d.scheller@gmx.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent cb778f5c
...@@ -114,6 +114,19 @@ static int i2c_write_reg(struct i2c_adapter *adap, u8 adr, ...@@ -114,6 +114,19 @@ static int i2c_write_reg(struct i2c_adapter *adap, u8 adr,
return i2c_write(adap, adr, msg, 2); return i2c_write(adap, adr, msg, 2);
} }
static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr)
{
u32 val = ddbreadl(adr);
/* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */
if (val == ~0) {
printk(KERN_ERR "ddbreadl failure, adr=%08x\n", adr);
return 0;
}
return val;
}
static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
{ {
struct ddb *dev = i2c->dev; struct ddb *dev = i2c->dev;
...@@ -1243,7 +1256,7 @@ static void input_tasklet(unsigned long data) ...@@ -1243,7 +1256,7 @@ static void input_tasklet(unsigned long data)
if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr))) if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))
printk(KERN_ERR "Overflow input %d\n", input->nr); printk(KERN_ERR "Overflow input %d\n", input->nr);
while (input->cbuf != ((input->stat >> 11) & 0x1f) while (input->cbuf != ((input->stat >> 11) & 0x1f)
|| (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))) { || (4 & safe_ddbreadl(dev, DMA_BUFFER_CONTROL(input->nr)))) {
dvb_dmx_swfilter_packets(&input->demux, dvb_dmx_swfilter_packets(&input->demux,
input->vbuf[input->cbuf], input->vbuf[input->cbuf],
input->dma_buf_size / 188); input->dma_buf_size / 188);
...@@ -1765,7 +1778,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) ...@@ -1765,7 +1778,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
wbuf += 4; wbuf += 4;
wlen -= 4; wlen -= 4;
ddbwritel(data, SPI_DATA); ddbwritel(data, SPI_DATA);
while (ddbreadl(SPI_CONTROL) & 0x0004) while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004)
; ;
} }
...@@ -1785,7 +1798,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) ...@@ -1785,7 +1798,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
if (shift) if (shift)
data <<= shift; data <<= shift;
ddbwritel(data, SPI_DATA); ddbwritel(data, SPI_DATA);
while (ddbreadl(SPI_CONTROL) & 0x0004) while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004)
; ;
if (!rlen) { if (!rlen) {
...@@ -1797,7 +1810,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) ...@@ -1797,7 +1810,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
while (rlen > 4) { while (rlen > 4) {
ddbwritel(0xffffffff, SPI_DATA); ddbwritel(0xffffffff, SPI_DATA);
while (ddbreadl(SPI_CONTROL) & 0x0004) while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004)
; ;
data = ddbreadl(SPI_DATA); data = ddbreadl(SPI_DATA);
*(u32 *) rbuf = swab32(data); *(u32 *) rbuf = swab32(data);
...@@ -1806,7 +1819,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) ...@@ -1806,7 +1819,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
} }
ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL); ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL);
ddbwritel(0xffffffff, SPI_DATA); ddbwritel(0xffffffff, SPI_DATA);
while (ddbreadl(SPI_CONTROL) & 0x0004) while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004)
; ;
data = ddbreadl(SPI_DATA); data = ddbreadl(SPI_DATA);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment