summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorJohannes Stezenbach <devnull@localhost>2003-01-13 17:24:16 +0000
committerJohannes Stezenbach <devnull@localhost>2003-01-13 17:24:16 +0000
commit8b66c89b2a6d7bec1ce0d650732db341b03ca5a4 (patch)
tree265cdc2743fd95f96e44a93866d39608c5aaef1f /linux
parentad7bd2281428a7ce922142891a7d40fd5b6cee57 (diff)
downloadmediapointer-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.c18
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);
}
}