I've seen these problems too. Mark Anderson sent me the
following patch, which introduces delays as you mention.
This fixed my CAM access problems I had with
dvb_ca_en50221.c
---
drivers/media/dvb/dvb-core/dvb_ca_en50221.c.orig
2007-05-3121:45:21.700049473 +1000
+++ drivers/media/dvb/dvb-core/dvb_ca_en50221.c 2007-06-0123:21:32.596707598 +1000 @@ -721,29 +721,34 @@ static int dvb_ca_en50221_write_data(str // sanity check if (bytes_write > ca->slot_info[slot].link_buf_size) return -EINVAL; - +msleep(1); /* check if interface is actually waiting for us to read fromit, or if a read is in progress */ if ((status = ca->pub->read_cam_control(ca->pub, slot,CTRLIF_STATUS)) < 0) goto exitnowrite; +msleep(1); if (status & (STATUSREG_DA | STATUSREG_RE)) { status = -EAGAIN; goto exitnowrite; } +msleep(1); /* OK, set HC bit */ if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_HC)) != 0) goto exit; +msleep(1); /* check if interface is still
free */
if ((status = ca->pub->read_cam_control(ca->pub, slot,CTRLIF_STATUS)) < 0) goto exit; +msleep(1); if (!(status & STATUSREG_FR)) { /* it wasn't free => try again later */ status = -EAGAIN; goto exit; } +msleep(1); /* send the amount of data
*/
if ((status = ca->pub->write_cam_control(ca->pub, slot,CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0) @@ -752,21 +757,26 @@ static int dvb_ca_en50221_write_data(str bytes_write & 0xff)) != 0) goto exit; +msleep(1);
/* send the buffer */ for (i = 0; i < bytes_write; i++) { if ((status = ca->pub->write_cam_control(ca->pub,slot, CTRLIF_DATA, buf[i])) != 0) goto exit; } +msleep(1);
/* check for write error (WE should now be 0) */ if ((status = ca->pub->read_cam_control(ca->pub, slot,CTRLIF_STATUS)) < 0) goto exit; +msleep(1); if (status & STATUSREG_WE) { ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; status = -EIO; goto exit; } +msleep(1); status = bytes_write; +msleep(1); dprintk("Wrote CA packet for
slot %i, connection id 0x%xlast_frag:%i size:0x%x\n",
slot,
buf[0], (buf[1] & 0x80) == 0, bytes_write);
--- drivers/media/common/saa7146_i2c.c.orig
2007-05-31
22:17:57.922566547 +1000 +++ drivers/media/common/saa7146_i2c.c 2007-06-01 20:51:56.638799917 +1000 @@ -179,6 +179,7 @@ static int saa7146_i2c_writeout(struct s u32 status = 0, mc2 = 0; int trial = 0; unsigned long timeout; + int retry; /* write out i2c-command
*/
DEB_I2C(("before: 0x%08x (status: 0x%08x),%d\n",*dword,saa7146_read(dev, I2C_STATUS), dev->i2c_op)); @@ -194,6 +195,9 @@ static int saa7146_i2c_writeout(struct s saa7146_write(dev, MC2, (MASK_00 | MASK_16));
timeout = HZ/100 + 1; /* 10ms
*/
+ retry = 1000; + while (retry-- > 0) + { 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); @@ -203,10 +207,21 @@ static int saa7146_i2c_writeout(struct s return -ERESTARTSYS;
printk(KERN_WARNING "saa7146_i2c_writeout:timed out waiting for end of
xfer\n");
+ msleep(1); + } + else + { + break; + } + } + if (retry <= 0) + { return -EIO; } status = saa7146_read(dev, I2C_STATUS); - } else { + } + else + { saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); saa7146_write(dev, I2C_TRANSFER, *dword); saa7146_write(dev, MC2, (MASK_00 | MASK_16)); @@ -235,7 +250,7 @@ static int saa7146_i2c_writeout(struct s /* this is normal when probing the bus * (no answer from nonexisistant device...) */ - DEB_I2C(("saa7146_i2c_writeout: timedout waiting for end of xfer\n")); + DEB_I2C(("saa7146_i2c_writeout: timedout waiting for end of xfer2\n")); return -EIO; } if (++trial < 50 && short_delay)
|
_______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb