Oliver Endriss wrote:
> e9hack wrote:
>
>
>> SAA7146_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;
>> + timeout = HZ/100 + 1; /* 10ms */
>> + timeout = wait_event_interruptible_timeout(dev->i2c_wq,
>> dev->i2c_op == 0, timeout);
>> + if (timeout == -ERESTARTSYS || dev->i2c_op) {
>> + SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
>> + SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
>> + if (timeout == -ERESTARTSYS) {
>> + /* a signal arrived */
>> + return -ERESTARTSYS;
>> + }
>>
>
> Please remove '{' and '}' - kernel coding style ;-)
>
The original code contains also this brackets. I removed it.
>
>> + /* 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;
>>
>
> Are you able to trigger this timeout? Is yes, how?
>
> Imho it cannot happen anymore (because of [1]) unless the hardware is
> broken. Even with nonexistent devices there should be an I2C irq.
>
> Anyway, it is a good idea to add this timeout protection.
>
I didn't see such a timeout.
> If it cannot happen under normal circumstances you should replace
> DEB_I2C by printk.
>
I changed it.
- Hartmut
Signed-off-by: Hartmut Birr <[EMAIL PROTECTED]>
Add a timeout to the wait for the i2c-interrupt.
The interrupt may never hit. The timeout prevents from endless waiting.
diff -r 7b945ba585c3 linux/drivers/media/common/saa7146_i2c.c
--- a/linux/drivers/media/common/saa7146_i2c.c Tue Oct 31 15:33:29 2006 -0300
+++ b/linux/drivers/media/common/saa7146_i2c.c Wed Nov 01 07:57:14 2006 +0100
@@ -190,13 +190,21 @@ static int saa7146_i2c_writeout(struct s
saa7146_write(dev, I2C_TRANSFER, *dword);
dev->i2c_op = 1;
+ SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
SAA7146_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;
+ timeout = HZ/100 + 1; /* 10ms */
+ timeout = wait_event_interruptible_timeout(dev->i2c_wq, dev->i2c_op == 0, timeout);
+ if (timeout == -ERESTARTSYS || dev->i2c_op) {
+ SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
+ SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
+ if (timeout == -ERESTARTSYS)
+ /* a signal arrived */
+ return -ERESTARTSYS;
+
+ printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for end of xfer\n");
+ return -EIO;
}
status = saa7146_read(dev, I2C_STATUS);
} else {
_______________________________________________
linux-dvb mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb