diff options
author | Johannes Stezenbach <devnull@localhost> | 2003-01-13 17:24:16 +0000 |
---|---|---|
committer | Johannes Stezenbach <devnull@localhost> | 2003-01-13 17:24:16 +0000 |
commit | 8b66c89b2a6d7bec1ce0d650732db341b03ca5a4 (patch) | |
tree | 265cdc2743fd95f96e44a93866d39608c5aaef1f /linux | |
parent | ad7bd2281428a7ce922142891a7d40fd5b6cee57 (diff) | |
download | mediapointer-dvb-s2-8b66c89b2a6d7bec1ce0d650732db341b03ca5a4.tar.gz mediapointer-dvb-s2-8b66c89b2a6d7bec1ce0d650732db341b03ca5a4.tar.bz2 |
add a timeout to saa7146_i2c_writeout() to prevent endless loop
Diffstat (limited to 'linux')
-rw-r--r-- | linux/drivers/media/common/saa7146_i2c.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c index adbf61aa6..b73803310 100644 --- a/linux/drivers/media/common/saa7146_i2c.c +++ b/linux/drivers/media/common/saa7146_i2c.c @@ -193,6 +193,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword) { u32 status = 0, mc2 = 0; + int timeout; /* write out i2c-command */ DEB_I2C(("before: 0x%08x (status: 0x%08x), %d\n",*dword,saa7146_read(dev, I2C_STATUS), dev->i2c_op)); @@ -205,11 +206,11 @@ int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword) dev->i2c_op = 1; IER_ENABLE(dev, MASK_16|MASK_17); saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - + wait_event_interruptible(dev->i2c_wq, dev->i2c_op == 0); if (signal_pending (current)) { /* a signal arrived */ - return -ERESTARTSYS; + return -ERESTARTSYS; } status = saa7146_read(dev, I2C_STATUS); } else { @@ -218,18 +219,31 @@ int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword) saa7146_write(dev, MC2, (MASK_00 | MASK_16)); /* do not poll for i2c-status before upload is complete */ + timeout = jiffies + HZ/100 + 1; /* 10ms */ while(1) { mc2 = (saa7146_read(dev, MC2) & 0x1); if( 0 != mc2 ) { break; } + if (jiffies > timeout) { + printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for MC2\n"); + return -EIO; + } } /* wait until we get a transfer done or error */ + timeout = jiffies + HZ/100 + 1; /* 10ms */ while(1) { status = saa7146_i2c_status(dev); if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) { break; } + if (jiffies > timeout) { + /* this is normal when probing the bus + * (no answer from nonexisistant device...) + */ + DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n")); + return -EIO; + } my_wait(dev,1); } } |