[linux-dvb] CA_CI_MODULE_READY not reset when CAM removed from AV7110 DVB card

Klaus Schmidinger Klaus.Schmidinger at cadsoft.de
Wed Nov 1 11:39:13 CET 2006


Oliver Endriss wrote:
> Klaus Schmidinger wrote:
>> I'm currently improving VDR's CAM handling, and while doing so
>> I came across what seems to be a bug in the AV7110 driver code.
>>
>> If I do
>>
>>    int fd = open("/dev/dvb/adapter0/ca0", O_RDWR);
>>    ca_slot_info_t sinfo;
>>    sinfo.num = 0;
>>    ioctl(fd, CA_GET_SLOT_INFO, &sinfo);
>>
>> to check whether the CI adapter contains a CAM, the value of
>> sinfo.flags is 0 as long as no CAM is inserted. When I insert a CAM,
>> it first goes to 1 (CA_CI_MODULE_PRESENT) and then to 3
>> (CA_CI_MODULE_PRESENT | CA_CI_MODULE_READY). So far everything is ok.
>>
>> However, when I remove the CAM from the slot, sinfo.flags still remains
>> set to 3. It never goes back to 0.
>>
>> Is this a bug or "intended behavior"?
> 
> Afaics it is a bug. Could you check whether CI_handle(in av7110_ca.c) is
> called when you remove the CAM? If not it's a firmware bug.

CI_handle(in av7110_ca.c) never gets called.

I've added the following debug output to av7110.c (after trying directly in
av7110_ca.c, which didn't give any results):

                 case DATA_CI_GET:
                 {
                         printk("DATA_CI_GET: %d %d %d %d %d %d %d\n", __LINE__, debibuf[0], debibuf[1], debibuf[2], debibuf[3], debibuf[4], debibuf[5]);//XXX
                         if ((debibuf[0] < 2) && debibuf[2] == 0xff) {
                                 int flags = 0;
                                 if (debibuf[5] > 0)
                                         flags |= CA_CI_MODULE_PRESENT;
                                 if (debibuf[5] > 5)
                                         flags |= CA_CI_MODULE_READY;
                                 printk("DATA_CI_GET: %d %04X %04X\n", __LINE__, av7110->ci_slot[debibuf[0]].flags, flags);//XXX
                                 av7110->ci_slot[debibuf[0]].flags = flags;
                         } else
                                 ci_get_data(&av7110->ci_rbuffer, debibuf, debilen);
                         break;
                 }

                 case DATA_COMMON_INTERFACE:
                         printk("DATA_COMMON_INTERFACE: %d %d\n", __LINE__, debilen);//XXX
                         CI_handle(av7110, debibuf, debilen);

What I get in the log file is:

* Start VDR with no CAM in the slot

Nov  1 11:25:22 video kernel: DATA_CI_GET: 376 0 0 255 2 0 0
Nov  1 11:25:22 video kernel: DATA_CI_GET: 383 0000 0000

* Insert CAM into slot:

Nov  1 11:25:58 video kernel: DATA_CI_GET: 376 0 0 255 2 0 1
Nov  1 11:25:58 video kernel: DATA_CI_GET: 383 0000 0001
Nov  1 11:25:59 video kernel: DATA_CI_GET: 376 0 0 255 2 0 2
Nov  1 11:25:59 video kernel: DATA_CI_GET: 383 0001 0001
Nov  1 11:25:59 video kernel: DATA_CI_GET: 376 0 0 255 2 0 3
Nov  1 11:25:59 video kernel: DATA_CI_GET: 383 0001 0001
Nov  1 11:25:59 video kernel: DATA_CI_GET: 376 0 0 255 2 0 4
Nov  1 11:25:59 video kernel: DATA_CI_GET: 383 0001 0001
Nov  1 11:25:59 video kernel: DATA_CI_GET: 376 0 0 255 2 0 5
Nov  1 11:25:59 video kernel: DATA_CI_GET: 383 0001 0001
Nov  1 11:25:59 video kernel: DATA_CI_GET: 376 0 0 255 2 0 6
Nov  1 11:25:59 video kernel: DATA_CI_GET: 383 0001 0003
Nov  1 11:26:00 video vdr: [8977] CAM: module ready in slot 0
Nov  1 11:26:01 video kernel: DATA_CI_GET: 376 0 1 131 1 1 128
Nov  1 11:26:01 video kernel: DATA_CI_GET: 376 0 1 128 2 1 128
Nov  1 11:26:01 video kernel: DATA_CI_GET: 376 0 1 160 7 1 145
Nov  1 11:26:01 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:01 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:02 video kernel: DATA_CI_GET: 376 0 1 128 2 1 128
Nov  1 11:26:03 video kernel: DATA_CI_GET: 376 0 1 160 130 0 9
Nov  1 11:26:03 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:04 video kernel: DATA_CI_GET: 376 0 1 128 2 1 128
Nov  1 11:26:04 video kernel: DATA_CI_GET: 376 0 1 160 130 0 9
Nov  1 11:26:04 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:06 video kernel: DATA_CI_GET: 376 0 1 128 2 1 128
Nov  1 11:26:06 video kernel: DATA_CI_GET: 376 0 1 160 7 1 145
Nov  1 11:26:06 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:06 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:07 video kernel: DATA_CI_GET: 376 0 1 128 2 1 128
Nov  1 11:26:07 video kernel: DATA_CI_GET: 376 0 1 160 130 0 31
Nov  1 11:26:07 video vdr: [8977] CAM: AlphaCrypt, 01, 4A20, 4A20
Nov  1 11:26:08 video kernel: DATA_CI_GET: 376 0 1 128 2 1 128
Nov  1 11:26:09 video kernel: DATA_CI_GET: 376 0 1 160 7 1 145
Nov  1 11:26:09 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:09 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:10 video kernel: DATA_CI_GET: 376 0 1 128 2 1 128
Nov  1 11:26:10 video kernel: DATA_CI_GET: 376 0 1 160 130 0 17
Nov  1 11:26:11 video kernel: DATA_CI_GET: 376 0 1 128 2 1 128
Nov  1 11:26:12 video kernel: DATA_CI_GET: 376 0 1 160 7 1 145
Nov  1 11:26:12 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:13 video kernel: DATA_CI_GET: 376 0 1 128 2 1 128
Nov  1 11:26:13 video kernel: DATA_CI_GET: 376 0 1 160 130 0 10
Nov  1 11:26:13 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:14 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0
Nov  1 11:26:16 video kernel: DATA_CI_GET: 376 0 1 128 2 1 0

(the last line is repeated continuously)

* Remove CAM from slot:

-> no more debug output at all.


Even though I call the CA_GET_SLOT_INFO ioctl() regularly to check
whether a module is still present, once a module has been found to
be ready, the code that would handle the CA_CI_MODULE_PRESENT and
CA_CI_MODULE_READY flags in av7110.c is never called again.

Klaus



More information about the linux-dvb mailing list