Re: Problem with init some CAM blocks on TTBudget-S1500 + CI

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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)
 
 
----- Original Message -----
Sent: Friday, July 20, 2007 9:01 AM
Subject: Re: Problem with init some CAM blocks on TTBudget-S1500 + CI

Evgen, all,
   I'm only a stupid newbie in the linuxtv world,
but from my experience with CAM cards it seems to me that Eugen's observation is correct but not precious:
 
IMHO, the sequence should be (from the DVB-CI standard):
 
  1) "host now tells the module to use this buffer size by writing a ?1? to the SW bit in the Command Register"
   2) "waiting until the FR bit is set"
   3) "writing the size as 2 bytes of data, most significant byte first..."
   4) "At the end of the transfer the host sets the SW bit to '0'. "
 
this is actually what is coded in  dvb_ca_en50221.c, but I GUESS - I HAVEN'T TESTED IT!!
that the problem is that one have to introduce some delay between writing the buffer size
and setting the SW bit to zero - since according to the standard we have to wait until the transfer (and not
simply the write operation) is finished
 
         if ((ret = dvb_ca_en50221_write_data(ca, slot, buf, 2)) != 2)
                 return -EIO;
/*
   WE NEED DELAY HERE ... ?
*/
         if ((ret = ca->pub->write_cam_control(ca->pub, slot, 
CTRLIF_COMMAND, IRQEN)) != 0)
                 return ret;
=======================
Now my question:
  I'm writing the DVB-CI driver for customer made HW developed by the firm I'm working for.
  I'm going to use the dvb-core infrastructure.
  Is there any card which driver already uses the dvb_ca part of the dvb-core ?
 
  I put an eye on Twinhan 1030 card, but it has the vendor-specific driver which has nothing in common
with dvb-core
 
Thanks in advance,
 
Akiva Sadovski
 
Scopus Video Networks


_______________________________________________
linux-dvb mailing list
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb
_______________________________________________
linux-dvb mailing list
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux